aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api')
-rw-r--r--Src/Wasabi/api/apiconfig.h176
-rw-r--r--Src/Wasabi/api/apiinit.cpp548
-rw-r--r--Src/Wasabi/api/apiinit.h255
-rw-r--r--Src/Wasabi/api/application/api_application.cpp12
-rw-r--r--Src/Wasabi/api/application/api_application.h416
-rw-r--r--Src/Wasabi/api/application/api_applicationi.cpp204
-rw-r--r--Src/Wasabi/api/application/api_applicationi.h49
-rw-r--r--Src/Wasabi/api/application/api_applicationx.cpp33
-rw-r--r--Src/Wasabi/api/application/api_applicationx.h42
-rw-r--r--Src/Wasabi/api/application/ifc_messageprocessor.cpp1
-rw-r--r--Src/Wasabi/api/application/ifc_messageprocessor.h26
-rw-r--r--Src/Wasabi/api/application/ifc_messageprocessori.cpp7
-rw-r--r--Src/Wasabi/api/application/ifc_messageprocessori.h13
-rw-r--r--Src/Wasabi/api/application/ipcs.cpp97
-rw-r--r--Src/Wasabi/api/application/ipcs.h60
-rw-r--r--Src/Wasabi/api/application/pathmgr.cpp14
-rw-r--r--Src/Wasabi/api/application/pathmgr.h15
-rw-r--r--Src/Wasabi/api/application/version.cpp47
-rw-r--r--Src/Wasabi/api/application/version.h12
-rw-r--r--Src/Wasabi/api/application/wkc.cpp12
-rw-r--r--Src/Wasabi/api/application/wkc.h61
-rw-r--r--Src/Wasabi/api/config/api_config.cpp12
-rw-r--r--Src/Wasabi/api/config/api_config.h149
-rw-r--r--Src/Wasabi/api/config/api_configi.cpp124
-rw-r--r--Src/Wasabi/api/config/api_configi.h46
-rw-r--r--Src/Wasabi/api/config/api_configx.cpp37
-rw-r--r--Src/Wasabi/api/config/api_configx.h44
-rw-r--r--Src/Wasabi/api/config/cfglist.cpp50
-rw-r--r--Src/Wasabi/api/config/cfglist.h23
-rw-r--r--Src/Wasabi/api/config/cfgscriptobj.cpp371
-rw-r--r--Src/Wasabi/api/config/cfgscriptobj.h198
-rw-r--r--Src/Wasabi/api/config/config.cpp329
-rw-r--r--Src/Wasabi/api/config/config.h43
-rw-r--r--Src/Wasabi/api/config/configapi.cpp95
-rw-r--r--Src/Wasabi/api/config/configapi.h32
-rw-r--r--Src/Wasabi/api/config/filetypes.cpp576
-rw-r--r--Src/Wasabi/api/config/filetypes.h46
-rw-r--r--Src/Wasabi/api/config/items/attrbool.h65
-rw-r--r--Src/Wasabi/api/config/items/attrcb.h127
-rw-r--r--Src/Wasabi/api/config/items/attrfloat.h52
-rw-r--r--Src/Wasabi/api/config/items/attrfn.h15
-rw-r--r--Src/Wasabi/api/config/items/attrhandler.h129
-rw-r--r--Src/Wasabi/api/config/items/attribs.h12
-rw-r--r--Src/Wasabi/api/config/items/attribute.cpp131
-rw-r--r--Src/Wasabi/api/config/items/attribute.h218
-rw-r--r--Src/Wasabi/api/config/items/attrint.h65
-rw-r--r--Src/Wasabi/api/config/items/attrstr.cpp14
-rw-r--r--Src/Wasabi/api/config/items/attrstr.h85
-rw-r--r--Src/Wasabi/api/config/items/cfgitem.h233
-rw-r--r--Src/Wasabi/api/config/items/cfgitemi.cpp274
-rw-r--r--Src/Wasabi/api/config/items/cfgitemi.h158
-rw-r--r--Src/Wasabi/api/config/items/cfgitemx.cpp27
-rw-r--r--Src/Wasabi/api/config/items/cfgitemx.h42
-rw-r--r--Src/Wasabi/api/config/items/intarray.cpp49
-rw-r--r--Src/Wasabi/api/config/items/intarray.h18
-rw-r--r--Src/Wasabi/api/config/options.cpp211
-rw-r--r--Src/Wasabi/api/config/options.h64
-rw-r--r--Src/Wasabi/api/config/uioptions.cpp109
-rw-r--r--Src/Wasabi/api/config/uioptions.h13
-rw-r--r--Src/Wasabi/api/console/console.cpp33
-rw-r--r--Src/Wasabi/api/console/console.h19
-rw-r--r--Src/Wasabi/api/core/api_core.cpp51
-rw-r--r--Src/Wasabi/api/core/api_core.h371
-rw-r--r--Src/Wasabi/api/core/buttons.h18
-rw-r--r--Src/Wasabi/api/core/coreactions.cpp181
-rw-r--r--Src/Wasabi/api/core/coreactions.h47
-rw-r--r--Src/Wasabi/api/core/corehandle.cpp304
-rw-r--r--Src/Wasabi/api/core/corehandle.h560
-rw-r--r--Src/Wasabi/api/core/sequence.cpp92
-rw-r--r--Src/Wasabi/api/core/sequence.h123
-rw-r--r--Src/Wasabi/api/dependency/api_dependent.cpp2
-rw-r--r--Src/Wasabi/api/dependency/api_dependent.h54
-rw-r--r--Src/Wasabi/api/dependency/api_dependentviewer.cpp2
-rw-r--r--Src/Wasabi/api/dependency/api_dependentviewer.h30
-rw-r--r--Src/Wasabi/api/filereader/api_filereader.cpp20
-rw-r--r--Src/Wasabi/api/filereader/api_filereader.h104
-rw-r--r--Src/Wasabi/api/filereader/api_readercallback.h22
-rw-r--r--Src/Wasabi/api/filereader/filereaderapi.cpp53
-rw-r--r--Src/Wasabi/api/filereader/filereaderapi.h25
-rw-r--r--Src/Wasabi/api/filereader/local/fileread.cpp132
-rw-r--r--Src/Wasabi/api/filereader/local/fileread.h23
-rw-r--r--Src/Wasabi/api/filereader/svc_filereadI.h100
-rw-r--r--Src/Wasabi/api/filereader/zip/zipread.cpp176
-rw-r--r--Src/Wasabi/api/filereader/zip/zipread.h39
-rw-r--r--Src/Wasabi/api/font/FontCreator.h7
-rw-r--r--Src/Wasabi/api/font/FontSvcEnum.h18
-rw-r--r--Src/Wasabi/api/font/api_font.cpp11
-rw-r--r--Src/Wasabi/api/font/api_font.h36
-rw-r--r--Src/Wasabi/api/font/bitmapfont.cpp394
-rw-r--r--Src/Wasabi/api/font/bitmapfont.h70
-rw-r--r--Src/Wasabi/api/font/font.cpp637
-rw-r--r--Src/Wasabi/api/font/font.h55
-rw-r--r--Src/Wasabi/api/font/fontapi.cpp32
-rw-r--r--Src/Wasabi/api/font/fontapi.h20
-rw-r--r--Src/Wasabi/api/font/linux/truetypefont_linux.cpp472
-rw-r--r--Src/Wasabi/api/font/linux/truetypefont_linux.h65
-rw-r--r--Src/Wasabi/api/font/skinfont.cpp43
-rw-r--r--Src/Wasabi/api/font/skinfont.h17
-rw-r--r--Src/Wasabi/api/font/svc_fontI.h39
-rw-r--r--Src/Wasabi/api/font/truetypefontdef.h56
-rw-r--r--Src/Wasabi/api/font/win32/truetypefont_win32.cpp561
-rw-r--r--Src/Wasabi/api/font/win32/truetypefont_win32.h61
-rw-r--r--Src/Wasabi/api/imgldr/ImgLoaderEnum.h24
-rw-r--r--Src/Wasabi/api/imgldr/api_imgldr.cpp20
-rw-r--r--Src/Wasabi/api/imgldr/api_imgldr.h98
-rw-r--r--Src/Wasabi/api/imgldr/imggen/grad.cpp60
-rw-r--r--Src/Wasabi/api/imgldr/imggen/grad.h15
-rw-r--r--Src/Wasabi/api/imgldr/imggen/imggen.cpp29
-rw-r--r--Src/Wasabi/api/imgldr/imggen/imggen.h14
-rw-r--r--Src/Wasabi/api/imgldr/imggen/osedge.cpp95
-rw-r--r--Src/Wasabi/api/imgldr/imggen/osedge.h13
-rw-r--r--Src/Wasabi/api/imgldr/imggen/poly.cpp59
-rw-r--r--Src/Wasabi/api/imgldr/imggen/poly.h13
-rw-r--r--Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp152
-rw-r--r--Src/Wasabi/api/imgldr/imggen/shadowwnd.h40
-rw-r--r--Src/Wasabi/api/imgldr/imggen/solid.cpp67
-rw-r--r--Src/Wasabi/api/imgldr/imggen/solid.h14
-rw-r--r--Src/Wasabi/api/imgldr/imgldr.cpp554
-rw-r--r--Src/Wasabi/api/imgldr/imgldr.h86
-rw-r--r--Src/Wasabi/api/imgldr/imgldrapi.cpp81
-rw-r--r--Src/Wasabi/api/imgldr/imgldrapi.h23
-rw-r--r--Src/Wasabi/api/imgldr/skinbmps.h122
-rw-r--r--Src/Wasabi/api/imgldr/winbmp.h47
-rw-r--r--Src/Wasabi/api/locales/LocalesInfo.cpp41
-rw-r--r--Src/Wasabi/api/locales/LocalesInfo.h30
-rw-r--r--Src/Wasabi/api/locales/api_locales.cpp12
-rw-r--r--Src/Wasabi/api/locales/api_locales.h80
-rw-r--r--Src/Wasabi/api/locales/api_localesi.cpp47
-rw-r--r--Src/Wasabi/api/locales/api_localesi.h23
-rw-r--r--Src/Wasabi/api/locales/api_localesx.cpp26
-rw-r--r--Src/Wasabi/api/locales/api_localesx.h31
-rw-r--r--Src/Wasabi/api/locales/localesmgr.cpp462
-rw-r--r--Src/Wasabi/api/locales/localesmgr.h173
-rw-r--r--Src/Wasabi/api/locales/xlatstr.h68
-rw-r--r--Src/Wasabi/api/memmgr/api_memmgr.cpp13
-rw-r--r--Src/Wasabi/api/memmgr/api_memmgr.h78
-rw-r--r--Src/Wasabi/api/metrics/metricscb.h37
-rw-r--r--Src/Wasabi/api/script/api_maki.cpp12
-rw-r--r--Src/Wasabi/api/script/api_maki.h392
-rw-r--r--Src/Wasabi/api/script/api_makidebug.cpp20
-rw-r--r--Src/Wasabi/api/script/api_makidebug.h134
-rw-r--r--Src/Wasabi/api/script/api_makii.cpp264
-rw-r--r--Src/Wasabi/api/script/api_makii.h93
-rw-r--r--Src/Wasabi/api/script/api_makix.cpp72
-rw-r--r--Src/Wasabi/api/script/api_makix.h81
-rw-r--r--Src/Wasabi/api/script/debugger/api_makidebug.cpp20
-rw-r--r--Src/Wasabi/api/script/debugger/api_makidebug.h134
-rw-r--r--Src/Wasabi/api/script/debugger/debugapi.cpp62
-rw-r--r--Src/Wasabi/api/script/debugger/debugapi.h28
-rw-r--r--Src/Wasabi/api/script/debugger/debuggerui.cpp11
-rw-r--r--Src/Wasabi/api/script/debugger/debuggerui.h42
-rw-r--r--Src/Wasabi/api/script/debugger/debugsymbols.cpp75
-rw-r--r--Src/Wasabi/api/script/debugger/debugsymbols.h38
-rw-r--r--Src/Wasabi/api/script/debugger/disasm.cpp193
-rw-r--r--Src/Wasabi/api/script/debugger/disasm.h38
-rw-r--r--Src/Wasabi/api/script/debugger/jitd.cpp176
-rw-r--r--Src/Wasabi/api/script/debugger/jitd.h71
-rw-r--r--Src/Wasabi/api/script/debugger/jitdbreak.cpp27
-rw-r--r--Src/Wasabi/api/script/debugger/jitdbreak.h22
-rw-r--r--Src/Wasabi/api/script/debugger/sdebuggerui.cpp437
-rw-r--r--Src/Wasabi/api/script/debugger/sdebuggerui.h65
-rw-r--r--Src/Wasabi/api/script/debugger/sourcecodeline.cpp69
-rw-r--r--Src/Wasabi/api/script/debugger/sourcecodeline.h100
-rw-r--r--Src/Wasabi/api/script/debugger/vcpudebug.cpp99
-rw-r--r--Src/Wasabi/api/script/debugger/vcpudebug.h39
-rw-r--r--Src/Wasabi/api/script/guru.cpp216
-rw-r--r--Src/Wasabi/api/script/guru.h51
-rw-r--r--Src/Wasabi/api/script/makiapi.cpp248
-rw-r--r--Src/Wasabi/api/script/makiapi.h66
-rw-r--r--Src/Wasabi/api/script/objcontroller.cpp156
-rw-r--r--Src/Wasabi/api/script/objcontroller.h316
-rw-r--r--Src/Wasabi/api/script/objcontrollert.cpp1
-rw-r--r--Src/Wasabi/api/script/objcontrollert.h67
-rw-r--r--Src/Wasabi/api/script/objects/PlaylistScriptObject.cpp438
-rw-r--r--Src/Wasabi/api/script/objects/PlaylistScriptObject.h102
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_browser.cpp127
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_browser.h49
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_button.cpp104
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_button.h45
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_checkbox.cpp84
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_checkbox.h39
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_container.cpp179
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_container.h61
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_dropdownlist.cpp184
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_dropdownlist.h63
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_edit.cpp135
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_edit.h53
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_group.cpp99
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_group.h43
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_grouplist.cpp85
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_grouplist.h39
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_guilist.cpp722
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_guilist.h189
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_guiobject.cpp739
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_guiobject.h193
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_guitree.cpp491
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_guitree.h131
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_layout.cpp236
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_layout.h79
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_menubutton.cpp80
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_menubutton.h39
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_querylist.cpp49
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_querylist.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_rootobj.cpp64
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_rootobj.h33
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_slider.cpp100
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_slider.h43
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_tabsheet.cpp59
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_tabsheet.h33
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_text.cpp89
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_text.h40
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_togglebutton.cpp59
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_togglebutton.h33
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_treeitem.cpp310
-rw-r--r--Src/Wasabi/api/script/objects/c_script/c_treeitem.h99
-rw-r--r--Src/Wasabi/api/script/objects/c_script/gen.m22
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_browser.cpp85
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_browser.h35
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_button.cpp62
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_button.h35
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_checkbox.cpp56
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_checkbox.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_container.cpp65
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_container.h37
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_dropdownlist.cpp56
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_dropdownlist.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_edit.cpp65
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_edit.h37
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_group.cpp56
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_group.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_grouplist.cpp53
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_grouplist.h29
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_guilist.cpp83
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_guilist.h49
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_guiobject.cpp117
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_guiobject.h71
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_guitree.cpp80
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_guitree.h47
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_layout.cpp80
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_layout.h47
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_menubutton.cpp62
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_menubutton.h35
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_querylist.cpp54
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_querylist.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_rootobj.cpp41
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_rootobj.h30
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_slider.cpp62
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_slider.h35
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_tabsheet.cpp53
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_tabsheet.h29
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_text.cpp56
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_text.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_togglebutton.cpp56
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_togglebutton.h31
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_treeitem.cpp89
-rw-r--r--Src/Wasabi/api/script/objects/c_script/h_treeitem.h53
-rw-r--r--Src/Wasabi/api/script/objects/c_script/scripthook.cpp47
-rw-r--r--Src/Wasabi/api/script/objects/c_script/scripthook.h49
-rw-r--r--Src/Wasabi/api/script/objects/compoobj.cpp361
-rw-r--r--Src/Wasabi/api/script/objects/compoobj.h119
-rw-r--r--Src/Wasabi/api/script/objects/core/coreadminobj.cpp184
-rw-r--r--Src/Wasabi/api/script/objects/core/coreadminobj.h67
-rw-r--r--Src/Wasabi/api/script/objects/core/coreobj.cpp1151
-rw-r--r--Src/Wasabi/api/script/objects/core/coreobj.h192
-rw-r--r--Src/Wasabi/api/script/objects/core/svc_scriptcore.cpp38
-rw-r--r--Src/Wasabi/api/script/objects/core/svc_scriptcore.h27
-rw-r--r--Src/Wasabi/api/script/objects/guiobj.cpp2880
-rw-r--r--Src/Wasabi/api/script/objects/guiobj.h423
-rw-r--r--Src/Wasabi/api/script/objects/guiobject.h855
-rw-r--r--Src/Wasabi/api/script/objects/guiobjectx.cpp131
-rw-r--r--Src/Wasabi/api/script/objects/guiobjectx.h177
-rw-r--r--Src/Wasabi/api/script/objects/rootobj.cpp42
-rw-r--r--Src/Wasabi/api/script/objects/rootobj.h40
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcb.cpp12
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcb.h40
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcbi.cpp3
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcbi.h15
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcbx.cpp20
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcbx.h29
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcontroller.cpp81
-rw-r--r--Src/Wasabi/api/script/objects/rootobjcontroller.h36
-rw-r--r--Src/Wasabi/api/script/objects/rootobject.cpp12
-rw-r--r--Src/Wasabi/api/script/objects/rootobject.h71
-rw-r--r--Src/Wasabi/api/script/objects/rootobjecti.cpp46
-rw-r--r--Src/Wasabi/api/script/objects/rootobjecti.h32
-rw-r--r--Src/Wasabi/api/script/objects/rootobjectx.cpp22
-rw-r--r--Src/Wasabi/api/script/objects/rootobjectx.h35
-rw-r--r--Src/Wasabi/api/script/objects/sapplication.cpp213
-rw-r--r--Src/Wasabi/api/script/objects/sapplication.h57
-rw-r--r--Src/Wasabi/api/script/objects/sbitlist.cpp118
-rw-r--r--Src/Wasabi/api/script/objects/sbitlist.h56
-rw-r--r--Src/Wasabi/api/script/objects/scolor.cpp236
-rw-r--r--Src/Wasabi/api/script/objects/scolor.h66
-rw-r--r--Src/Wasabi/api/script/objects/scolormgr.cpp235
-rw-r--r--Src/Wasabi/api/script/objects/scolormgr.h66
-rw-r--r--Src/Wasabi/api/script/objects/sfile.cpp119
-rw-r--r--Src/Wasabi/api/script/objects/sfile.h53
-rw-r--r--Src/Wasabi/api/script/objects/sgammagroup.cpp235
-rw-r--r--Src/Wasabi/api/script/objects/sgammagroup.h66
-rw-r--r--Src/Wasabi/api/script/objects/sgammaset.cpp201
-rw-r--r--Src/Wasabi/api/script/objects/sgammaset.h62
-rw-r--r--Src/Wasabi/api/script/objects/slist.cpp172
-rw-r--r--Src/Wasabi/api/script/objects/slist.h62
-rw-r--r--Src/Wasabi/api/script/objects/smap.cpp205
-rw-r--r--Src/Wasabi/api/script/objects/smap.h74
-rw-r--r--Src/Wasabi/api/script/objects/spopup.cpp140
-rw-r--r--Src/Wasabi/api/script/objects/spopup.h60
-rw-r--r--Src/Wasabi/api/script/objects/sprivate.cpp258
-rw-r--r--Src/Wasabi/api/script/objects/sprivate.h47
-rw-r--r--Src/Wasabi/api/script/objects/sregion.cpp256
-rw-r--r--Src/Wasabi/api/script/objects/sregion.h92
-rw-r--r--Src/Wasabi/api/script/objects/svcwnd.cpp239
-rw-r--r--Src/Wasabi/api/script/objects/svcwnd.h89
-rw-r--r--Src/Wasabi/api/script/objects/sxmldoc.cpp231
-rw-r--r--Src/Wasabi/api/script/objects/sxmldoc.h76
-rw-r--r--Src/Wasabi/api/script/objects/systemobj.cpp3500
-rw-r--r--Src/Wasabi/api/script/objects/systemobj.h397
-rw-r--r--Src/Wasabi/api/script/objects/timer.cpp165
-rw-r--r--Src/Wasabi/api/script/objects/timer.h77
-rw-r--r--Src/Wasabi/api/script/objects/wacobj.cpp161
-rw-r--r--Src/Wasabi/api/script/objects/wacobj.h75
-rw-r--r--Src/Wasabi/api/script/objecttable.cpp748
-rw-r--r--Src/Wasabi/api/script/objecttable.h144
-rw-r--r--Src/Wasabi/api/script/opcodes.h64
-rw-r--r--Src/Wasabi/api/script/script.cpp269
-rw-r--r--Src/Wasabi/api/script/script.h86
-rw-r--r--Src/Wasabi/api/script/scriptguid.h143
-rw-r--r--Src/Wasabi/api/script/scriptmgr.cpp602
-rw-r--r--Src/Wasabi/api/script/scriptmgr.h81
-rw-r--r--Src/Wasabi/api/script/scriptobj.cpp12
-rw-r--r--Src/Wasabi/api/script/scriptobj.h139
-rw-r--r--Src/Wasabi/api/script/scriptobji.cpp305
-rw-r--r--Src/Wasabi/api/script/scriptobji.h134
-rw-r--r--Src/Wasabi/api/script/scriptobjx.cpp34
-rw-r--r--Src/Wasabi/api/script/scriptobjx.h44
-rw-r--r--Src/Wasabi/api/script/scriptvar.h35
-rw-r--r--Src/Wasabi/api/script/vcpu.cpp2069
-rw-r--r--Src/Wasabi/api/script/vcpu.h171
-rw-r--r--Src/Wasabi/api/script/vcputypes.h78
-rw-r--r--Src/Wasabi/api/service/api_service.cpp12
-rw-r--r--Src/Wasabi/api/service/api_service.h184
-rw-r--r--Src/Wasabi/api/service/api_servicei.cpp83
-rw-r--r--Src/Wasabi/api/service/api_servicei.h150
-rw-r--r--Src/Wasabi/api/service/api_servicex.cpp35
-rw-r--r--Src/Wasabi/api/service/api_servicex.h44
-rw-r--r--Src/Wasabi/api/service/service.h16
-rw-r--r--Src/Wasabi/api/service/servicei.cpp5
-rw-r--r--Src/Wasabi/api/service/servicei.h180
-rw-r--r--Src/Wasabi/api/service/services.h76
-rw-r--r--Src/Wasabi/api/service/svc_enum.cpp2
-rw-r--r--Src/Wasabi/api/service/svc_enum.h24
-rw-r--r--Src/Wasabi/api/service/svccache.cpp35
-rw-r--r--Src/Wasabi/api/service/svccache.h43
-rw-r--r--Src/Wasabi/api/service/svcenum.cpp45
-rw-r--r--Src/Wasabi/api/service/svcenum.h37
-rw-r--r--Src/Wasabi/api/service/svcenumbyguid.cpp5
-rw-r--r--Src/Wasabi/api/service/svcenumbyguid.h37
-rw-r--r--Src/Wasabi/api/service/svcenumt.cpp5
-rw-r--r--Src/Wasabi/api/service/svcenumt.h30
-rw-r--r--Src/Wasabi/api/service/svcmgr.cpp365
-rw-r--r--Src/Wasabi/api/service/svcmgr.h41
-rw-r--r--Src/Wasabi/api/service/svcs/svc_accessibility.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_accessibility.h43
-rw-r--r--Src/Wasabi/api/service/svcs/svc_accroleserver.cpp70
-rw-r--r--Src/Wasabi/api/service/svcs/svc_accroleserver.h132
-rw-r--r--Src/Wasabi/api/service/svcs/svc_action.cpp38
-rw-r--r--Src/Wasabi/api/service/svcs/svc_action.h154
-rw-r--r--Src/Wasabi/api/service/svcs/svc_burner.cpp70
-rw-r--r--Src/Wasabi/api/service/svcs/svc_burner.h243
-rw-r--r--Src/Wasabi/api/service/svcs/svc_collection.cpp194
-rw-r--r--Src/Wasabi/api/service/svcs/svc_collection.h226
-rw-r--r--Src/Wasabi/api/service/svcs/svc_console.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_console.h36
-rw-r--r--Src/Wasabi/api/service/svcs/svc_contextCmd.cpp16
-rw-r--r--Src/Wasabi/api/service/svcs/svc_contextCmd.h127
-rw-r--r--Src/Wasabi/api/service/svcs/svc_coreadmin.cpp70
-rw-r--r--Src/Wasabi/api/service/svcs/svc_coreadmin.h230
-rw-r--r--Src/Wasabi/api/service/svcs/svc_db.cpp78
-rw-r--r--Src/Wasabi/api/service/svcs/svc_db.h512
-rw-r--r--Src/Wasabi/api/service/svcs/svc_debuggerui.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_debuggerui.h44
-rw-r--r--Src/Wasabi/api/service/svcs/svc_device.h54
-rw-r--r--Src/Wasabi/api/service/svcs/svc_droptarget.cpp11
-rw-r--r--Src/Wasabi/api/service/svcs/svc_droptarget.h82
-rw-r--r--Src/Wasabi/api/service/svcs/svc_eval.cpp11
-rw-r--r--Src/Wasabi/api/service/svcs/svc_eval.h64
-rw-r--r--Src/Wasabi/api/service/svcs/svc_export.h32
-rw-r--r--Src/Wasabi/api/service/svcs/svc_fileread.cpp30
-rw-r--r--Src/Wasabi/api/service/svcs/svc_fileread.h199
-rw-r--r--Src/Wasabi/api/service/svcs/svc_filesel.cpp15
-rw-r--r--Src/Wasabi/api/service/svcs/svc_filesel.h89
-rw-r--r--Src/Wasabi/api/service/svcs/svc_font.cpp27
-rw-r--r--Src/Wasabi/api/service/svcs/svc_font.h178
-rw-r--r--Src/Wasabi/api/service/svcs/svc_fontmaker.cpp9
-rw-r--r--Src/Wasabi/api/service/svcs/svc_fontmaker.h73
-rw-r--r--Src/Wasabi/api/service/svcs/svc_fontrender.cpp16
-rw-r--r--Src/Wasabi/api/service/svcs/svc_fontrender.h126
-rw-r--r--Src/Wasabi/api/service/svcs/svc_imggen.cpp11
-rw-r--r--Src/Wasabi/api/service/svcs/svc_imggen.h68
-rw-r--r--Src/Wasabi/api/service/svcs/svc_imgload.cpp14
-rw-r--r--Src/Wasabi/api/service/svcs/svc_imgload.h101
-rw-r--r--Src/Wasabi/api/service/svcs/svc_imgwrite.h101
-rw-r--r--Src/Wasabi/api/service/svcs/svc_itemmgr.cpp20
-rw-r--r--Src/Wasabi/api/service/svcs/svc_itemmgr.h112
-rw-r--r--Src/Wasabi/api/service/svcs/svc_loadlib.h16
-rw-r--r--Src/Wasabi/api/service/svcs/svc_mediaconverter.cpp23
-rw-r--r--Src/Wasabi/api/service/svcs/svc_mediaconverter.h161
-rw-r--r--Src/Wasabi/api/service/svcs/svc_mediacore.cpp45
-rw-r--r--Src/Wasabi/api/service/svcs/svc_mediacore.h172
-rw-r--r--Src/Wasabi/api/service/svcs/svc_metadata.cpp14
-rw-r--r--Src/Wasabi/api/service/svcs/svc_metadata.h97
-rw-r--r--Src/Wasabi/api/service/svcs/svc_minibrowser.cpp12
-rw-r--r--Src/Wasabi/api/service/svcs/svc_minibrowser.h69
-rw-r--r--Src/Wasabi/api/service/svcs/svc_objectdir.cpp32
-rw-r--r--Src/Wasabi/api/service/svcs/svc_objectdir.h294
-rw-r--r--Src/Wasabi/api/service/svcs/svc_player.h35
-rw-r--r--Src/Wasabi/api/service/svcs/svc_playlist.cpp28
-rw-r--r--Src/Wasabi/api/service/svcs/svc_playlist.h216
-rw-r--r--Src/Wasabi/api/service/svcs/svc_redir.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_redir.h63
-rw-r--r--Src/Wasabi/api/service/svcs/svc_scriptobj.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_scriptobj.h29
-rw-r--r--Src/Wasabi/api/service/svcs/svc_scriptobji.h51
-rw-r--r--Src/Wasabi/api/service/svcs/svc_skinfilter.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_skinfilter.h56
-rw-r--r--Src/Wasabi/api/service/svcs/svc_storagevolenum.cpp30
-rw-r--r--Src/Wasabi/api/service/svcs/svc_storagevolenum.h96
-rw-r--r--Src/Wasabi/api/service/svcs/svc_stringconverter.cpp12
-rw-r--r--Src/Wasabi/api/service/svcs/svc_stringconverter.h94
-rw-r--r--Src/Wasabi/api/service/svcs/svc_stringtypes.h35
-rw-r--r--Src/Wasabi/api/service/svcs/svc_textfeed.cpp18
-rw-r--r--Src/Wasabi/api/service/svcs/svc_textfeed.h21
-rw-r--r--Src/Wasabi/api/service/svcs/svc_tooltips.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_tooltips.h30
-rw-r--r--Src/Wasabi/api/service/svcs/svc_wndcreate.cpp16
-rw-r--r--Src/Wasabi/api/service/svcs/svc_wndcreate.h120
-rw-r--r--Src/Wasabi/api/service/svcs/svc_xmlprov.cpp10
-rw-r--r--Src/Wasabi/api/service/svcs/svc_xmlprov.h56
-rw-r--r--Src/Wasabi/api/service/svcs/svc_xuiobject.cpp12
-rw-r--r--Src/Wasabi/api/service/svcs/svc_xuiobject.h76
-rw-r--r--Src/Wasabi/api/service/waservicefactory.cpp12
-rw-r--r--Src/Wasabi/api/service/waservicefactory.h109
-rw-r--r--Src/Wasabi/api/service/waservicefactorybase.cpp5
-rw-r--r--Src/Wasabi/api/service/waservicefactorybase.h76
-rw-r--r--Src/Wasabi/api/service/waservicefactoryi.cpp2
-rw-r--r--Src/Wasabi/api/service/waservicefactoryi.h73
-rw-r--r--Src/Wasabi/api/service/waservicefactoryt.cpp5
-rw-r--r--Src/Wasabi/api/service/waservicefactoryt.h28
-rw-r--r--Src/Wasabi/api/service/waservicefactorytsingle.cpp5
-rw-r--r--Src/Wasabi/api/service/waservicefactorytsingle.h47
-rw-r--r--Src/Wasabi/api/service/waservicefactoryx.cpp32
-rw-r--r--Src/Wasabi/api/service/waservicefactoryx.h37
-rw-r--r--Src/Wasabi/api/skin/SkinElementAlias.cpp8
-rw-r--r--Src/Wasabi/api/skin/SkinElementAlias.h65
-rw-r--r--Src/Wasabi/api/skin/SkinVersion.cpp42
-rw-r--r--Src/Wasabi/api/skin/SkinVersion.h18
-rw-r--r--Src/Wasabi/api/skin/api_colorthemes.cpp3
-rw-r--r--Src/Wasabi/api/skin/api_colorthemes.h161
-rw-r--r--Src/Wasabi/api/skin/api_palette.cpp1
-rw-r--r--Src/Wasabi/api/skin/api_palette.h273
-rw-r--r--Src/Wasabi/api/skin/api_skin.cpp63
-rw-r--r--Src/Wasabi/api/skin/api_skin.h429
-rw-r--r--Src/Wasabi/api/skin/colorthemes.h87
-rw-r--r--Src/Wasabi/api/skin/cursormgr.cpp29
-rw-r--r--Src/Wasabi/api/skin/cursormgr.h18
-rw-r--r--Src/Wasabi/api/skin/feeds/TextFeedEnum.h35
-rw-r--r--Src/Wasabi/api/skin/feeds/api_textfeed.cpp2
-rw-r--r--Src/Wasabi/api/skin/feeds/api_textfeed.h66
-rw-r--r--Src/Wasabi/api/skin/feeds/ezfeed.h27
-rw-r--r--Src/Wasabi/api/skin/feeds/feedwatch.cpp90
-rw-r--r--Src/Wasabi/api/skin/feeds/feedwatch.h54
-rw-r--r--Src/Wasabi/api/skin/feeds/feedwatcherso.cpp136
-rw-r--r--Src/Wasabi/api/skin/feeds/feedwatcherso.h64
-rw-r--r--Src/Wasabi/api/skin/feeds/textfeed.cpp116
-rw-r--r--Src/Wasabi/api/skin/feeds/textfeed.h57
-rw-r--r--Src/Wasabi/api/skin/feeds/textfeedcb.cpp9
-rw-r--r--Src/Wasabi/api/skin/feeds/textfeedcb.h34
-rw-r--r--Src/Wasabi/api/skin/gammamgr.cpp135
-rw-r--r--Src/Wasabi/api/skin/gammamgr.h91
-rw-r--r--Src/Wasabi/api/skin/group.h366
-rw-r--r--Src/Wasabi/api/skin/groupmgr.cpp51
-rw-r--r--Src/Wasabi/api/skin/groupmgr.h42
-rw-r--r--Src/Wasabi/api/skin/groupwndcreate.cpp51
-rw-r--r--Src/Wasabi/api/skin/groupwndcreate.h25
-rw-r--r--Src/Wasabi/api/skin/guitree.cpp379
-rw-r--r--Src/Wasabi/api/skin/guitree.h171
-rw-r--r--Src/Wasabi/api/skin/nakedobject.cpp34
-rw-r--r--Src/Wasabi/api/skin/nakedobject.h24
-rw-r--r--Src/Wasabi/api/skin/objectactuator.cpp106
-rw-r--r--Src/Wasabi/api/skin/objectactuator.h49
-rw-r--r--Src/Wasabi/api/skin/regioncache.cpp32
-rw-r--r--Src/Wasabi/api/skin/regioncache.h53
-rw-r--r--Src/Wasabi/api/skin/skin.cpp812
-rw-r--r--Src/Wasabi/api/skin/skin.h150
-rw-r--r--Src/Wasabi/api/skin/skinapi.cpp347
-rw-r--r--Src/Wasabi/api/skin/skinapi.h79
-rw-r--r--Src/Wasabi/api/skin/skinbmps.h122
-rw-r--r--Src/Wasabi/api/skin/skinelem.cpp316
-rw-r--r--Src/Wasabi/api/skin/skinelem.h106
-rw-r--r--Src/Wasabi/api/skin/skinfilter.cpp18
-rw-r--r--Src/Wasabi/api/skin/skinfilter.h12
-rw-r--r--Src/Wasabi/api/skin/skinfont.cpp48
-rw-r--r--Src/Wasabi/api/skin/skinfont.h17
-rw-r--r--Src/Wasabi/api/skin/skinitem.cpp14
-rw-r--r--Src/Wasabi/api/skin/skinitem.h66
-rw-r--r--Src/Wasabi/api/skin/skinparse.cpp1822
-rw-r--r--Src/Wasabi/api/skin/skinparse.h337
-rw-r--r--Src/Wasabi/api/skin/widgets.cpp451
-rw-r--r--Src/Wasabi/api/skin/widgets.h35
-rw-r--r--Src/Wasabi/api/skin/widgets/animlayer.cpp880
-rw-r--r--Src/Wasabi/api/skin/widgets/animlayer.h214
-rw-r--r--Src/Wasabi/api/skin/widgets/button.cpp508
-rw-r--r--Src/Wasabi/api/skin/widgets/button.h134
-rw-r--r--Src/Wasabi/api/skin/widgets/checkbox.cpp262
-rw-r--r--Src/Wasabi/api/skin/widgets/checkbox.h246
-rw-r--r--Src/Wasabi/api/skin/widgets/combobox.cpp270
-rw-r--r--Src/Wasabi/api/skin/widgets/combobox.h121
-rw-r--r--Src/Wasabi/api/skin/widgets/compbuck2.cpp611
-rw-r--r--Src/Wasabi/api/skin/widgets/compbuck2.h156
-rw-r--r--Src/Wasabi/api/skin/widgets/customobject.cpp8
-rw-r--r--Src/Wasabi/api/skin/widgets/customobject.h78
-rw-r--r--Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp406
-rw-r--r--Src/Wasabi/api/skin/widgets/db/autofilterlist.h447
-rw-r--r--Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp111
-rw-r--r--Src/Wasabi/api/skin/widgets/db/autoquerylist.h109
-rw-r--r--Src/Wasabi/api/skin/widgets/db/queryline.cpp32
-rw-r--r--Src/Wasabi/api/skin/widgets/db/queryline.h64
-rw-r--r--Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp103
-rw-r--r--Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h53
-rw-r--r--Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp73
-rw-r--r--Src/Wasabi/api/skin/widgets/db/xuiqueryline.h35
-rw-r--r--Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp119
-rw-r--r--Src/Wasabi/api/skin/widgets/db/xuiquerylist.h72
-rw-r--r--Src/Wasabi/api/skin/widgets/dropdownlist.cpp747
-rw-r--r--Src/Wasabi/api/skin/widgets/dropdownlist.h531
-rw-r--r--Src/Wasabi/api/skin/widgets/edit.cpp312
-rw-r--r--Src/Wasabi/api/skin/widgets/edit.h100
-rw-r--r--Src/Wasabi/api/skin/widgets/fx.h12
-rw-r--r--Src/Wasabi/api/skin/widgets/fx_dmove.cpp409
-rw-r--r--Src/Wasabi/api/skin/widgets/fx_dmove.h48
-rw-r--r--Src/Wasabi/api/skin/widgets/group.cpp1753
-rw-r--r--Src/Wasabi/api/skin/widgets/group.h365
-rw-r--r--Src/Wasabi/api/skin/widgets/groupclickwnd.cpp84
-rw-r--r--Src/Wasabi/api/skin/widgets/groupclickwnd.h226
-rw-r--r--Src/Wasabi/api/skin/widgets/grouplist.cpp228
-rw-r--r--Src/Wasabi/api/skin/widgets/grouplist.h79
-rw-r--r--Src/Wasabi/api/skin/widgets/grouptgbutton.cpp109
-rw-r--r--Src/Wasabi/api/skin/widgets/grouptgbutton.h101
-rw-r--r--Src/Wasabi/api/skin/widgets/grouptips.cpp92
-rw-r--r--Src/Wasabi/api/skin/widgets/grouptips.h23
-rw-r--r--Src/Wasabi/api/skin/widgets/guiradiogroup.cpp36
-rw-r--r--Src/Wasabi/api/skin/widgets/guiradiogroup.h53
-rw-r--r--Src/Wasabi/api/skin/widgets/historyeditbox.cpp152
-rw-r--r--Src/Wasabi/api/skin/widgets/historyeditbox.h58
-rw-r--r--Src/Wasabi/api/skin/widgets/layer.cpp1727
-rw-r--r--Src/Wasabi/api/skin/widgets/layer.h287
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp637
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/iebrowser.h102
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp70
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h24
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp48
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/mbsvc.h26
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp26
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h24
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp36
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/minibrowser.h215
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp173
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h57
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp180
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h63
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp39
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h33
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp385
-rw-r--r--Src/Wasabi/api/skin/widgets/mb/xuibrowser.h106
-rw-r--r--Src/Wasabi/api/skin/widgets/mouseredir.cpp221
-rw-r--r--Src/Wasabi/api/skin/widgets/mouseredir.h88
-rw-r--r--Src/Wasabi/api/skin/widgets/objdirwnd.cpp227
-rw-r--r--Src/Wasabi/api/skin/widgets/objdirwnd.h90
-rw-r--r--Src/Wasabi/api/skin/widgets/pathpicker.cpp111
-rw-r--r--Src/Wasabi/api/skin/widgets/pathpicker.h183
-rw-r--r--Src/Wasabi/api/skin/widgets/pslider.cpp371
-rw-r--r--Src/Wasabi/api/skin/widgets/pslider.h110
-rw-r--r--Src/Wasabi/api/skin/widgets/sa.cpp735
-rw-r--r--Src/Wasabi/api/skin/widgets/sa.h157
-rw-r--r--Src/Wasabi/api/skin/widgets/seeker.h22
-rw-r--r--Src/Wasabi/api/skin/widgets/seqband.cpp121
-rw-r--r--Src/Wasabi/api/skin/widgets/seqband.h47
-rw-r--r--Src/Wasabi/api/skin/widgets/seqpreamp.cpp44
-rw-r--r--Src/Wasabi/api/skin/widgets/seqpreamp.h28
-rw-r--r--Src/Wasabi/api/skin/widgets/seqvis.cpp367
-rw-r--r--Src/Wasabi/api/skin/widgets/seqvis.h104
-rw-r--r--Src/Wasabi/api/skin/widgets/spanbar.cpp58
-rw-r--r--Src/Wasabi/api/skin/widgets/spanbar.h31
-rw-r--r--Src/Wasabi/api/skin/widgets/sseeker.cpp128
-rw-r--r--Src/Wasabi/api/skin/widgets/sseeker.h56
-rw-r--r--Src/Wasabi/api/skin/widgets/sstatus.cpp172
-rw-r--r--Src/Wasabi/api/skin/widgets/sstatus.h100
-rw-r--r--Src/Wasabi/api/skin/widgets/stats/statswnd.cpp38
-rw-r--r--Src/Wasabi/api/skin/widgets/stats/statswnd.h18
-rw-r--r--Src/Wasabi/api/skin/widgets/stats/xuistats.cpp149
-rw-r--r--Src/Wasabi/api/skin/widgets/stats/xuistats.h43
-rw-r--r--Src/Wasabi/api/skin/widgets/svolbar.cpp55
-rw-r--r--Src/Wasabi/api/skin/widgets/svolbar.h30
-rw-r--r--Src/Wasabi/api/skin/widgets/text.cpp1767
-rw-r--r--Src/Wasabi/api/skin/widgets/text.h240
-rw-r--r--Src/Wasabi/api/skin/widgets/textbase.cpp345
-rw-r--r--Src/Wasabi/api/skin/widgets/textbase.h95
-rw-r--r--Src/Wasabi/api/skin/widgets/tgbutton.cpp313
-rw-r--r--Src/Wasabi/api/skin/widgets/tgbutton.h136
-rw-r--r--Src/Wasabi/api/skin/widgets/title.cpp261
-rw-r--r--Src/Wasabi/api/skin/widgets/title.h87
-rw-r--r--Src/Wasabi/api/skin/widgets/titlebox.cpp183
-rw-r--r--Src/Wasabi/api/skin/widgets/titlebox.h95
-rw-r--r--Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp186
-rw-r--r--Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h63
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiaddparams.cpp41
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiaddparams.h34
-rw-r--r--Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp50
-rw-r--r--Src/Wasabi/api/skin/widgets/xuibookmarklist.h36
-rw-r--r--Src/Wasabi/api/skin/widgets/xuicheckbox.cpp165
-rw-r--r--Src/Wasabi/api/skin/widgets/xuicheckbox.h81
-rw-r--r--Src/Wasabi/api/skin/widgets/xuicombobox.cpp7
-rw-r--r--Src/Wasabi/api/skin/widgets/xuicombobox.h10
-rw-r--r--Src/Wasabi/api/skin/widgets/xuicustomobject.cpp64
-rw-r--r--Src/Wasabi/api/skin/widgets/xuicustomobject.h40
-rw-r--r--Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp411
-rw-r--r--Src/Wasabi/api/skin/widgets/xuidownloadslist.h77
-rw-r--r--Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp7
-rw-r--r--Src/Wasabi/api/skin/widgets/xuidropdownlist.h10
-rw-r--r--Src/Wasabi/api/skin/widgets/xuieditbox.cpp6
-rw-r--r--Src/Wasabi/api/skin/widgets/xuieditbox.h21
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiframe.cpp241
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiframe.h97
-rw-r--r--Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp66
-rw-r--r--Src/Wasabi/api/skin/widgets/xuigradientwnd.h26
-rw-r--r--Src/Wasabi/api/skin/widgets/xuigrid.cpp297
-rw-r--r--Src/Wasabi/api/skin/widgets/xuigrid.h59
-rw-r--r--Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp120
-rw-r--r--Src/Wasabi/api/skin/widgets/xuigroupxfade.h40
-rw-r--r--Src/Wasabi/api/skin/widgets/xuihideobject.cpp50
-rw-r--r--Src/Wasabi/api/skin/widgets/xuihideobject.h40
-rw-r--r--Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp7
-rw-r--r--Src/Wasabi/api/skin/widgets/xuihistoryedit.h10
-rw-r--r--Src/Wasabi/api/skin/widgets/xuilist.cpp1734
-rw-r--r--Src/Wasabi/api/skin/widgets/xuilist.h221
-rw-r--r--Src/Wasabi/api/skin/widgets/xuimenu.cpp384
-rw-r--r--Src/Wasabi/api/skin/widgets/xuimenu.h110
-rw-r--r--Src/Wasabi/api/skin/widgets/xuimenuso.cpp271
-rw-r--r--Src/Wasabi/api/skin/widgets/xuimenuso.h76
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp57
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h32
-rw-r--r--Src/Wasabi/api/skin/widgets/xuioswndhost.cpp306
-rw-r--r--Src/Wasabi/api/skin/widgets/xuioswndhost.h78
-rw-r--r--Src/Wasabi/api/skin/widgets/xuipathpicker.cpp73
-rw-r--r--Src/Wasabi/api/skin/widgets/xuipathpicker.h53
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp162
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiprogressgrid.h59
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp17
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiradiogroup.h30
-rw-r--r--Src/Wasabi/api/skin/widgets/xuirect.cpp186
-rw-r--r--Src/Wasabi/api/skin/widgets/xuirect.h43
-rw-r--r--Src/Wasabi/api/skin/widgets/xuisendparams.cpp37
-rw-r--r--Src/Wasabi/api/skin/widgets/xuisendparams.h36
-rw-r--r--Src/Wasabi/api/skin/widgets/xuistatus.cpp98
-rw-r--r--Src/Wasabi/api/skin/widgets/xuistatus.h54
-rw-r--r--Src/Wasabi/api/skin/widgets/xuitabsheet.cpp217
-rw-r--r--Src/Wasabi/api/skin/widgets/xuitabsheet.h91
-rw-r--r--Src/Wasabi/api/skin/widgets/xuithemeslist.cpp365
-rw-r--r--Src/Wasabi/api/skin/widgets/xuithemeslist.h128
-rw-r--r--Src/Wasabi/api/skin/widgets/xuititlebox.cpp59
-rw-r--r--Src/Wasabi/api/skin/widgets/xuititlebox.h44
-rw-r--r--Src/Wasabi/api/skin/widgets/xuitree.cpp2644
-rw-r--r--Src/Wasabi/api/skin/widgets/xuitree.h326
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiwndholder.cpp272
-rw-r--r--Src/Wasabi/api/skin/widgets/xuiwndholder.h80
-rw-r--r--Src/Wasabi/api/skin/xmlobject.cpp174
-rw-r--r--Src/Wasabi/api/skin/xmlobject.h132
-rw-r--r--Src/Wasabi/api/syscb/api_syscb.cpp14
-rw-r--r--Src/Wasabi/api/syscb/api_syscb.h77
-rw-r--r--Src/Wasabi/api/syscb/api_syscbi.cpp35
-rw-r--r--Src/Wasabi/api/syscb/api_syscbi.h28
-rw-r--r--Src/Wasabi/api/syscb/api_syscbx.cpp22
-rw-r--r--Src/Wasabi/api/syscb/api_syscbx.h32
-rw-r--r--Src/Wasabi/api/syscb/callbacks/authcb.h20
-rw-r--r--Src/Wasabi/api/syscb/callbacks/browsercb.cpp2
-rw-r--r--Src/Wasabi/api/syscb/callbacks/browsercb.h11
-rw-r--r--Src/Wasabi/api/syscb/callbacks/browsercbi.h32
-rw-r--r--Src/Wasabi/api/syscb/callbacks/consolecb.cpp14
-rw-r--r--Src/Wasabi/api/syscb/callbacks/consolecb.h24
-rw-r--r--Src/Wasabi/api/syscb/callbacks/corecb.cpp79
-rw-r--r--Src/Wasabi/api/syscb/callbacks/corecb.h71
-rw-r--r--Src/Wasabi/api/syscb/callbacks/corecbi.h67
-rw-r--r--Src/Wasabi/api/syscb/callbacks/gccb.h31
-rw-r--r--Src/Wasabi/api/syscb/callbacks/metacb.h41
-rw-r--r--Src/Wasabi/api/syscb/callbacks/playlistcb.cpp10
-rw-r--r--Src/Wasabi/api/syscb/callbacks/playlistcb.h26
-rw-r--r--Src/Wasabi/api/syscb/callbacks/runlevelcb.h39
-rw-r--r--Src/Wasabi/api/syscb/callbacks/skincb.cpp20
-rw-r--r--Src/Wasabi/api/syscb/callbacks/skincb.h41
-rw-r--r--Src/Wasabi/api/syscb/callbacks/svccb.h12
-rw-r--r--Src/Wasabi/api/syscb/callbacks/svccbi.h34
-rw-r--r--Src/Wasabi/api/syscb/callbacks/syscb.cpp12
-rw-r--r--Src/Wasabi/api/syscb/callbacks/syscb.h73
-rw-r--r--Src/Wasabi/api/syscb/callbacks/syscbi.cpp4
-rw-r--r--Src/Wasabi/api/syscb/callbacks/syscbi.h46
-rw-r--r--Src/Wasabi/api/syscb/callbacks/syscbx.cpp21
-rw-r--r--Src/Wasabi/api/syscb/callbacks/syscbx.h30
-rw-r--r--Src/Wasabi/api/syscb/callbacks/sysmemcb.h53
-rw-r--r--Src/Wasabi/api/syscb/callbacks/wndcb.cpp36
-rw-r--r--Src/Wasabi/api/syscb/callbacks/wndcb.h43
-rw-r--r--Src/Wasabi/api/syscb/cbmgr.cpp41
-rw-r--r--Src/Wasabi/api/syscb/cbmgr.h18
-rw-r--r--Src/Wasabi/api/timer/api_timer.h47
-rw-r--r--Src/Wasabi/api/timer/osx_timer.cpp38
-rw-r--r--Src/Wasabi/api/timer/osx_timer.h17
-rw-r--r--Src/Wasabi/api/timer/timerclient.cpp108
-rw-r--r--Src/Wasabi/api/timer/timerclient.h183
-rw-r--r--Src/Wasabi/api/timer/timeslicer.cpp62
-rw-r--r--Src/Wasabi/api/timer/timeslicer.h64
-rw-r--r--Src/Wasabi/api/util/savefile.cpp228
-rw-r--r--Src/Wasabi/api/util/savefile.h31
-rw-r--r--Src/Wasabi/api/util/selectfile.cpp111
-rw-r--r--Src/Wasabi/api/util/selectfile.h41
-rw-r--r--Src/Wasabi/api/util/systray.cpp93
-rw-r--r--Src/Wasabi/api/util/systray.h23
-rw-r--r--Src/Wasabi/api/util/varmgr.cpp111
-rw-r--r--Src/Wasabi/api/util/varmgr.h17
-rw-r--r--Src/Wasabi/api/wac/compdb.h28
-rw-r--r--Src/Wasabi/api/wac/compon.cpp480
-rw-r--r--Src/Wasabi/api/wac/compon.h56
-rw-r--r--Src/Wasabi/api/wac/main.h134
-rw-r--r--Src/Wasabi/api/wac/papi.h12
-rw-r--r--Src/Wasabi/api/wac/wac.h266
-rw-r--r--Src/Wasabi/api/wac/waclient.cpp347
-rw-r--r--Src/Wasabi/api/wnd/PaintCanvas.h3
-rw-r--r--Src/Wasabi/api/wnd/accessible.cpp16
-rw-r--r--Src/Wasabi/api/wnd/accessible.h622
-rw-r--r--Src/Wasabi/api/wnd/api_canvas.cpp2
-rw-r--r--Src/Wasabi/api/wnd/api_canvas.h163
-rw-r--r--Src/Wasabi/api/wnd/api_region.cpp2
-rw-r--r--Src/Wasabi/api/wnd/api_region.h200
-rw-r--r--Src/Wasabi/api/wnd/api_window.cpp3
-rw-r--r--Src/Wasabi/api/wnd/api_window.h1277
-rw-r--r--Src/Wasabi/api/wnd/api_wnd.cpp57
-rw-r--r--Src/Wasabi/api/wnd/api_wnd.h390
-rw-r--r--Src/Wasabi/api/wnd/basewnd.cpp5743
-rw-r--r--Src/Wasabi/api/wnd/basewnd.h944
-rw-r--r--Src/Wasabi/api/wnd/bitmap.cpp1584
-rw-r--r--Src/Wasabi/api/wnd/bitmap.h7
-rw-r--r--Src/Wasabi/api/wnd/blending.cpp56
-rw-r--r--Src/Wasabi/api/wnd/blending.h536
-rw-r--r--Src/Wasabi/api/wnd/bltcanvas.h5
-rw-r--r--Src/Wasabi/api/wnd/bucketitem.h76
-rw-r--r--Src/Wasabi/api/wnd/canvas.cpp3
-rw-r--r--Src/Wasabi/api/wnd/canvas.h5
-rw-r--r--Src/Wasabi/api/wnd/contextmenu.cpp170
-rw-r--r--Src/Wasabi/api/wnd/contextmenu.h42
-rw-r--r--Src/Wasabi/api/wnd/cursor.cpp48
-rw-r--r--Src/Wasabi/api/wnd/cursor.h62
-rw-r--r--Src/Wasabi/api/wnd/cwndtrack.h11
-rw-r--r--Src/Wasabi/api/wnd/deactivatemgr.cpp55
-rw-r--r--Src/Wasabi/api/wnd/deactivatemgr.h22
-rw-r--r--Src/Wasabi/api/wnd/di.cpp46
-rw-r--r--Src/Wasabi/api/wnd/drag.h75
-rw-r--r--Src/Wasabi/api/wnd/dragitem.h23
-rw-r--r--Src/Wasabi/api/wnd/dragitemi.cpp36
-rw-r--r--Src/Wasabi/api/wnd/dragitemi.h58
-rw-r--r--Src/Wasabi/api/wnd/fakedrag.h12
-rw-r--r--Src/Wasabi/api/wnd/findobjectcb.cpp8
-rw-r--r--Src/Wasabi/api/wnd/findobjectcb.h44
-rw-r--r--Src/Wasabi/api/wnd/fontdef.h15
-rw-r--r--Src/Wasabi/api/wnd/ifc_bitmap.h51
-rw-r--r--Src/Wasabi/api/wnd/keyboard.cpp570
-rw-r--r--Src/Wasabi/api/wnd/keyboard.h77
-rw-r--r--Src/Wasabi/api/wnd/minibrowser.cpp28
-rw-r--r--Src/Wasabi/api/wnd/minibrowser.h1
-rw-r--r--Src/Wasabi/api/wnd/notifmsg.h109
-rw-r--r--Src/Wasabi/api/wnd/paintcb.cpp52
-rw-r--r--Src/Wasabi/api/wnd/paintcb.h73
-rw-r--r--Src/Wasabi/api/wnd/paintset.cpp603
-rw-r--r--Src/Wasabi/api/wnd/paintset.h18
-rw-r--r--Src/Wasabi/api/wnd/paintsets.h18
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp51
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h45
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/bltcanvas.h26
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/canvas.h69
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp220
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h47
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp95
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp275
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp217
-rw-r--r--Src/Wasabi/api/wnd/platform/osx/region.h115
-rw-r--r--Src/Wasabi/api/wnd/platform/win32/bitmap.h81
-rw-r--r--Src/Wasabi/api/wnd/platform/win32/canvas.h1
-rw-r--r--Src/Wasabi/api/wnd/platform/win32/region.h135
-rw-r--r--Src/Wasabi/api/wnd/popexitcb.cpp8
-rw-r--r--Src/Wasabi/api/wnd/popexitcb.h40
-rw-r--r--Src/Wasabi/api/wnd/popexitchecker.cpp79
-rw-r--r--Src/Wasabi/api/wnd/popexitchecker.h39
-rw-r--r--Src/Wasabi/api/wnd/popup.cpp1720
-rw-r--r--Src/Wasabi/api/wnd/popup.h341
-rw-r--r--Src/Wasabi/api/wnd/region.cpp1
-rw-r--r--Src/Wasabi/api/wnd/region.h5
-rw-r--r--Src/Wasabi/api/wnd/resizable.h21
-rw-r--r--Src/Wasabi/api/wnd/rootwnd.cpp197
-rw-r--r--Src/Wasabi/api/wnd/rootwnd.h275
-rw-r--r--Src/Wasabi/api/wnd/textalign.h32
-rw-r--r--Src/Wasabi/api/wnd/usermsg.h23
-rw-r--r--Src/Wasabi/api/wnd/virtualwnd.cpp672
-rw-r--r--Src/Wasabi/api/wnd/virtualwnd.h84
-rw-r--r--Src/Wasabi/api/wnd/wndapi.cpp384
-rw-r--r--Src/Wasabi/api/wnd/wndapi.h101
-rw-r--r--Src/Wasabi/api/wnd/wndclass/SelItemList.cpp72
-rw-r--r--Src/Wasabi/api/wnd/wndclass/SelItemList.h31
-rw-r--r--Src/Wasabi/api/wnd/wndclass/abstractwndhold.cpp287
-rw-r--r--Src/Wasabi/api/wnd/wndclass/abstractwndhold.h267
-rw-r--r--Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp1113
-rw-r--r--Src/Wasabi/api/wnd/wndclass/appbarwnd.h155
-rw-r--r--Src/Wasabi/api/wnd/wndclass/backbufferwnd.cpp86
-rw-r--r--Src/Wasabi/api/wnd/wndclass/backbufferwnd.h53
-rw-r--r--Src/Wasabi/api/wnd/wndclass/blankwnd.cpp24
-rw-r--r--Src/Wasabi/api/wnd/wndclass/blankwnd.h41
-rw-r--r--Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.cpp113
-rw-r--r--Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.h40
-rw-r--r--Src/Wasabi/api/wnd/wndclass/buttbar.cpp208
-rw-r--r--Src/Wasabi/api/wnd/wndclass/buttbar.h168
-rw-r--r--Src/Wasabi/api/wnd/wndclass/buttwnd.cpp761
-rw-r--r--Src/Wasabi/api/wnd/wndclass/buttwnd.h602
-rw-r--r--Src/Wasabi/api/wnd/wndclass/clickwnd.cpp319
-rw-r--r--Src/Wasabi/api/wnd/wndclass/clickwnd.h74
-rw-r--r--Src/Wasabi/api/wnd/wndclass/ddrawwnd.cpp219
-rw-r--r--Src/Wasabi/api/wnd/wndclass/ddrawwnd.h60
-rw-r--r--Src/Wasabi/api/wnd/wndclass/editwnd.cpp1001
-rw-r--r--Src/Wasabi/api/wnd/wndclass/editwnd.h134
-rw-r--r--Src/Wasabi/api/wnd/wndclass/editwndstring.cpp17
-rw-r--r--Src/Wasabi/api/wnd/wndclass/editwndstring.h24
-rw-r--r--Src/Wasabi/api/wnd/wndclass/embeddedxui.cpp143
-rw-r--r--Src/Wasabi/api/wnd/wndclass/embeddedxui.h88
-rw-r--r--Src/Wasabi/api/wnd/wndclass/foreignwnd.cpp60
-rw-r--r--Src/Wasabi/api/wnd/wndclass/foreignwnd.h56
-rw-r--r--Src/Wasabi/api/wnd/wndclass/framewnd.cpp777
-rw-r--r--Src/Wasabi/api/wnd/wndclass/framewnd.h124
-rw-r--r--Src/Wasabi/api/wnd/wndclass/gradientwnd.cpp82
-rw-r--r--Src/Wasabi/api/wnd/wndclass/gradientwnd.h31
-rw-r--r--Src/Wasabi/api/wnd/wndclass/guiobjwnd.cpp476
-rw-r--r--Src/Wasabi/api/wnd/wndclass/guiobjwnd.h237
-rw-r--r--Src/Wasabi/api/wnd/wndclass/itemlistwnd.cpp286
-rw-r--r--Src/Wasabi/api/wnd/wndclass/itemlistwnd.h426
-rw-r--r--Src/Wasabi/api/wnd/wndclass/labelwnd.cpp203
-rw-r--r--Src/Wasabi/api/wnd/wndclass/labelwnd.h46
-rw-r--r--Src/Wasabi/api/wnd/wndclass/listwnd.cpp2151
-rw-r--r--Src/Wasabi/api/wnd/wndclass/listwnd.h459
-rw-r--r--Src/Wasabi/api/wnd/wndclass/oswnd.cpp32
-rw-r--r--Src/Wasabi/api/wnd/wndclass/oswnd.h19
-rw-r--r--Src/Wasabi/api/wnd/wndclass/oswndhost.cpp14
-rw-r--r--Src/Wasabi/api/wnd/wndclass/oswndhost.h53
-rw-r--r--Src/Wasabi/api/wnd/wndclass/qpaintwnd.cpp357
-rw-r--r--Src/Wasabi/api/wnd/wndclass/qpaintwnd.h154
-rw-r--r--Src/Wasabi/api/wnd/wndclass/rootwndholder.cpp113
-rw-r--r--Src/Wasabi/api/wnd/wndclass/rootwndholder.h41
-rw-r--r--Src/Wasabi/api/wnd/wndclass/scbkgwnd.cpp869
-rw-r--r--Src/Wasabi/api/wnd/wndclass/scbkgwnd.h463
-rw-r--r--Src/Wasabi/api/wnd/wndclass/scrollbar.cpp679
-rw-r--r--Src/Wasabi/api/wnd/wndclass/scrollbar.h423
-rw-r--r--Src/Wasabi/api/wnd/wndclass/sepwnd.cpp63
-rw-r--r--Src/Wasabi/api/wnd/wndclass/sepwnd.h27
-rw-r--r--Src/Wasabi/api/wnd/wndclass/slider.cpp705
-rw-r--r--Src/Wasabi/api/wnd/wndclass/slider.h451
-rw-r--r--Src/Wasabi/api/wnd/wndclass/status.cpp242
-rw-r--r--Src/Wasabi/api/wnd/wndclass/status.h178
-rw-r--r--Src/Wasabi/api/wnd/wndclass/svcwndhold.cpp53
-rw-r--r--Src/Wasabi/api/wnd/wndclass/svcwndhold.h51
-rw-r--r--Src/Wasabi/api/wnd/wndclass/tabsheet.cpp544
-rw-r--r--Src/Wasabi/api/wnd/wndclass/tabsheet.h268
-rw-r--r--Src/Wasabi/api/wnd/wndclass/tabsheetbar.cpp130
-rw-r--r--Src/Wasabi/api/wnd/wndclass/tabsheetbar.h39
-rw-r--r--Src/Wasabi/api/wnd/wndclass/textbar.cpp148
-rw-r--r--Src/Wasabi/api/wnd/wndclass/textbar.h219
-rw-r--r--Src/Wasabi/api/wnd/wndclass/tooltip.cpp47
-rw-r--r--Src/Wasabi/api/wnd/wndclass/tooltip.h18
-rw-r--r--Src/Wasabi/api/wnd/wndclass/treewnd.cpp1645
-rw-r--r--Src/Wasabi/api/wnd/wndclass/treewnd.h624
-rw-r--r--Src/Wasabi/api/wnd/wndclass/typesheet.cpp38
-rw-r--r--Src/Wasabi/api/wnd/wndclass/typesheet.h49
-rw-r--r--Src/Wasabi/api/wnd/wndclass/virtualhostwnd.cpp198
-rw-r--r--Src/Wasabi/api/wnd/wndclass/virtualhostwnd.h51
-rw-r--r--Src/Wasabi/api/wnd/wndclass/wndholder.cpp369
-rw-r--r--Src/Wasabi/api/wnd/wndclass/wndholder.h285
-rw-r--r--Src/Wasabi/api/wnd/wndevent.h5
-rw-r--r--Src/Wasabi/api/wnd/wndtrack.cpp945
-rw-r--r--Src/Wasabi/api/wnd/wndtrack.h104
-rw-r--r--Src/Wasabi/api/wndmgr/alphamgr.cpp661
-rw-r--r--Src/Wasabi/api/wndmgr/alphamgr.h136
-rw-r--r--Src/Wasabi/api/wndmgr/animate.cpp96
-rw-r--r--Src/Wasabi/api/wndmgr/animate.h11
-rw-r--r--Src/Wasabi/api/wndmgr/api_wndmgr.cpp47
-rw-r--r--Src/Wasabi/api/wndmgr/api_wndmgr.h305
-rw-r--r--Src/Wasabi/api/wndmgr/appcmds.cpp61
-rw-r--r--Src/Wasabi/api/wndmgr/appcmds.h89
-rw-r--r--Src/Wasabi/api/wndmgr/autopopup.cpp157
-rw-r--r--Src/Wasabi/api/wndmgr/autopopup.h76
-rw-r--r--Src/Wasabi/api/wndmgr/container.cpp919
-rw-r--r--Src/Wasabi/api/wndmgr/container.h231
-rw-r--r--Src/Wasabi/api/wndmgr/gc.cpp24
-rw-r--r--Src/Wasabi/api/wndmgr/gc.h19
-rw-r--r--Src/Wasabi/api/wndmgr/guistatuscb.cpp15
-rw-r--r--Src/Wasabi/api/wndmgr/guistatuscb.h83
-rw-r--r--Src/Wasabi/api/wndmgr/layout.cpp2586
-rw-r--r--Src/Wasabi/api/wndmgr/layout.h465
-rw-r--r--Src/Wasabi/api/wndmgr/msgbox.cpp251
-rw-r--r--Src/Wasabi/api/wndmgr/msgbox.h49
-rw-r--r--Src/Wasabi/api/wndmgr/resize.cpp383
-rw-r--r--Src/Wasabi/api/wndmgr/resize.h48
-rw-r--r--Src/Wasabi/api/wndmgr/skinembed.cpp733
-rw-r--r--Src/Wasabi/api/wndmgr/skinembed.h76
-rw-r--r--Src/Wasabi/api/wndmgr/skinwnd.cpp99
-rw-r--r--Src/Wasabi/api/wndmgr/skinwnd.h42
-rw-r--r--Src/Wasabi/api/wndmgr/snappnt.cpp181
-rw-r--r--Src/Wasabi/api/wndmgr/snappnt.h49
-rw-r--r--Src/Wasabi/api/wndmgr/wndmgrapi.cpp279
-rw-r--r--Src/Wasabi/api/wndmgr/wndmgrapi.h59
-rw-r--r--Src/Wasabi/api/xml/LoadXML.cpp92
-rw-r--r--Src/Wasabi/api/xml/LoadXML.h7
-rw-r--r--Src/Wasabi/api/xml/XMLAutoInclude.cpp87
-rw-r--r--Src/Wasabi/api/xml/XMLAutoInclude.h22
-rw-r--r--Src/Wasabi/api/xml/api_xmlreadercallback.cpp2
-rw-r--r--Src/Wasabi/api/xml/xmlparams.cpp12
-rw-r--r--Src/Wasabi/api/xml/xmlparams.h103
-rw-r--r--Src/Wasabi/api/xml/xmlparamsi.cpp119
-rw-r--r--Src/Wasabi/api/xml/xmlparamsi.h52
-rw-r--r--Src/Wasabi/api/xml/xmlparamsx.cpp32
-rw-r--r--Src/Wasabi/api/xml/xmlparamsx.h38
-rw-r--r--Src/Wasabi/api/xml/xmlparse.h23
-rw-r--r--Src/Wasabi/api/xml/xmlreader.cpp197
-rw-r--r--Src/Wasabi/api/xml/xmlreader.h75
-rw-r--r--Src/Wasabi/api/xml/xmlwrite.cpp262
-rw-r--r--Src/Wasabi/api/xml/xmlwrite.h45
937 files changed, 150769 insertions, 0 deletions
diff --git a/Src/Wasabi/api/apiconfig.h b/Src/Wasabi/api/apiconfig.h
new file mode 100644
index 00000000..722bf444
--- /dev/null
+++ b/Src/Wasabi/api/apiconfig.h
@@ -0,0 +1,176 @@
+#ifndef __API_DEF_CFG_H
+#define __API_DEF_CFG_H
+
+#define WASABINOMAINAPI
+
+#ifdef WASABI_COMPILE_APP
+# define WASABI_API_APP applicationApi
+#endif
+
+#ifdef WASABI_COMPILE_SVC
+# define WASABI_API_SVC serviceApi
+#endif
+
+#ifdef WASABI_COMPILE_SYSCB
+# define WASABI_API_SYSCB sysCallbackApi
+#endif
+
+#ifdef WASABI_COMPILE_COMPONENTS
+# define WASABI_API_COMPONENT componentApi
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+# define WASABI_API_MAKI makiApi
+#endif
+
+#ifdef WASABI_COMPILE_UTF
+# define WASABI_API_UTF utfApi
+#endif
+
+#ifdef WASABI_COMPILE_WND
+# define WASABI_API_WND wndApi
+#endif
+
+#ifdef WASABI_COMPILE_IMGLDR
+# define WASABI_API_IMGLDR imgLoaderApi
+#endif
+
+#ifdef WASABI_COMPILE_FILEREADER
+# define WASABI_API_FILE fileApi
+#endif
+
+#ifdef WASABI_COMPILE_TIMERS
+# define WASABI_API_TIMER timerApi
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+# define WASABI_API_WNDMGR wndManagerApi
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+# define WASABI_API_SKIN skinApi
+#endif
+
+#ifdef WASABI_COMPILE_METADB
+# define WASABI_API_METADB metadbApi
+#endif
+
+#ifdef WASABI_COMPILE_LOCALES
+# define WASABI_API_LOCALE localeApi
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+# define WASABI_API_CONFIG configApi
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+# define WASABI_API_FONT fontApi
+// This sets the static font renderer. If you are compiling with api_config, the attribute to set is { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } }, "Font Renderer"
+# if defined(WASABI_FONT_RENDERER_USE_WIN32)
+# define WASABI_FONT_RENDERER "" // "" is Win32
+# elif defined(WASABI_FONT_RENDERER_USE_FREETYPE)
+# define WASABI_FONT_RENDERER "Freetype" // Freetype lib
+# else
+# define WASABI_FONT_RENDERER "" // "" default for OS
+# endif
+#endif
+
+#ifdef WASABI_COMPILE_MEMMGR
+# define WASABI_API_MEMMGR memmgrApi
+#endif
+
+#ifdef WASABI_COMPILE_XMLPARSER
+# define WASABI_API_XML xmlApi
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+# define WASABI_API_MEDIACORE coreApi
+#endif
+
+#ifdef WASABI_COMPILE_TEXTMODE
+# define WASABI_API_TEXTMODE textmodeApi
+#endif
+
+#ifdef LINUX
+# define WASABI_COMPILE_LINUX
+# define WASABI_API_LINUX linuxApi
+#endif
+
+#ifdef WASABI_COMPILE_STATSWND
+# if defined(_DEBUG) | defined(WASABI_DEBUG)
+# define WASABI_COMPILE_STATSWND
+# ifndef WASABI_DEBUG
+# define WASABI_DEBUG
+# endif
+# endif
+#endif
+
+#ifdef WASABI_COMPILE_APP
+# include <api/application/api_application.h>
+#endif
+
+#ifdef WASABI_COMPILE_SVC
+# include <api/service/api_service.h>
+#endif
+
+#ifdef WASABI_COMPILE_SYSCB
+# include <api/syscb/api_syscb.h>
+#endif
+
+#ifdef WASABI_COMPILE_MEMMGR
+# include <api/memmgr/api_memmgr.h>
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+# include <api/script/api_maki.h>
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+# include <api/font/api_font.h>
+#endif
+
+#ifdef WASABI_COMPILE_WND
+# include <api/wnd/api_wnd.h>
+#endif
+
+#ifdef WASABI_COMPILE_IMGLDR
+# include <api/imgldr/api_imgldr.h>
+#endif
+
+#ifdef WASABI_COMPILE_FILEREADER
+# include <api/filereader/api_filereader.h>
+#endif
+
+#ifdef WASABI_COMPILE_TIMERS
+# include <api/timer/api_timer.h>
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+# include <api/wndmgr/api_wndmgr.h>
+#endif
+
+#ifdef WASABI_COMPILE_LOCALES
+# include <api/locales/api_locales.h>
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+# include <api/config/api_config.h>
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+# include <api/skin/api_skin.h>
+#endif
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+# include <api/script/debugger/api_makidebug.h>
+#endif
+
+#ifdef WASABI_COMPILE_TEXTMODE
+# include <api/textmode/api_textmode.h>
+#endif
+
+#ifdef WASABI_API_LINUX
+#include <api/linux/api_linux.h>
+#endif
+
+#endif
diff --git a/Src/Wasabi/api/apiinit.cpp b/Src/Wasabi/api/apiinit.cpp
new file mode 100644
index 00000000..0b198ad6
--- /dev/null
+++ b/Src/Wasabi/api/apiinit.cpp
@@ -0,0 +1,548 @@
+#include "./wndmgr/layout.h"
+
+#include <tataki/export.h>
+//<?#include "<class data="implementationheader"/>"
+#include "apiinit.h"
+//?>
+
+#include <api/memmgr/api_memmgr.h>
+
+#define WASABI_SAYMYNAME
+#include <wasabicfg.h>
+#undef WASABI_SAYMYNAME
+
+#include <api/service/servicei.h>
+#include <api/locales/api_localesi.h>
+#include <api/config/api_configi.h>
+#include <api/config/items/cfgitem.h>
+#ifdef WASABI_COMPILE_FONTS
+#include <api/font/FontCreator.h>
+#include <api/font/fontapi.h>
+#endif
+#include <api/skin/skinapi.h>
+#include <api/skin/groupwndcreate.h>
+#include <api/script/makiapi.h>
+#include <api/script/objecttable.h>
+#include <api/wnd/wndapi.h>
+#include <api/wnd/wndclass/foreignwnd.h>
+#include <api/wnd/wndclass/clickwnd.h>
+#include <api/imgldr/imgldrapi.h>
+
+#ifdef WASABI_COMPILE_FONTS
+#ifdef WIN32
+# include <api/font/win32/truetypefont_win32.h>
+#elif defined(LINUX)
+# include <api/font/linux/truetypefont_linux.h>
+#else
+# error port me
+#endif // platform
+#endif // fonts
+
+#include <api/wndmgr/wndmgrapi.h>
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+#include <api/script/debugger/debugapi.h>
+#endif
+#ifdef WASABI_COMPILE_MAKIDEBUG
+#include <api/core/api_core.h>
+#endif
+#ifdef WASABI_COMPILE_FILEREADER
+#include <api/filereader/filereaderapi.h>
+#ifdef WASABI_COMPILE_ZIPREADER
+#include <api/filereader/zip/zipread.h>
+#endif
+#endif
+#ifdef WASABI_COMPILE_LINUX
+#include <api/linux/api_linuxi.h>
+#endif
+#ifdef WASABI_COMPILE_TEXTMODE
+#if defined(WIN32)
+#include <api/textmode/textmode_win32.h>
+#elif defined(LINUX)
+#include <api/textmode/textmode_ncurses.h>
+#else // dummy
+#include <api/textmode/api_textmodeI.h>
+#endif
+#endif
+
+
+#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME
+#include <api/wac/compon.h>
+#endif
+
+#include <api/wndmgr/gc.h>
+
+#include <api/application/api_application.h>
+#ifndef WASABI_CUSTOM_MODULE_SVCMGR
+DECLARE_MODULE_SVCMGR;
+#endif
+
+#ifdef _WIN32
+extern HINSTANCE hInstance;
+#endif
+
+extern StringW g_resourcepath;
+api_application *applicationApi = NULL;
+timer_api *timerApi = NULL;
+
+int ApiInit::init(OSMODULEHANDLE hinstance, OSWINDOWHANDLE mainwnd, api_service *wa5_svc)
+{
+ Tataki::Init(wa5_svc);
+ serviceApi = wa5_svc;
+ initcount++;
+
+#ifndef WA3COMPATIBILITY
+
+ // ------------------------------------------------------------------------
+ // Init callback system
+ // ------------------------------------------------------------------------
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(syscbApiServiceGuid);
+ if (sf) sysCallbackApi = reinterpret_cast<api_syscb *>(sf->getInterface());
+
+ // ------------------------------------------------------------------------
+ // Init application API
+ // ------------------------------------------------------------------------
+
+ sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf) applicationApi = reinterpret_cast<api_application *>(sf->getInterface());
+
+g_resourcepath = StringPathCombine(WASABI_API_APP->path_getAppPath(), WASABI_RESOURCES_SUBDIRECTORY);
+
+ // ------------------------------------------------------------------------
+ // Init centralized memory manager api
+ // ------------------------------------------------------------------------
+
+ sf = WASABI_API_SVC->service_getServiceByGuid(memMgrApiServiceGuid);
+ if (sf) WASABI_API_MEMMGR = reinterpret_cast<api_memmgr *>(sf->getInterface());
+
+#ifdef WASABI_COMPILE_FILEREADER
+ // ------------------------------------------------------------------------
+ // Init file reader api and optional file readers
+ // ------------------------------------------------------------------------
+ fr = new FileReaderApi();
+ fileApi = fr;
+ WASABI_API_SVC->service_register(frapisvc = new FileReaderApiService());
+ //WASABI_API_SVC->service_register(&diskReader);
+ // set up custom file readers
+#ifdef WASABI_COMPILE_ZIPREADER
+ zipRead = new waServiceTSingle<svc_fileReader, ZipRead>;
+#endif
+#ifdef WASABI_COMPILE_ZIPREADER
+ WASABI_API_SVC->service_register(zipRead);
+#endif
+#endif // WASABI_COMPILE_FILEREADER
+
+
+ // ------------------------------------------------------------------------
+ // Init config api and register optional config items
+ // ------------------------------------------------------------------------
+#ifdef WASABI_COMPILE_CONFIG
+ cfg = new api_configI();
+ configApi = cfg;
+ WASABI_API_SVC->service_register(cfgapisvc = new ConfigApiService());
+#endif
+
+ // if no static service was ever declared, we need to init it so we don't hit null
+ INIT_MODULE_SVCMGR();
+
+ DebugStringW(L"Auto-initializing %d services (system pass)\n", staticServiceMgr->__m_modules2.getNumItems());
+ MODULE_SVCMGR_ONINIT2();
+
+#ifdef WASABI_COMPILE_IMGLDR
+ // ------------------------------------------------------------------------
+ // Init image loading api and optional image formats
+ // ------------------------------------------------------------------------
+ img = new ImgLdrApi();
+ imgLoaderApi = img;
+ WASABI_API_SVC->service_register(imgldrapisvc = new ImgLdrApiService());
+
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+ // ------------------------------------------------------------------------
+ // Init font rendering api
+ // ------------------------------------------------------------------------
+ font = new FontApi();
+ fontApi = font;
+ win32Font = new FontCreator<TrueTypeFont_Win32>;
+ WASABI_API_SVC->service_register(win32Font);
+ WASABI_API_SVC->service_register(fontapisvc = new FontApiService());
+#endif
+
+
+#ifdef WASABI_COMPILE_LOCALES
+ // ------------------------------------------------------------------------
+ // Init localization
+ // ------------------------------------------------------------------------
+ loc = new api_localesI();
+ localesApi = loc;
+ WASABI_API_SVC->service_register(localesapisvc = new LocalesApiService());
+#endif
+
+ // ------------------------------------------------------------------------
+ // Init timer api
+ // ------------------------------------------------------------------------
+ sf = WASABI_API_SVC->service_getServiceByGuid(timerApiServiceGuid);
+ if (sf) timerApi = reinterpret_cast<timer_api *>(sf->getInterface());
+
+
+#ifdef WASABI_COMPILE_WND
+ // ------------------------------------------------------------------------
+ // Init window api
+ // ------------------------------------------------------------------------
+ wnd = new WndApi();
+ wndApi = wnd;
+#ifdef _WIN32
+ if (mainwnd != NULL)
+ {
+ mainWnd = new ForeignWnd(mainwnd, hInstance);
+ DebugStringW(L"main wnd handle is %x\n", mainWnd->gethWnd());
+ wnd->main_setRootWnd(mainWnd);
+ }
+ else
+ {
+ default_mainWnd = new ClickWnd();
+ default_mainWnd->init(hInstance, NULL, TRUE);
+ wnd->main_setRootWnd(default_mainWnd);
+ }
+ #endif
+ WASABI_API_SVC->service_register(wndapisvc = new WndApiService());
+#endif
+
+ // ------------------------------------------------------------------------
+ // Init media core api
+ // ------------------------------------------------------------------------
+#ifdef WASABI_COMPILE_MEDIACORE
+ #ifndef WA3COMPATIBILITY
+ #ifdef WASABI_CUSTOMIMPL_MEDIACORE
+ coreApi = createCustomCoreApi();
+#else
+ #error "not done yet"
+ #endif
+ #endif
+ WASABI_API_SVC->service_register(coreapisvc = new CoreApiService());
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+ // ------------------------------------------------------------------------
+ // Init window manager api
+ // ------------------------------------------------------------------------
+ wndmgr = new WndMgrApi ();
+ wndManagerApi = wndmgr;
+ WASABI_API_SVC->service_register(wndmgrapisvc = new WndMgrApiService());
+#endif
+
+
+
+#ifdef WASABI_COMPILE_SKIN
+ // ------------------------------------------------------------------------
+ // Init skin
+ // ------------------------------------------------------------------------
+ skin = new SkinApi();
+ skinApi = skin;
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ groupcreate = new waServiceTSingle<svc_windowCreate, GroupWndCreateSvc>;
+ WASABI_API_SVC->service_register(groupcreate);
+#endif
+
+ WASABI_API_SVC->service_register(skinapisvc = new SkinApiService());
+
+#endif
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ // ------------------------------------------------------------------------
+ // Init script debugger api
+ // ------------------------------------------------------------------------
+ debug = new MakiDebuggerApi();
+ debugApi = debug;
+ WASABI_API_SVC->service_register(makidebugapisvc = new MakiDebugApiService());
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+ widgets = new Widgets();
+#endif
+
+#endif
+
+
+ DebugStringW(L"Auto-initializing %d services (user pass)\n", staticServiceMgr->__m_modules.getNumItems());
+ MODULE_SVCMGR_ONINIT();
+
+#ifndef WA3COMPATIBILITY
+
+#ifdef WASABI_COMPILE_SCRIPT
+ // ------------------------------------------------------------------------
+ // Init scripting api
+ // ------------------------------------------------------------------------
+ maki = new api_makiI();
+ makiApi = maki;
+ WASABI_API_SVC->service_register(makiapisvc = new MakiApiService());
+ maki->init();
+
+
+
+#ifdef WASABI_COMPILE_WNDMGR
+ garbageCollector = new GarbageCollector();
+#endif
+
+ ObjectTable::start();
+#endif
+
+#endif //wa3compat
+
+ return 1; // success
+}
+
+int ApiInit::shutdown()
+{
+#ifndef WA3COMPATIBILITY
+
+ garbageCollector->gccb_onGarbageCollect();
+ delete garbageCollector;
+
+#ifdef WASABI_COMPILE_SKIN
+ skin->preShutdown();
+#endif
+
+ MODULE_SVCMGR_ONSHUTDOWN();
+
+#ifdef _WIN32
+ ComponentManager::unloadAll();
+#else
+#warning port me?
+#endif
+
+ WASABI_API_SVC->service_deregister(skinapisvc);
+ delete skin;
+ skinApi = NULL;
+
+ delete skinapisvc;
+ skinapisvc = 0;
+
+#ifdef WASABI_COMPILE_SCRIPT
+ ObjectTable::shutdown();
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+ delete widgets;
+ widgets = NULL;
+#endif
+ WASABI_API_SVC->service_deregister(makiapisvc);
+ delete maki;
+ makiApi = NULL;
+
+ delete makiapisvc;
+ makiapisvc = 0;
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ WASABI_API_SVC->service_deregister(groupcreate);
+ delete groupcreate;
+ groupcreate = 0;
+#endif
+
+ WASABI_API_SVC->service_deregister(win32Font);
+ delete win32Font;
+ win32Font = 0;
+
+#ifdef WASABI_COMPILE_MEDIACORE
+ #ifndef WA3COMPATIBILITY
+ #ifdef WASABI_CUSTOMIMPL_MEDIACORE
+ destroyCustomCoreApi(coreApi);
+#else
+ #error "not done yet"
+ #endif
+ #endif
+
+ WASABI_API_SVC->service_deregister(coreapisvc);
+ delete coreapisvc;
+ coreapisvc = 0;
+#endif
+
+
+
+ WASABI_API_SVC->service_deregister(wndmgrapisvc);
+ delete wndmgr;
+ wndManagerApi = NULL;
+
+
+ delete wndmgrapisvc;
+ wndmgrapisvc = 0;
+
+
+ delete loc;
+ localesApi = NULL;
+
+ WASABI_API_SVC->service_deregister(localesapisvc);
+ delete localesapisvc;
+ localesapisvc = 0;
+
+
+#ifdef WASABI_COMPILE_FILEREADER
+#ifdef WASABI_COMPILE_ZIPREADER
+ WASABI_API_SVC->service_deregister(zipRead);
+ delete zipRead;
+#endif
+
+
+ delete fr;
+ fileApi = NULL;
+
+ WASABI_API_SVC->service_deregister(frapisvc);
+ delete frapisvc;
+ frapisvc = 0;
+#endif
+
+#endif
+
+ delete mainWnd;
+ mainWnd = NULL;
+ delete default_mainWnd;
+ default_mainWnd = NULL;
+ WASABI_API_SVC->service_deregister(wndapisvc);
+ delete wnd;
+ wndApi = NULL;
+
+ delete wndapisvc;
+ wndapisvc = 0;
+
+#ifdef WASABI_COMPILE_FONTS
+ WASABI_API_SVC->service_deregister(fontapisvc);
+ delete font;
+ fontApi = NULL;
+
+ delete fontapisvc;
+ fontapisvc = 0;
+#endif
+
+#ifndef WA3COMPATIBILITY
+
+
+ delete img;
+ imgLoaderApi = NULL;
+
+ WASABI_API_SVC->service_deregister(imgldrapisvc);
+ delete imgldrapisvc;
+ imgldrapisvc = 0;
+
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_SVC->service_deregister(cfgapisvc);
+ delete cfg;
+ configApi = NULL;
+
+ delete cfgapisvc;
+ cfgapisvc = 0;
+#endif
+
+ MODULE_SVCMGR_ONSHUTDOWN2();
+
+ WASABI_API_MEMMGR = NULL;
+
+applicationApi=NULL;
+#endif //wa3compatibility
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ delete debug;
+ debugApi = NULL;
+
+ WASABI_API_SVC->service_deregister(makidebugapisvc);
+ delete makidebugapisvc;
+ makidebugapisvc = 0;
+#endif
+
+ if (alphaMgr)
+ delete alphaMgr;
+ alphaMgr=0;
+
+ // TODO: releaseInterface
+ timerApi = NULL;
+
+ Tataki::Quit();
+ sysCallbackApi = NULL;
+
+ return 1; // success
+}
+
+int ApiInit::getInitCount()
+{
+ return initcount;
+}
+
+#ifdef WASABI_COMPILE_SKIN
+#ifdef WASABI_COMPILE_COMPONENTS
+waServiceFactoryI * ApiInit::groupcreate = NULL;
+#endif
+#endif //WASABI_COMPILE_SKIN
+
+#ifdef WASABI_COMPILE_FONTS
+waServiceFactoryI * ApiInit::win32Font = NULL;
+FontApiService *ApiInit::fontapisvc = NULL;
+#endif //WASABI_COMPILE_FONTS
+
+#ifdef WASABI_COMPILE_SKIN
+Widgets * ApiInit::widgets = NULL;
+SkinApiService *ApiInit::skinapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+api_configI * ApiInit::cfg = NULL;
+ConfigApiService *ApiInit::cfgapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_IMGLDR
+ImgLdrApi * ApiInit::img = NULL;
+ImgLdrApiService *ApiInit::imgldrapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+FontApi * ApiInit::font = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_FILEREADER
+FileReaderApi * ApiInit::fr = NULL;
+#ifdef WASABI_COMPILE_ZIPREADER
+waServiceFactoryI * ApiInit::zipRead = NULL;
+#endif
+FileReaderApiService *ApiInit::frapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_LOCALES
+api_localesI * ApiInit::loc = NULL;
+LocalesApiService *ApiInit::localesapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_WND
+WndApi * ApiInit::wnd = NULL;
+ForeignWnd * ApiInit::mainWnd = NULL;
+ClickWnd * ApiInit::default_mainWnd = NULL;
+WndApiService *ApiInit::wndapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+WndMgrApi * ApiInit::wndmgr = NULL;
+WndMgrApiService *ApiInit::wndmgrapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+api_makiI * ApiInit::maki = NULL;
+MakiApiService *ApiInit::makiapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+SkinApi * ApiInit::skin = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+MakiDebuggerApi * ApiInit::debug = NULL;
+MakiDebugApiService *ApiInit::makidebugapisvc = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+CoreApiService *ApiInit::coreapisvc = NULL;
+#endif
+
+
+int ApiInit::initcount = 0;
+
+api_memmgr *memmgrApi = NULL; \ No newline at end of file
diff --git a/Src/Wasabi/api/apiinit.h b/Src/Wasabi/api/apiinit.h
new file mode 100644
index 00000000..2bf3adae
--- /dev/null
+++ b/Src/Wasabi/api/apiinit.h
@@ -0,0 +1,255 @@
+#ifndef __API_INIT_H
+#define __API_INIT_H
+
+#include <bfc/platform/platform.h>
+#include <api/skin/widgets.h>
+#include <bfc/string/bfcstring.h>
+#include <api/syscb/api_syscbi.h>
+#include <api/service/service.h>
+
+class api_configI;
+class SkinApi;
+class api_makiI;
+class MemMgrApi;
+class TimerApi;
+class WndApi;
+class ForeignWnd;
+class ClickWnd;
+
+class ImgLdrApi;
+#ifdef WASABI_COMPILE_FONTS
+class FontApi;
+#endif
+#ifdef WASABI_COMPILE_WNDMGR
+class WndMgrApi;
+#endif
+#ifdef WASABI_COMPILE_MAKIDEBUG
+class MakiDebuggerApi;
+#endif
+#ifdef WASABI_COMPILE_FILEREADER
+class FileReaderApi;
+#endif
+#ifdef WASABI_COMPILE_LOCALES
+class api_localesI;
+#endif
+#ifndef WA3COMPATIBILITY
+#ifdef WASABI_COMPILE_MEDIACORE
+class Core;
+#endif
+#endif
+
+
+
+#include <api/syscb/api_syscb.h>
+
+
+
+
+#ifdef WASABI_COMPILE_MEDIACORE
+
+#include <api/core/api_core.h>
+
+class CoreApiService : public waServiceBase<api_core, CoreApiService> {
+public:
+ CoreApiService() : waServiceBase<api_core, CoreApiService>(coreApiServiceGuid) {}
+ static const char *getServiceName() { return "Core API"; }
+ virtual api_core *getService() { return coreApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#endif // WASABI_COMPILE_MEDIACORE
+
+#ifdef WASABI_COMPILE_FILEREADER
+
+#include <api/filereader/api_filereader.h>
+
+class FileReaderApiService : public waServiceBase<api_fileReader, FileReaderApiService> {
+public:
+ FileReaderApiService() : waServiceBase<api_fileReader, FileReaderApiService>(fileReaderApiServiceGuid) {}
+ static const char *getServiceName() { return "FileReader API"; }
+ virtual api_fileReader *getService() { return fileApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#endif // WASABI_COMPILE_FILEREADER
+
+#ifdef WASABI_COMPILE_CONFIG
+
+#include <api/config/api_config.h>
+
+class ConfigApiService : public waServiceBase<api_config, ConfigApiService> {
+public:
+ ConfigApiService() : waServiceBase<api_config, ConfigApiService>(configApiServiceGuid) {}
+ static const char *getServiceName() { return "Config API"; }
+ virtual api_config *getService() { return configApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#endif // WASABI_COMPILE_CONFIG
+
+#ifdef WASABI_COMPILE_IMGLDR
+
+#include <api/imgldr/api_imgldr.h>
+
+class ImgLdrApiService: public waServiceBase<imgldr_api, ImgLdrApiService> {
+public:
+ ImgLdrApiService() : waServiceBase<imgldr_api, ImgLdrApiService>(imgLdrApiServiceGuid) {}
+ static const char *getServiceName() { return "Image Loading API"; }
+ virtual imgldr_api *getService() { return imgLoaderApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#endif // WASABI_COMPILE_IMGLDR
+
+#ifdef WASABI_COMPILE_FONTS
+
+#include <api/font/api_font.h>
+
+class FontApiService : public waServiceBase<api_font, FontApiService> {
+public:
+ FontApiService() : waServiceBase<api_font, FontApiService>(fontApiServiceGuid) {}
+ static const char *getServiceName() { return "Font Rendering API"; }
+ virtual api_font *getService() { return fontApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#endif // WASABI_COMPILE_FONT
+
+
+#include <api/locales/api_locales.h>
+
+class LocalesApiService : public waServiceBase<api_locales, LocalesApiService> {
+public:
+ LocalesApiService() : waServiceBase<api_locales, LocalesApiService>(localesApiServiceGuid) {}
+ static const char *getServiceName() { return "Locales API"; }
+ virtual api_locales *getService() { return localesApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+
+
+#include <api/wnd/api_wnd.h>
+
+class WndApiService : public waServiceBase<wnd_api, WndApiService> {
+public:
+ WndApiService() : waServiceBase<wnd_api, WndApiService>(wndApiServiceGuid) {}
+ static const char *getServiceName() { return "Windowing API"; }
+ virtual wnd_api *getService() { return wndApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+
+#include <api/wndmgr/api_wndmgr.h>
+
+class WndMgrApiService : public waServiceBase<wndmgr_api, WndMgrApiService> {
+public:
+ WndMgrApiService() : waServiceBase<wndmgr_api, WndMgrApiService>(wndMgrApiServiceGuid) {}
+ static const char *getServiceName() { return "Window Manager API"; }
+ virtual wndmgr_api *getService() { return wndManagerApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#include <api/skin/api_skin.h>
+
+class SkinApiService : public waServiceBase<api_skin, SkinApiService> {
+public:
+ SkinApiService() : waServiceBase<api_skin, SkinApiService>(skinApiServiceGuid) {}
+ static const char *getServiceName() { return "Skinning API"; }
+ virtual api_skin *getService() { return skinApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#include <api/script/api_maki.h>
+
+class MakiApiService : public waServiceBase<api_maki, MakiApiService> {
+public:
+ MakiApiService() : waServiceBase<api_maki, MakiApiService>(makiApiServiceGuid) {}
+ static const char *getServiceName() { return "MAKI Scripting API"; }
+ virtual api_maki *getService() { return makiApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+
+#include <api/script/debugger/api_makidebug.h>
+
+class MakiDebugApiService : public waServiceBase<api_makiDebugger, MakiDebugApiService> {
+public:
+ MakiDebugApiService() : waServiceBase<api_makiDebugger, MakiDebugApiService>(makiDebugApiServiceGuid) {}
+ static const char *getServiceName() { return "MAKI Debugger API"; }
+ virtual api_makiDebugger *getService() { return debugApi; }
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+};
+
+#endif // WASABI_COMPILE_SKIN
+
+class ApiInit
+{
+public:
+ static int init(OSMODULEHANDLE hinstance, OSWINDOWHANDLE mainwnd, api_service *wa5_svc); // 0 == error, 1 == success
+ static int shutdown(); // 0 == error, 1 == success
+ static int getInitCount(); // if you do init / shutdown more than once in the session, this may be useful to invalid some caches
+
+private:
+ #ifdef WASABI_COMPILE_SKIN
+ #ifdef WASABI_COMPILE_COMPONENTS
+ static waServiceFactoryI * groupcreate;
+ #endif //WASABI_COMPILE_COMPONENTS
+ #endif //WASABI_COMPILE_SKIN
+
+ static waServiceFactoryI * win32Font;
+ static FontApiService *fontapisvc;
+
+public:
+ static Widgets * widgets;
+private:
+ static SkinApiService *skinapisvc;
+
+ static api_configI * cfg;
+ static ConfigApiService *cfgapisvc;
+ static ImgLdrApi * img;
+ static ImgLdrApiService *imgldrapisvc;
+
+ #ifdef WASABI_COMPILE_FONTS
+ static FontApi * font;
+ #endif
+
+ #ifdef WASABI_COMPILE_FILEREADER
+ static FileReaderApi * fr;
+ #ifdef WASABI_COMPILE_ZIPREADER
+ static waServiceFactoryI * zipRead;
+ #endif
+ static FileReaderApiService *frapisvc;
+ #endif
+
+ static api_localesI *loc;
+ static LocalesApiService *localesapisvc;
+
+ static WndApi * wnd;
+ static ForeignWnd * mainWnd;
+ static ClickWnd * default_mainWnd;
+ static WndApiService *wndapisvc;
+
+ static WndMgrApi * wndmgr;
+ static WndMgrApiService *wndmgrapisvc;
+
+
+ static api_makiI * maki;
+ static MakiApiService *makiapisvc;
+
+ static SkinApi * skin;
+
+ #ifdef WASABI_COMPILE_MAKIDEBUG
+ static MakiDebuggerApi * debug;
+ static MakiDebugApiService *makidebugapisvc;
+ #endif
+
+ #ifdef WASABI_COMPILE_MEDIACORE
+ static CoreApiService *coreapisvc;
+ #endif
+
+ static int initcount;
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/application/api_application.cpp b/Src/Wasabi/api/application/api_application.cpp
new file mode 100644
index 00000000..32cf2e8b
--- /dev/null
+++ b/Src/Wasabi/api/application/api_application.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:55:56 2003]
+//
+// File : api_application.cpp
+// Class : api_application
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_application.h"
+
+
diff --git a/Src/Wasabi/api/application/api_application.h b/Src/Wasabi/api/application/api_application.h
new file mode 100644
index 00000000..d04ec0b8
--- /dev/null
+++ b/Src/Wasabi/api/application/api_application.h
@@ -0,0 +1,416 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:55:56 2003]
+//
+// File : api_application.h
+// Class : api_application
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_APPLICATION_H
+#define __API_APPLICATION_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/guid.h>
+#include <bfc/platform/platform.h>
+#ifdef _WIN32
+#include "ifc_messageprocessor.h"
+#endif
+
+// ----------------------------------------------------------------------------
+
+enum
+{
+ API_APPLICATION_SUCCESS = 0,
+ API_APPLICATION_FAILURE = 1,
+};
+
+enum
+{
+ TRANSLATE_MODE_NORMAL = 0,
+ TRANSLATE_MODE_GLOBAL = 1,
+ TRANSLATE_MODE_CHILD = 2,
+};
+
+class NOVTABLE api_application: public Dispatchable
+{
+protected:
+ api_application() {}
+ ~api_application() {}
+
+public:
+ const wchar_t *main_getAppName(); // returns (e.g.) "Winamp"
+ const wchar_t *main_getVersionString(); // returns (e.g.) "Winamp 5.12"
+ const wchar_t *main_getVersionNumString(); // returns (e.g.) "5.12"
+ unsigned int main_getBuildNumber(); // returns (e.g.) 666
+ GUID main_getGUID();
+
+#ifdef _WIN32
+ HANDLE main_getMainThreadHandle(); // This actually gives you a DuplicateHandle, so call CloseHandle() when you are done.
+ HINSTANCE main_gethInstance();
+#endif // !_WIN32
+
+ const wchar_t *main_getCommandLine();
+ void main_shutdown( int deferred = TRUE );
+ void main_cancelShutdown();
+ int main_isShuttingDown();
+ const wchar_t *path_getAppPath();
+ const wchar_t *path_getUserSettingsPath();
+
+ // added for 5.58+ so gen_ff can fill @SKINSPATH@ in scripts correctly
+ const wchar_t *path_getSkinSettingsPath();
+ int app_getInitCount();
+ intptr_t app_messageLoopStep();
+
+#ifdef _WIN32
+ void app_addMessageProcessor( ifc_messageprocessor *processor );
+ void app_removeMessageProcessor( ifc_messageprocessor *processor );
+
+ /* accelerators are 5.53+ */
+ void app_addAccelerators( HWND hwnd, HACCEL *phAccel, INT cAccel, UINT translateMode );
+ void app_removeAccelerators( HWND hwnd );
+ bool app_translateAccelerators( MSG *msg );
+ int app_getAccelerators( HWND hwnd, HACCEL *phAccel, INT cchAccelMax, BOOL bGlobal ); // phAccel == NULL && cchAccelMax == 0 -> returns accels count
+
+ /* register window as part of winamp global group (5.54+) */
+ void app_registerGlobalWindow( HWND hwnd );
+ void app_unregisterGlobalWindow( HWND hwnd );
+
+ /* 5.58 + */
+ bool DirectMouseWheel_RegisterSkipClass( ATOM klass );
+ bool DirectMouseWheel_UnregisterSkipClass( ATOM klass );
+ bool DirectMouseWheel_EnableConvertToMouseWheel( HWND hwnd, BOOL enable ); // !!! must be disabled before window destroyed !!!
+
+ /* 5.64 + */
+ BOOL DirectMouseWheel_ProcessDialogMessage( HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam, const int controls[], int controlslen );
+
+ /* 5.61 + */
+ void ActiveDialog_Register( HWND hwnd );
+ void ActiveDialog_Unregister( HWND hwnd );
+ HWND ActiveDialog_Get();
+
+ /* 5.64 + */
+ const wchar_t *getATFString(); // returns the current ATF formatting string
+
+ /* 5.66 + */
+ // used for dpi scaling so we're consistent in usage throughout the UI, etc
+ int getScaleX( int x );
+ int getScaleY( int y );
+
+#endif // !_WIN32
+
+ /*
+ note: on windows, these two functions DON'T call Set/GetCurrentDirectory, Winamp maintains it's own path
+ because calling SetCurrentDirectory locks the folder
+ Added for 5.34
+ */
+ const wchar_t *path_getWorkingPath(); // useful to call for populating lpstrInitialDir in GetOpenFileName
+ void path_setWorkingPath(const wchar_t *newPath); // useful to call for populating lpstrInitialDir in GetOpenFileName
+
+ /*
+ The following three function return you unique IDs you can use if you need
+ They are created anonymously, so information cannot be tracked back to a specific person
+ The main reason for their existence is that a few third party libraries require them
+ and some online media providers require this info for billing.
+ You can call this functions with a pointer to any 16 byte data structure cast to a GUID *
+ Added for 5.35
+ */
+ // returns an ID unique to this computer, but not unique to the logged in user (two windows accts would share this ID)
+ int GetMachineID( GUID *id );
+ // returns an ID unique to this user. Another user logged in to the computer will have a different ID
+ // note that if Winamp was installed with "shared settings", the IDs of multiple users will probably be identical
+ // as we're just storing it in winamp.ini for now
+ int GetUserID( GUID *id );
+ // returns a unique ID for this session. Generated on the fly the first time someone calls this function
+ int GetSessionID( GUID *id );
+
+ /* 5.54 + */
+ size_t AllocateThreadStorage(); // returns an index, -1 for error
+ void *GetThreadStorage(size_t index);
+ void SetThreadStorage(size_t index, void *value);
+
+protected:
+ enum
+ {
+ API_APPLICATION_MAIN_GETAPPNAME = 10,
+ API_APPLICATION_MAIN_GETVERSIONSTRING = 20,
+ API_APPLICATION_MAIN_GETVERSIONSTRING2 = 21,
+ API_APPLICATION_MAIN_GETBUILDNUMBER = 30,
+ API_APPLICATION_MAIN_GETGUID = 40,
+ API_APPLICATION_MAIN_GETMAINTHREADHANDLE = 50,
+ API_APPLICATION_MAIN_GETHINSTANCE = 60,
+ API_APPLICATION_MAIN_GETCOMMANDLINE = 70,
+ API_APPLICATION_MAIN_SHUTDOWN = 80,
+ API_APPLICATION_MAIN_CANCELSHUTDOWN = 90,
+ API_APPLICATION_MAIN_ISSHUTTINGDOWN = 100,
+ API_APPLICATION_PATH_GETAPPPATH = 110,
+ API_APPLICATION_PATH_GETUSERSETTINGSPATH = 120,
+ API_APPLICATION_APP_GETINITCOUNT = 130,
+ API_APPLICATION_APP_MESSAGELOOPSTEP = 140,
+ API_APPLICATION_APP_ADDMESSAGEPROCESSOR = 150,
+ API_APPLICATION_APP_REMOVEMESSAGEPROCESSOR = 160,
+ API_APPLICATION_APP_ADDMODELESSDIALOG = 170,
+ API_APPLICATION_APP_REMOVEMODELESSDIALOG = 180,
+ API_APPLICATION_PATH_GETWORKINGPATH = 190,
+ API_APPLICATION_PATH_SETWORKINGPATH = 200,
+ API_APPLICATION_GETMACHINEID = 210,
+ API_APPLICATION_GETUSERID = 220,
+ API_APPLICATION_GETSESSIONID = 230,
+ API_APPLICATION_APP_ADDACCELERATORS = 240,
+ API_APPLICATION_APP_REMOVEACCELERATORS = 250,
+ API_APPLICATION_APP_TRANSLATEACCELERATORS = 260,
+ API_APPLICATION_APP_GETACCELERATORS = 270,
+ API_APPLICATION_APP_REGISTERGLOBALWINDOW = 280,
+ API_APPLICATION_APP_UNREGISTERGLOBALWINDOW = 290,
+ API_APPLICATION_ALLOCATETHREADSTORAGE = 300,
+ API_APPLICATION_GETTHREADSTORAGE = 310,
+ API_APPLICATION_SETTHREADSTORAGE = 320,
+ API_APPLICATION_PATH_GETSKINSETTINGSPATH = 330,
+ API_APPLICATION_DIRECTMOUSEWHEEL_REGISTERSKIPCLASS = 340,
+ API_APPLICATION_DIRECTMOUSEWHEEL_UNREGISTERSKIPCLASS = 350,
+ API_APPLICATION_DIRECTMOUSEWHEEL_ENABLECONVERTTOMOUSEWHEEL = 360,
+ API_APPLICATION_DIRECTMOUSEWHEEL_PROCESSDIALOGMESSAGE = 365,
+ API_APPLICATION_ACTIVEDIALOG_REGISTER = 370,
+ API_APPLICATION_ACTIVEDIALOG_UNREGISTER = 380,
+ API_APPLICATION_ACTIVEDIALOG_GET = 390,
+ API_APPLICATION_GETATFSTRING = 400,
+ API_APPLICATION_GETSCALEX = 500,
+ API_APPLICATION_GETSCALEY = 510,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline const wchar_t *api_application::main_getAppName()
+{
+ const wchar_t *__retval = _call(API_APPLICATION_MAIN_GETAPPNAME, (const wchar_t *)0);
+ return __retval;
+}
+
+inline const wchar_t *api_application::main_getVersionString()
+{
+ const wchar_t *__retval = _call(API_APPLICATION_MAIN_GETVERSIONSTRING, (const wchar_t *)0);
+ return __retval;
+}
+
+inline const wchar_t *api_application::main_getVersionNumString()
+{
+ return _call(API_APPLICATION_MAIN_GETVERSIONSTRING2, (const wchar_t *)0);
+}
+
+inline unsigned int api_application::main_getBuildNumber()
+{
+ return _call(API_APPLICATION_MAIN_GETBUILDNUMBER, 0);
+}
+
+inline GUID api_application::main_getGUID()
+{
+ GUID __retval = _call(API_APPLICATION_MAIN_GETGUID, INVALID_GUID);
+ return __retval;
+}
+
+#ifdef _WIN32
+inline HANDLE api_application::main_getMainThreadHandle()
+{
+ HANDLE __retval = _call(API_APPLICATION_MAIN_GETMAINTHREADHANDLE, (HANDLE)NULL);
+ return __retval;
+}
+
+inline HINSTANCE api_application::main_gethInstance()
+{
+ HINSTANCE __retval = _call(API_APPLICATION_MAIN_GETHINSTANCE, (HINSTANCE)NULL);
+ return __retval;
+}
+#endif
+
+inline const wchar_t *api_application::main_getCommandLine()
+{
+ const wchar_t *__retval = _call(API_APPLICATION_MAIN_GETCOMMANDLINE, (const wchar_t *)0);
+ return __retval;
+}
+
+inline void api_application::main_shutdown(int deferred)
+{
+ _voidcall(API_APPLICATION_MAIN_SHUTDOWN, deferred);
+}
+
+inline void api_application::main_cancelShutdown()
+{
+ _voidcall(API_APPLICATION_MAIN_CANCELSHUTDOWN);
+}
+
+inline int api_application::main_isShuttingDown()
+{
+ int __retval = _call(API_APPLICATION_MAIN_ISSHUTTINGDOWN, (int)0);
+ return __retval;
+}
+
+inline const wchar_t *api_application::path_getAppPath()
+{
+ const wchar_t *__retval = _call(API_APPLICATION_PATH_GETAPPPATH, (const wchar_t *)0);
+ return __retval;
+}
+
+inline const wchar_t *api_application::path_getUserSettingsPath()
+{
+ return _call(API_APPLICATION_PATH_GETUSERSETTINGSPATH, (const wchar_t *)0);
+}
+
+inline const wchar_t *api_application::path_getSkinSettingsPath()
+{
+ return _call(API_APPLICATION_PATH_GETSKINSETTINGSPATH, (const wchar_t *)0);
+}
+
+inline int api_application::app_getInitCount()
+{
+ int __retval = _call(API_APPLICATION_APP_GETINITCOUNT, 0);
+ return __retval;
+}
+
+inline intptr_t api_application::app_messageLoopStep()
+{
+ return _call(API_APPLICATION_APP_MESSAGELOOPSTEP, (intptr_t)1);
+}
+
+#ifdef _WIN32
+inline void api_application::app_addMessageProcessor(ifc_messageprocessor *processor)
+{
+ _voidcall(API_APPLICATION_APP_ADDMESSAGEPROCESSOR, processor);
+}
+
+inline void api_application::app_removeMessageProcessor(ifc_messageprocessor *processor)
+{
+ _voidcall(API_APPLICATION_APP_REMOVEMESSAGEPROCESSOR, processor);
+}
+
+inline void api_application::app_addAccelerators(HWND hwnd, HACCEL *phAccel, INT cAccel, UINT translateMode)
+{
+ _voidcall(API_APPLICATION_APP_ADDACCELERATORS, hwnd, phAccel, cAccel, translateMode);
+}
+
+inline void api_application::app_removeAccelerators(HWND hwnd)
+{
+ _voidcall(API_APPLICATION_APP_REMOVEACCELERATORS, hwnd);
+}
+
+inline bool api_application::app_translateAccelerators(MSG *msg)
+{
+ return _call(API_APPLICATION_APP_TRANSLATEACCELERATORS, (bool)false, msg);
+}
+
+inline int api_application::app_getAccelerators(HWND hwnd, HACCEL *phAccel, INT cchAccelMax, BOOL bGlobal)
+{
+ return _call(API_APPLICATION_APP_GETACCELERATORS, (int)0, hwnd, phAccel, cchAccelMax, bGlobal);
+}
+
+inline void api_application::app_registerGlobalWindow(HWND hwnd)
+{
+ _voidcall(API_APPLICATION_APP_REGISTERGLOBALWINDOW, hwnd);
+}
+
+inline void api_application::app_unregisterGlobalWindow(HWND hwnd)
+{
+ _voidcall(API_APPLICATION_APP_UNREGISTERGLOBALWINDOW, hwnd);
+}
+
+inline bool api_application::DirectMouseWheel_RegisterSkipClass(ATOM klass)
+{
+ return _call(API_APPLICATION_DIRECTMOUSEWHEEL_REGISTERSKIPCLASS, (bool)false, klass);
+}
+
+inline bool api_application::DirectMouseWheel_UnregisterSkipClass(ATOM klass)
+{
+ return _call(API_APPLICATION_DIRECTMOUSEWHEEL_UNREGISTERSKIPCLASS, (bool)false, klass);
+}
+
+inline bool api_application::DirectMouseWheel_EnableConvertToMouseWheel(HWND hwnd, BOOL enable)
+{
+ return _call(API_APPLICATION_DIRECTMOUSEWHEEL_ENABLECONVERTTOMOUSEWHEEL, (bool)false, hwnd, enable);
+}
+
+inline BOOL api_application::DirectMouseWheel_ProcessDialogMessage(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam, const int controls[], int controlslen)
+{
+ return _call(API_APPLICATION_DIRECTMOUSEWHEEL_PROCESSDIALOGMESSAGE, (BOOL)FALSE, hwnd, uMsg, wParam, lParam, controls, controlslen);
+}
+
+inline void api_application::ActiveDialog_Register(HWND hwnd)
+{
+ _voidcall(API_APPLICATION_ACTIVEDIALOG_REGISTER, hwnd);
+}
+
+inline void api_application::ActiveDialog_Unregister(HWND hwnd)
+{
+ _voidcall(API_APPLICATION_ACTIVEDIALOG_UNREGISTER, hwnd);
+}
+
+inline HWND api_application::ActiveDialog_Get()
+{
+ return _call(API_APPLICATION_ACTIVEDIALOG_GET, (HWND)NULL);
+}
+
+inline const wchar_t *api_application::getATFString()
+{
+ return _call(API_APPLICATION_GETATFSTRING, (wchar_t *)0);
+}
+
+inline int api_application::getScaleX(int x)
+{
+ return _call(API_APPLICATION_GETSCALEX, (int)0, x);
+}
+
+inline int api_application::getScaleY(int y)
+{
+ return _call(API_APPLICATION_GETSCALEY, (int)0, y);
+}
+#endif
+
+inline const wchar_t *api_application::path_getWorkingPath()
+{
+ return _call(API_APPLICATION_PATH_GETWORKINGPATH, (wchar_t *)0);
+}
+
+inline void api_application::path_setWorkingPath(const wchar_t *newPath)
+{
+ _voidcall(API_APPLICATION_PATH_SETWORKINGPATH, newPath);
+}
+
+inline int api_application::GetMachineID(GUID *id)
+{
+ return _call(API_APPLICATION_GETMACHINEID, (int)API_APPLICATION_FAILURE, id);
+}
+
+inline int api_application::GetUserID(GUID *id)
+{
+ return _call(API_APPLICATION_GETUSERID, (int)API_APPLICATION_FAILURE, id);
+}
+
+inline int api_application::GetSessionID(GUID *id)
+{
+ return _call(API_APPLICATION_GETSESSIONID, (int)API_APPLICATION_FAILURE, id);
+}
+
+inline size_t api_application::AllocateThreadStorage()
+{
+ return _call(API_APPLICATION_ALLOCATETHREADSTORAGE, (size_t)-1);
+}
+
+inline void *api_application::GetThreadStorage(size_t index)
+{
+ return _call(API_APPLICATION_GETTHREADSTORAGE, (void *)0, index);
+}
+
+inline void api_application::SetThreadStorage(size_t index, void *value)
+{
+ _voidcall(API_APPLICATION_SETTHREADSTORAGE, index, value);
+}
+
+// ----------------------------------------------------------------------------
+
+// {23B96771-09D7-46d3-9AE2-20DCEA6C86EA}
+static const GUID applicationApiServiceGuid =
+ {
+ 0x23b96771, 0x9d7, 0x46d3, { 0x9a, 0xe2, 0x20, 0xdc, 0xea, 0x6c, 0x86, 0xea }
+ };
+
+extern api_application *applicationApi;
+
+#endif // __API_APPLICATION_H \ No newline at end of file
diff --git a/Src/Wasabi/api/application/api_applicationi.cpp b/Src/Wasabi/api/application/api_applicationi.cpp
new file mode 100644
index 00000000..694bc865
--- /dev/null
+++ b/Src/Wasabi/api/application/api_applicationi.cpp
@@ -0,0 +1,204 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "api_applicationi.h"
+//?>
+
+#include <wasabicfg.h>
+#include <api/application/pathmgr.h>
+#include <api/application/version.h>
+#include <api/apiinit.h>
+
+#ifdef WA3COMPATIBILITY
+#include <runtime/main.h> // CUT!
+#include <wndmgr/layout.h> // CUT!
+#include <skin/skinparse.h>
+#endif
+
+StringW g_resourcepath;
+
+// {3CBD4483-DC44-11d3-B608-000086340885}
+static const GUID _baseGUID =
+ { 0x3cbd4483, 0xdc44, 0x11d3, { 0xb6, 0x8, 0x0, 0x0, 0x86, 0x34, 0x8, 0x85 } };
+
+api_application *applicationApi = NULL;
+api_applicationI::api_applicationI(HINSTANCE instance, const wchar_t *_userPath)
+: appInstance(instance), mainthread(0), shuttingdown(0)
+{
+ userPath = _userPath;
+#ifndef _WASABIRUNTIME
+
+#ifdef WASABI_DIRS_FROMEXEPATH
+ HINSTANCE hInst = GetModuleHandle(0);
+#else
+ HINSTANCE hInst = appInstance;
+#endif
+
+ StringW path;
+ {
+ wchar_t g[WA_MAX_PATH];
+ GetModuleFileNameW(hInst, g, WA_MAX_PATH - 1);
+ wchar_t *p = wcsrchr(g, '\\');
+ if (p) *p = 0;
+ path = g;
+ }
+#ifdef WIN32
+ g_resourcepath = path;
+#elif defined(LINUX)
+ g_resourcepath = "/usr/local/share/";
+ g_resourcepath += WasabiVersion::getAppName();
+#endif
+
+#ifdef LINUX
+ //char *file = getenv( "WASABI_LOG_FILE" );
+ //if (!ACCESS(file, 0)) UNLINK(file);
+#endif
+
+ apppath = path;
+
+ g_resourcepath.AddBackslash();
+
+#if defined(WASABI_COMPILE_SKIN) || defined(WASABI_COMPILE_IMGLDR)
+ g_resourcepath.AppendPath(WASABI_RESOURCES_SUBDIRECTORY);
+#endif
+
+#endif
+
+#ifdef WIN32
+ HANDLE h = NULL;
+ DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ mainthread = h; // 32-bit writes assumed atomic
+#endif
+#ifdef LINUX
+ DebugString("portme: api main thread handle dup\n");
+#endif
+}
+
+api_applicationI::~api_applicationI()
+{
+ g_resourcepath.purge();
+}
+
+const wchar_t *api_applicationI::main_getAppName()
+{
+ return WasabiVersion::getAppName();
+}
+
+const wchar_t *api_applicationI::main_getVersionString()
+{
+ return WasabiVersion::getVersionString();
+}
+
+unsigned int api_applicationI::main_getBuildNumber()
+{
+ return WasabiVersion::getBuildNumber();
+}
+
+GUID api_applicationI::main_getGUID()
+{
+ return guid;
+}
+
+HANDLE api_applicationI::main_getMainThreadHandle()
+{
+ if (mainthread == 0) return (HANDLE)0;
+ HANDLE h = (HANDLE)0;
+#ifdef WIN32
+ DuplicateHandle(GetCurrentProcess(), mainthread, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS);
+#endif
+#ifdef LINUX
+ DebugString("portme: dup handle\n");
+#endif
+ return h;
+}
+
+HINSTANCE api_applicationI::main_gethInstance()
+{
+ return appInstance;
+}
+
+const wchar_t *api_applicationI::main_getCommandLine()
+{
+ return cmdLine;
+}
+
+void api_applicationI::main_shutdown(int deferred)
+{
+ int x = 1;
+#ifdef WASABI_CHECK_CAN_EXIT
+ WASABI_CHECK_CAN_EXIT(x)
+#endif
+ if (!x) return ;
+ shuttingdown = 1;
+#ifdef _WASABIRUNTIME
+ Main::doAction(ACTION_CLOSE, deferred);
+#endif
+#ifdef WASABI_CUSTOM_QUIT
+ WASABI_CUSTOM_QUITFN
+#endif
+
+}
+
+void api_applicationI::main_cancelShutdown()
+{
+#ifdef _WASABIRUNTIME
+ Main::cancelShutdown();
+#endif
+ shuttingdown = 0;
+}
+
+int api_applicationI::main_isShuttingDown()
+{
+ return shuttingdown;
+}
+
+const wchar_t *api_applicationI::path_getAppPath()
+{
+#ifdef _WASABIRUNTIME
+ return Main::getMainAppPath();
+#endif
+ return apppath;
+}
+
+const wchar_t *api_applicationI::path_getUserSettingsPath()
+{
+ return userPath;
+ //return PathMgr::getUserSettingsPath();
+}
+
+void api_applicationI::setHInstance(HINSTANCE instance)
+{
+ appInstance = instance;
+};
+
+void api_applicationI::setCommandLine(const wchar_t *cmdline)
+{
+ cmdLine = cmdline;
+}
+
+void api_applicationI::setGUID(GUID g)
+{
+ guid = g;
+}
+
+int api_applicationI::app_getInitCount()
+{
+ return ApiInit::getInitCount();
+}
+
+
+int api_applicationI::app_messageLoopStep()
+{
+#if defined(WASABI_COMPILE_TIMERS) || defined(WASABI_COMPILE_WND)
+ MSG msg;
+ if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
+ {
+ if (!GetMessage( &msg, NULL, 0, 0 )) return 0;
+#ifdef WASABI_COMPILE_WND
+ TranslateMessage( &msg );
+#endif
+ DispatchMessage( &msg );
+ }
+#endif
+ return 1;
+}
+
diff --git a/Src/Wasabi/api/application/api_applicationi.h b/Src/Wasabi/api/application/api_applicationi.h
new file mode 100644
index 00000000..5018250a
--- /dev/null
+++ b/Src/Wasabi/api/application/api_applicationi.h
@@ -0,0 +1,49 @@
+#ifndef __API_APPLICATIONI_IMPL_H
+#define __API_APPLICATIONI_IMPL_H
+
+/*<?<autoheader/>*/
+#include "api_application.h"
+#include "api_applicationx.h"
+/*?>*/
+
+/*[interface.header.h]
+#include "common/nsGUID.h"
+class String;
+*/
+
+class api_applicationI : public api_applicationX {
+public:
+ NODISPATCH api_applicationI(HINSTANCE instance, const wchar_t *_userPath);
+ NODISPATCH virtual ~api_applicationI();
+
+ DISPATCH(10) const wchar_t *main_getAppName();
+ DISPATCH(20) const wchar_t *main_getVersionString();
+ DISPATCH(30) unsigned int main_getBuildNumber();
+ DISPATCH(40) GUID main_getGUID();
+ DISPATCH(50) HANDLE main_getMainThreadHandle();
+ DISPATCH(60) HINSTANCE main_gethInstance();
+ DISPATCH(70) const wchar_t *main_getCommandLine();
+ DISPATCH(80) void main_shutdown(int deferred = TRUE);
+ DISPATCH(90) void main_cancelShutdown();
+ DISPATCH(100) int main_isShuttingDown();
+ DISPATCH(110) const wchar_t *path_getAppPath();
+ DISPATCH(120) const wchar_t *path_getUserSettingsPath();
+ DISPATCH(130) int app_getInitCount();
+ DISPATCH(140) int app_messageLoopStep();
+
+ NODISPATCH void setHInstance(HINSTANCE instance);
+ NODISPATCH void setCommandLine(const wchar_t *cmdline);
+ NODISPATCH void setGUID(GUID g);
+
+protected:
+
+ HINSTANCE appInstance;
+ StringW cmdLine;
+ StringW userPath;
+ HANDLE mainthread;
+ GUID guid;
+ int shuttingdown;
+ StringW apppath;
+};
+
+#endif // __API_APPLICATIONI_IMPL_H
diff --git a/Src/Wasabi/api/application/api_applicationx.cpp b/Src/Wasabi/api/application/api_applicationx.cpp
new file mode 100644
index 00000000..3c689467
--- /dev/null
+++ b/Src/Wasabi/api/application/api_applicationx.cpp
@@ -0,0 +1,33 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:55:56 2003]
+//
+// File : api_applicationx.cpp
+// Class : api_application
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "api_applicationx.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_applicationX
+START_DISPATCH;
+ CB(API_APPLICATION_MAIN_GETAPPNAME, main_getAppName);
+ CB(API_APPLICATION_MAIN_GETVERSIONSTRING, main_getVersionString);
+ CB(API_APPLICATION_MAIN_GETBUILDNUMBER, main_getBuildNumber);
+ CB(API_APPLICATION_MAIN_GETGUID, main_getGUID);
+ CB(API_APPLICATION_MAIN_GETMAINTHREADHANDLE, main_getMainThreadHandle);
+ CB(API_APPLICATION_MAIN_GETHINSTANCE, main_gethInstance);
+ CB(API_APPLICATION_MAIN_GETCOMMANDLINE, main_getCommandLine);
+ VCB(API_APPLICATION_MAIN_SHUTDOWN, main_shutdown);
+ VCB(API_APPLICATION_MAIN_CANCELSHUTDOWN, main_cancelShutdown);
+ CB(API_APPLICATION_MAIN_ISSHUTTINGDOWN, main_isShuttingDown);
+ CB(API_APPLICATION_PATH_GETAPPPATH, path_getAppPath);
+ CB(API_APPLICATION_PATH_GETUSERSETTINGSPATH, path_getUserSettingsPath);
+ CB(API_APPLICATION_APP_GETINITCOUNT, app_getInitCount);
+ CB(API_APPLICATION_APP_MESSAGELOOPSTEP, app_messageLoopStep);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/application/api_applicationx.h b/Src/Wasabi/api/application/api_applicationx.h
new file mode 100644
index 00000000..a95809ca
--- /dev/null
+++ b/Src/Wasabi/api/application/api_applicationx.h
@@ -0,0 +1,42 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:55:56 2003]
+//
+// File : api_applicationx.h
+// Class : api_application
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_APPLICATIONX_H
+#define __API_APPLICATIONX_H
+
+#include "api_application.h"
+
+
+
+
+// ----------------------------------------------------------------------------
+
+class api_applicationX : public api_application {
+ protected:
+ api_applicationX() {}
+ public:
+ virtual const wchar_t *main_getAppName()=0;
+ virtual const wchar_t *main_getVersionString()=0;
+ virtual unsigned int main_getBuildNumber()=0;
+ virtual GUID main_getGUID()=0;
+ virtual HANDLE main_getMainThreadHandle()=0;
+ virtual HINSTANCE main_gethInstance()=0;
+ virtual const wchar_t *main_getCommandLine()=0;
+ virtual void main_shutdown(int deferred = TRUE)=0;
+ virtual void main_cancelShutdown()=0;
+ virtual int main_isShuttingDown()=0;
+ virtual const wchar_t *path_getAppPath()=0;
+ virtual const wchar_t *path_getUserSettingsPath()=0;
+ virtual int app_getInitCount()=0;
+ virtual int app_messageLoopStep()=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_APPLICATIONX_H
diff --git a/Src/Wasabi/api/application/ifc_messageprocessor.cpp b/Src/Wasabi/api/application/ifc_messageprocessor.cpp
new file mode 100644
index 00000000..953b85c0
--- /dev/null
+++ b/Src/Wasabi/api/application/ifc_messageprocessor.cpp
@@ -0,0 +1 @@
+#include "api_messageprocessor.h" \ No newline at end of file
diff --git a/Src/Wasabi/api/application/ifc_messageprocessor.h b/Src/Wasabi/api/application/ifc_messageprocessor.h
new file mode 100644
index 00000000..0d61bdc1
--- /dev/null
+++ b/Src/Wasabi/api/application/ifc_messageprocessor.h
@@ -0,0 +1,26 @@
+#ifndef __WASABI_IFC_MESSAGEPROCESSOR_H
+#define __WASABI_IFC_MESSAGEPROCESSOR_H
+
+#include <bfc/dispatch.h>
+#include <windows.h>
+class ifc_messageprocessor : public Dispatchable
+{
+protected:
+ ifc_messageprocessor() {}
+ ~ifc_messageprocessor() {}
+
+public:
+ bool ProcessMessage(MSG *msg); // return true to 'eat' the message
+public:
+ DISPATCH_CODES
+ {
+ IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE = 10,
+ };
+};
+inline bool ifc_messageprocessor::ProcessMessage(MSG *msg)
+{
+ return _call(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, false, msg);
+}
+
+typedef ifc_messageprocessor api_messageprocessor; // TODO: CUT!
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/application/ifc_messageprocessori.cpp b/Src/Wasabi/api/application/ifc_messageprocessori.cpp
new file mode 100644
index 00000000..38bb15e3
--- /dev/null
+++ b/Src/Wasabi/api/application/ifc_messageprocessori.cpp
@@ -0,0 +1,7 @@
+#include "ifc_messageprocessori.h"
+
+#define CBCLASS ifc_messageprocessorI
+START_DISPATCH;
+CB(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/application/ifc_messageprocessori.h b/Src/Wasabi/api/application/ifc_messageprocessori.h
new file mode 100644
index 00000000..7cb10e55
--- /dev/null
+++ b/Src/Wasabi/api/application/ifc_messageprocessori.h
@@ -0,0 +1,13 @@
+#ifndef NULLSOFT_WASABI_MESSAGEPROCESSORI_H
+#define NULLSOFT_WASABI_MESSAGEPROCESSORI_H
+
+#include <api/application/ifc_messageprocessor.h>
+
+class ifc_messageprocessorI: public ifc_messageprocessor
+{
+public:
+ virtual bool ProcessMessage(MSG *msg)=0;
+protected:
+ RECVS_DISPATCH;
+};
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/application/ipcs.cpp b/Src/Wasabi/api/application/ipcs.cpp
new file mode 100644
index 00000000..2320a4d8
--- /dev/null
+++ b/Src/Wasabi/api/application/ipcs.cpp
@@ -0,0 +1,97 @@
+#include <precomp.h>
+#ifdef WASABI_API_COMPONENT
+#include <api/wac/main.h> //CUT!!!
+#endif
+#include "ipcs.h"
+#ifdef LINUX
+#include <api/linux/linuxapi.h>
+#endif
+
+using namespace IpcsCommand;
+
+#ifdef WIN32
+IpcsPtr::IpcsPtr(HWND h) {
+ hwnd = h;
+}
+#else
+IpcsPtr::IpcsPtr(int q) {
+ qid = q;
+}
+#endif
+
+void IpcsPtr::moveToForeground() {
+#ifdef WIN32
+ if (IsIconic(hwnd)) ShowWindow(hwnd, SW_RESTORE);
+// ShowWindow(hwnd,SW_SHOW); //FG> SW_RESTORE should take care of it and is trapped for taskbar button hiding. Explicitly showing the window will make an iconless button reapear if studio is set to not have a taskbar button
+ SetForegroundWindow(hwnd);
+#else
+ DebugString( "portme -- IpcsPtr::moveToForeground\n" );
+#endif
+}
+
+void IpcsPtr::sendWasabiCommand(int command, void *param, int paramlen) {
+#ifdef WIN32
+ COPYDATASTRUCT cd;
+ cd.dwData=command;
+ cd.cbData=paramlen;
+ cd.lpData=param;
+ SendMessage(hwnd, WM_COPYDATA, NULL, (long)&cd);
+#else
+ wa_msgbuf msg;
+ msg.mtype = command;
+ ASSERT( paramlen < IPC_MSGMAX - 4 );
+ msg.paramlen = paramlen;
+ MEMCPY( msg.param, param, paramlen );
+
+ if ( msgsnd( qid , &msg, IPC_MSGMAX, 0 ) == 1 ) {
+ perror( "msgsnd" );
+ }
+#endif
+}
+
+void IpcsPtr::sendWasabiCommand(int command, const char *param) {
+ sendWasabiCommand(command, (void *)param, STRLEN(param)+1);
+}
+
+
+IpcsPtr *Ipcs::getOtherWasabiInstance() {
+ extern String ipcWindowClassName;
+
+#ifdef WIN32
+ HWND hwnd_instance=FindWindow(ipcWindowClassName,NULL);
+ if(!hwnd_instance) return NULL;
+
+ return(new IpcsPtr(hwnd_instance));
+#else
+ int key = ftok( ".", 'w' );
+
+ int qid = msgget( key, 0 );
+ if ( qid == -1 && errno == ENOENT ) {
+ qid = msgget( key, IPC_CREAT | IPC_EXCL | 0660 );
+
+ LinuxAPI::setIPCId( qid );
+
+ return NULL;
+ } else if ( qid == -1 ) {
+ return NULL;
+ } else {
+ return new IpcsPtr( qid );
+ }
+#endif
+}
+
+#pragma warning(push)
+#pragma warning(disable: 4060)
+
+int Ipcs::onIpcsMessage(int command, void *param, int paramlen) {
+ switch(command) {
+#ifdef WASABI_API_COMPONENT
+ case IPC_COMMANDLINE:
+ Main::processCommandLine((const char *)param);
+ return 0;
+#endif
+ }
+ return 0;
+}
+
+#pragma warning(pop)
diff --git a/Src/Wasabi/api/application/ipcs.h b/Src/Wasabi/api/application/ipcs.h
new file mode 100644
index 00000000..8ef50062
--- /dev/null
+++ b/Src/Wasabi/api/application/ipcs.h
@@ -0,0 +1,60 @@
+#ifndef _IPCS_H
+#define _IPCS_H
+
+// same value as winamp 2.x
+#define WM_WA_IPC WM_USER
+
+#ifdef LINUX
+// Stolen from a webpage, I think Linux's is higher, but to be safe...
+#define IPC_MSGMAX 4056
+
+struct wa_msgbuf {
+ long mtype;
+ int paramlen;
+ char param[IPC_MSGMAX - 4];
+};
+#endif
+
+namespace IpcsCommand {
+ enum {
+#ifdef WASABI_API_MEDIACORE
+ // wa2.x IPC messages
+ IPC_PLAYFILE=100,
+#endif
+
+#ifdef WASABI_API_COMPONENT
+ // wa3 IPC messages
+ IPC_COMMANDLINE=1000,
+#endif
+ };
+};
+
+class IpcsPtr {
+public:
+#ifdef WIN32
+ IpcsPtr(HWND hwnd);
+#else
+ IpcsPtr(int qid);
+#endif
+
+ void sendWasabiCommand(int command, void *param=0, int paramlen=0);
+ void sendWasabiCommand(int command, const char *param);
+
+ void moveToForeground();
+
+private:
+#ifdef WIN32
+ HWND hwnd;
+#else
+ int qid;
+#endif
+};
+
+class Ipcs {
+public:
+ static IpcsPtr *getOtherWasabiInstance();
+
+ static int onIpcsMessage(int command, void *param, int paramlen);
+};
+
+#endif
diff --git a/Src/Wasabi/api/application/pathmgr.cpp b/Src/Wasabi/api/application/pathmgr.cpp
new file mode 100644
index 00000000..ffdce62a
--- /dev/null
+++ b/Src/Wasabi/api/application/pathmgr.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+#include "pathmgr.h"
+#include <api/api.h>
+#include <bfc/util/inifile.h>
+
+#if !defined(WIN32) && !defined(LINUX)
+#error port me
+#endif
+
+#ifdef WIN32
+#include <shlobj.h>
+#endif
+
+
diff --git a/Src/Wasabi/api/application/pathmgr.h b/Src/Wasabi/api/application/pathmgr.h
new file mode 100644
index 00000000..7b0354e6
--- /dev/null
+++ b/Src/Wasabi/api/application/pathmgr.h
@@ -0,0 +1,15 @@
+#ifndef _PATHMGR_H
+#define _PATHMGR_H
+
+#include <bfc/std.h>
+
+class PathMgr
+{
+public:
+ //static const char *getUserSettingsPath();
+#ifdef WASABI_COMPILE_COMPONENTS
+ static const wchar_t *getComponentDataPath(GUID g);
+#endif
+};
+
+#endif
diff --git a/Src/Wasabi/api/application/version.cpp b/Src/Wasabi/api/application/version.cpp
new file mode 100644
index 00000000..b2ce69cc
--- /dev/null
+++ b/Src/Wasabi/api/application/version.cpp
@@ -0,0 +1,47 @@
+#include <precomp.h>
+#include "version.h"
+#include <bfc/parse/pathparse.h>
+
+static int buildno = -1;
+static const wchar_t *WASABI_VERSION = L"";
+
+#define STRFILEVER "1, 0, 0, 502\0"
+
+static StringW version_string;
+
+void WasabiVersion::setAppName(const wchar_t *name)
+{
+ appname = name;
+}
+
+const wchar_t *WasabiVersion::getAppName()
+{
+ return appname;
+}
+
+const wchar_t *WasabiVersion::getVersionString()
+{
+ if (appname.isempty())
+ appname=L"";
+ if (version_string.isempty())
+ {
+ if (!appname.isempty())
+ version_string = appname.getValue();
+ if (wcslen(WASABI_VERSION))
+ {
+ version_string.cat(L" ");
+ version_string.cat(WASABI_VERSION);
+ }
+ }
+ return version_string;
+}
+
+unsigned int WasabiVersion::getBuildNumber()
+{
+ if (buildno == -1)
+ {
+ PathParser pp(STRFILEVER, ",");
+ buildno = ATOI(pp.enumString(3));
+ }
+ return buildno;
+}
diff --git a/Src/Wasabi/api/application/version.h b/Src/Wasabi/api/application/version.h
new file mode 100644
index 00000000..bfb68994
--- /dev/null
+++ b/Src/Wasabi/api/application/version.h
@@ -0,0 +1,12 @@
+#ifndef _VERSION_H
+#define _VERSION_H
+/*
+class WasabiVersion {
+public:
+ static void setAppName(const wchar_t *name);
+ static const wchar_t *getAppName();
+ static const wchar_t *getVersionString();
+ static unsigned int getBuildNumber();
+};*/
+
+#endif
diff --git a/Src/Wasabi/api/application/wkc.cpp b/Src/Wasabi/api/application/wkc.cpp
new file mode 100644
index 00000000..05d9f00a
--- /dev/null
+++ b/Src/Wasabi/api/application/wkc.cpp
@@ -0,0 +1,12 @@
+#include <precomp.h>
+
+#include "wkc.h"
+
+#define CBCLASS WasabiKernelControllerI
+START_DISPATCH;
+ CB(TESTCOMPONENT, testComponent);
+ CB(TESTSCRIPT, testScript);
+ CB(TESTSKIN, testSkin);
+ CB(TESTSKINFILE, testSkinFile);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/application/wkc.h b/Src/Wasabi/api/application/wkc.h
new file mode 100644
index 00000000..4f7eee86
--- /dev/null
+++ b/Src/Wasabi/api/application/wkc.h
@@ -0,0 +1,61 @@
+#ifndef _WKC_H
+#define _WKC_H
+
+#include <bfc/dispatch.h>
+
+/**
+ A callback class for the loader so it can determine which resources wasabi.dll should load.
+*/
+class NOVTABLE WasabiKernelController : public Dispatchable {
+public:
+/**
+ Check if a component should load.
+*/
+ int testComponent(const char *filename);
+ int testScript(const char *filename, void *data, int datalen);
+ int testSkin(const char *skinname);
+ int testSkinFile(const char *filename);
+
+protected:
+ enum {
+ TESTCOMPONENT=1000,
+ TESTSCRIPT=2000,
+ TESTSKIN=3000,
+ TESTSKINFILE=4000,
+ };
+};
+
+inline
+int WasabiKernelController::testComponent(const char *filename) {
+ return _call(TESTCOMPONENT, TRUE, filename);
+}
+
+inline
+int WasabiKernelController::testScript(const char *filename, void *data, int datalen) {
+ return _call(TESTSCRIPT, TRUE, filename, data, datalen);
+}
+
+inline
+int WasabiKernelController::testSkin(const char *skinname) {
+ return _call(TESTSKIN, TRUE, skinname);
+}
+
+inline
+int WasabiKernelController::testSkinFile(const char *filename) {
+ return _call(TESTSKINFILE, TRUE, filename);
+}
+
+// implementors derive from this one
+class WasabiKernelControllerI : public WasabiKernelController {
+public:
+ // default to OK
+ virtual int testComponent(const char *filename) { return 1; }
+ virtual int testScript(const char *filename, void *data, int datalen) { return 1; }
+ virtual int testSkin(const char *skinname) { return 1; }
+ virtual int testSkinFile(const char *filename) { return 1; }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/api_config.cpp b/Src/Wasabi/api/config/api_config.cpp
new file mode 100644
index 00000000..4cffc910
--- /dev/null
+++ b/Src/Wasabi/api/config/api_config.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:24 2003]
+//
+// File : api_config.cpp
+// Class : api_config
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_config.h"
+
+
diff --git a/Src/Wasabi/api/config/api_config.h b/Src/Wasabi/api/config/api_config.h
new file mode 100644
index 00000000..ece231b5
--- /dev/null
+++ b/Src/Wasabi/api/config/api_config.h
@@ -0,0 +1,149 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:24 2003]
+//
+// File : api_config.h
+// Class : api_config
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_CONFIG_H
+#define __API_CONFIG_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+
+class CfgItem;
+class ConfigFile;
+
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE api_config: public Dispatchable
+{
+ protected:
+ api_config() {}
+ ~api_config() {}
+ public:
+ void config_registerCfgItem(CfgItem *cfgitem);
+ void config_deregisterCfgItem(CfgItem *cfgitem);
+ int config_getNumCfgItems();
+ CfgItem *config_enumCfgItem(int n);
+ CfgItem *config_getCfgItemByGuid(GUID g);
+ void setIntPrivate(const wchar_t *name, int val);
+ int getIntPrivate(const wchar_t *name, int def_val);
+ void setIntArrayPrivate(const wchar_t *name, const int *val, int nval);
+ int getIntArrayPrivate(const wchar_t *name, int *val, int nval);
+ void setStringPrivate(const wchar_t *name, const wchar_t *str);
+ int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+ int getStringPrivateLen(const wchar_t *name);
+ void setIntPublic(const wchar_t *name, int val);
+ int getIntPublic(const wchar_t *name, int def_val);
+ void setStringPublic(const wchar_t *name, const wchar_t *str);
+ int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+
+ protected:
+ enum {
+ API_CONFIG_CONFIG_REGISTERCFGITEM = 10,
+ API_CONFIG_CONFIG_DEREGISTERCFGITEM = 20,
+ API_CONFIG_CONFIG_GETNUMCFGITEMS = 30,
+ API_CONFIG_CONFIG_ENUMCFGITEM = 40,
+ API_CONFIG_CONFIG_GETCFGITEMBYGUID = 50,
+ API_CONFIG_SETINTPRIVATE = 60,
+ API_CONFIG_GETINTPRIVATE = 70,
+ API_CONFIG_SETINTARRAYPRIVATE = 80,
+ API_CONFIG_GETINTARRAYPRIVATE = 90,
+ API_CONFIG_SETSTRINGPRIVATE = 100,
+ API_CONFIG_GETSTRINGPRIVATE = 110,
+ API_CONFIG_GETSTRINGPRIVATELEN = 120,
+ API_CONFIG_SETINTPUBLIC = 130,
+ API_CONFIG_GETINTPUBLIC = 140,
+ API_CONFIG_SETSTRINGPUBLIC = 150,
+ API_CONFIG_GETSTRINGPUBLIC = 160,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline void api_config::config_registerCfgItem(CfgItem *cfgitem) {
+ _voidcall(API_CONFIG_CONFIG_REGISTERCFGITEM, cfgitem);
+}
+
+inline void api_config::config_deregisterCfgItem(CfgItem *cfgitem) {
+ _voidcall(API_CONFIG_CONFIG_DEREGISTERCFGITEM, cfgitem);
+}
+
+inline int api_config::config_getNumCfgItems() {
+ int __retval = _call(API_CONFIG_CONFIG_GETNUMCFGITEMS, (int)0);
+ return __retval;
+}
+
+inline CfgItem *api_config::config_enumCfgItem(int n) {
+ CfgItem *__retval = _call(API_CONFIG_CONFIG_ENUMCFGITEM, (CfgItem *)NULL, n);
+ return __retval;
+}
+
+inline CfgItem *api_config::config_getCfgItemByGuid(GUID g) {
+ CfgItem *__retval = _call(API_CONFIG_CONFIG_GETCFGITEMBYGUID, (CfgItem *)NULL, g);
+ return __retval;
+}
+
+inline void api_config::setIntPrivate(const wchar_t *name, int val) {
+ _voidcall(API_CONFIG_SETINTPRIVATE, name, val);
+}
+
+inline int api_config::getIntPrivate(const wchar_t *name, int def_val) {
+ int __retval = _call(API_CONFIG_GETINTPRIVATE, (int)0, name, def_val);
+ return __retval;
+}
+
+inline void api_config::setIntArrayPrivate(const wchar_t *name, const int *val, int nval) {
+ _voidcall(API_CONFIG_SETINTARRAYPRIVATE, name, val, nval);
+}
+
+inline int api_config::getIntArrayPrivate(const wchar_t *name, int *val, int nval) {
+ int __retval = _call(API_CONFIG_GETINTARRAYPRIVATE, (int)0, name, val, nval);
+ return __retval;
+}
+
+inline void api_config::setStringPrivate(const wchar_t *name, const wchar_t *str) {
+ _voidcall(API_CONFIG_SETSTRINGPRIVATE, name, str);
+}
+
+inline int api_config::getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str) {
+ int __retval = _call(API_CONFIG_GETSTRINGPRIVATE, (int)0, name, buf, buf_len, default_str);
+ return __retval;
+}
+
+inline int api_config::getStringPrivateLen(const wchar_t *name) {
+ int __retval = _call(API_CONFIG_GETSTRINGPRIVATELEN, (int)0, name);
+ return __retval;
+}
+
+inline void api_config::setIntPublic(const wchar_t *name, int val) {
+ _voidcall(API_CONFIG_SETINTPUBLIC, name, val);
+}
+
+inline int api_config::getIntPublic(const wchar_t *name, int def_val) {
+ int __retval = _call(API_CONFIG_GETINTPUBLIC, (int)0, name, def_val);
+ return __retval;
+}
+
+inline void api_config::setStringPublic(const wchar_t *name, const wchar_t *str) {
+ _voidcall(API_CONFIG_SETSTRINGPUBLIC, name, str);
+}
+
+inline int api_config::getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str) {
+ int __retval = _call(API_CONFIG_GETSTRINGPUBLIC, (int)0, name, buf, buf_len, default_str);
+ return __retval;
+}
+
+// ----------------------------------------------------------------------------
+
+
+// {470B890C-4747-4113-ABA5-A8F8F4F8AB7E}
+static const GUID configApiServiceGuid =
+{ 0x470b890c, 0x4747, 0x4113, { 0xab, 0xa5, 0xa8, 0xf8, 0xf4, 0xf8, 0xab, 0x7e } };
+
+extern api_config *configApi;
+
+#endif // __API_CONFIG_H
diff --git a/Src/Wasabi/api/config/api_configi.cpp b/Src/Wasabi/api/config/api_configi.cpp
new file mode 100644
index 00000000..d6b62189
--- /dev/null
+++ b/Src/Wasabi/api/config/api_configi.cpp
@@ -0,0 +1,124 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "api_configi.h"
+//?>
+
+#include <bfc/parse/pathparse.h>
+#include <api/config/cfglist.h>
+
+
+static CfgList cfglist;
+
+api_config *configApi = NULL;
+
+api_configI::api_configI()
+: public_config(StringPrintfW(INVALID_GUID), L"public data")
+{
+ public_config.initialize();
+}
+
+api_configI::~api_configI()
+{
+}
+
+void api_configI::config_registerCfgItem(CfgItem *cfgitem)
+{
+ cfglist.addItem(cfgitem);
+}
+
+void api_configI::config_deregisterCfgItem(CfgItem *cfgitem)
+{
+ cfglist.delItem(cfgitem);
+}
+
+int api_configI::config_getNumCfgItems()
+{
+ return cfglist.getNumItems();
+}
+
+CfgItem *api_configI::config_enumCfgItem(int n)
+{
+ return cfglist.enumItem(n);
+}
+
+CfgItem *api_configI::config_getCfgItemByGuid(GUID g)
+{
+ return cfglist.getByGuid(g);
+}
+
+// The private config functions are currently pointing at the public config item, this is because
+// only the monolithic api gets instantiated once per component and thus can know its GUID, this
+// version of the config api should eventually be instantiated once per component as well when
+// we start making them use the modular apis
+void api_configI::setIntPrivate(const wchar_t *name, int val)
+{
+ public_config.setInt(name, val);
+}
+
+int api_configI::getIntPrivate(const wchar_t *name, int def_val)
+{
+ int ret = public_config.getInt(name, def_val);
+ return ret;
+}
+
+void api_configI::setIntArrayPrivate(const wchar_t *name, const int *val, int nval)
+{
+ if (nval > 256) return;
+ wchar_t buf[12*256]=L"";
+ for (int i = 0; i < nval; i++)
+ {
+ wcscat(buf, StringPrintfW(L"%d", val[i]));
+ if (i != nval-1)
+ wcscat(buf, L",");
+ }
+ public_config.setString(name, buf);
+}
+
+int api_configI::getIntArrayPrivate(const wchar_t *name, int *val, int nval)
+{
+ wchar_t buf[12*256]=L"";
+ public_config.getString(name, buf, sizeof(buf)/sizeof(*buf), L"");
+ PathParserW pp(buf, L",");
+ if (pp.getNumStrings() != nval) return 0;
+ for (int i = 0; i < nval; i++) {
+ *val = WTOI(pp.enumString(i));
+ val ++;
+ }
+ return 1;
+}
+
+void api_configI::setStringPrivate(const wchar_t *name, const wchar_t *str)
+{
+ public_config.setString(name, str);
+}
+
+int api_configI::getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str)
+{
+ int ret = public_config.getString(name, buf, buf_len, default_str);
+ return ret;
+}
+
+int api_configI::getStringPrivateLen(const wchar_t *name)
+{
+ return public_config.getStringLen(name);
+}
+
+void api_configI::setIntPublic(const wchar_t *name, int val)
+{
+ public_config.setInt(name, val);
+}
+
+int api_configI::getIntPublic(const wchar_t *name, int def_val)
+{
+ return public_config.getInt(name, def_val);
+}
+
+void api_configI::setStringPublic(const wchar_t *name, const wchar_t *str)
+{
+ public_config.setString(name, str);
+}
+
+int api_configI::getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str)
+{
+ return public_config.getString(name, buf, buf_len, default_str);
+}
diff --git a/Src/Wasabi/api/config/api_configi.h b/Src/Wasabi/api/config/api_configi.h
new file mode 100644
index 00000000..d0e5f755
--- /dev/null
+++ b/Src/Wasabi/api/config/api_configi.h
@@ -0,0 +1,46 @@
+#ifndef __API_CONFIG_IMPL_H
+#define __API_CONFIG_IMPL_H
+
+/*<?<autoheader/>*/
+#include "api_config.h"
+#include "api_configx.h"
+#include <api/config/config.h>
+
+class CfgItem;
+/*?>*/
+
+class api_configI : public api_configX
+{
+public:
+ api_configI();
+ virtual ~api_configI();
+
+ DISPATCH(10) virtual void config_registerCfgItem(CfgItem *cfgitem);
+ DISPATCH(20) virtual void config_deregisterCfgItem(CfgItem *cfgitem);
+ DISPATCH(30) virtual int config_getNumCfgItems();
+ DISPATCH(40) virtual CfgItem *config_enumCfgItem(int n);
+ DISPATCH(50) virtual CfgItem *config_getCfgItemByGuid(GUID g);
+ DISPATCH(60) virtual void setIntPrivate(const wchar_t *name, int val);
+ DISPATCH(70) virtual int getIntPrivate(const wchar_t *name, int def_val);
+ DISPATCH(80) virtual void setIntArrayPrivate(const wchar_t *name, const int *val, int nval);
+ DISPATCH(90) virtual int getIntArrayPrivate(const wchar_t *name, int *val, int nval);
+ DISPATCH(100) virtual void setStringPrivate(const wchar_t *name, const wchar_t *str);
+ DISPATCH(110) virtual int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+ DISPATCH(120) virtual int getStringPrivateLen(const wchar_t *name);
+ DISPATCH(130) virtual void setIntPublic(const wchar_t *name, int val);
+ DISPATCH(140) virtual int getIntPublic(const wchar_t *name, int def_val);
+ DISPATCH(150) virtual void setStringPublic(const wchar_t *name, const wchar_t *str);
+ DISPATCH(160) virtual int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+private:
+ ConfigFile public_config;
+};
+
+/*[interface.footer.h]
+// {470B890C-4747-4113-ABA5-A8F8F4F8AB7E}
+static const GUID configApiServiceGuid =
+{ 0x470b890c, 0x4747, 0x4113, { 0xab, 0xa5, 0xa8, 0xf8, 0xf4, 0xf8, 0xab, 0x7e } };
+
+extern api_config *configApi;
+*/
+
+#endif // __API_CONFIG_IMPL_H
diff --git a/Src/Wasabi/api/config/api_configx.cpp b/Src/Wasabi/api/config/api_configx.cpp
new file mode 100644
index 00000000..8296023e
--- /dev/null
+++ b/Src/Wasabi/api/config/api_configx.cpp
@@ -0,0 +1,37 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:25 2003]
+//
+// File : api_configx.cpp
+// Class : api_config
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "api_configx.h"
+#include "api_configi.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_configX
+START_DISPATCH;
+ VCB(API_CONFIG_CONFIG_REGISTERCFGITEM, config_registerCfgItem);
+ VCB(API_CONFIG_CONFIG_DEREGISTERCFGITEM, config_deregisterCfgItem);
+ CB(API_CONFIG_CONFIG_GETNUMCFGITEMS, config_getNumCfgItems);
+ CB(API_CONFIG_CONFIG_ENUMCFGITEM, config_enumCfgItem);
+ CB(API_CONFIG_CONFIG_GETCFGITEMBYGUID, config_getCfgItemByGuid);
+ VCB(API_CONFIG_SETINTPRIVATE, setIntPrivate);
+ CB(API_CONFIG_GETINTPRIVATE, getIntPrivate);
+ VCB(API_CONFIG_SETINTARRAYPRIVATE, setIntArrayPrivate);
+ CB(API_CONFIG_GETINTARRAYPRIVATE, getIntArrayPrivate);
+ VCB(API_CONFIG_SETSTRINGPRIVATE, setStringPrivate);
+ CB(API_CONFIG_GETSTRINGPRIVATE, getStringPrivate);
+ CB(API_CONFIG_GETSTRINGPRIVATELEN, getStringPrivateLen);
+ VCB(API_CONFIG_SETINTPUBLIC, setIntPublic);
+ CB(API_CONFIG_GETINTPUBLIC, getIntPublic);
+ VCB(API_CONFIG_SETSTRINGPUBLIC, setStringPublic);
+ CB(API_CONFIG_GETSTRINGPUBLIC, getStringPublic);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/config/api_configx.h b/Src/Wasabi/api/config/api_configx.h
new file mode 100644
index 00000000..d8594b68
--- /dev/null
+++ b/Src/Wasabi/api/config/api_configx.h
@@ -0,0 +1,44 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:24 2003]
+//
+// File : api_configx.h
+// Class : api_config
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_CONFIGX_H
+#define __API_CONFIGX_H
+
+#include "api_config.h"
+
+class CfgItem;
+class ConfigFile;
+
+// ----------------------------------------------------------------------------
+
+class api_configX : public api_config {
+ protected:
+ api_configX() {}
+ public:
+ virtual void config_registerCfgItem(CfgItem *cfgitem)=0;
+ virtual void config_deregisterCfgItem(CfgItem *cfgitem)=0;
+ virtual int config_getNumCfgItems()=0;
+ virtual CfgItem *config_enumCfgItem(int n)=0;
+ virtual CfgItem *config_getCfgItemByGuid(GUID g)=0;
+ virtual void setIntPrivate(const wchar_t *name, int val)=0;
+ virtual int getIntPrivate(const wchar_t *name, int def_val)=0;
+ virtual void setIntArrayPrivate(const wchar_t *name, const int *val, int nval)=0;
+ virtual int getIntArrayPrivate(const wchar_t *name, int *val, int nval)=0;
+ virtual void setStringPrivate(const wchar_t *name, const wchar_t *str)=0;
+ virtual int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str)=0;
+ virtual int getStringPrivateLen(const wchar_t *name)=0;
+ virtual void setIntPublic(const wchar_t *name, int val)=0;
+ virtual int getIntPublic(const wchar_t *name, int def_val)=0;
+ virtual void setStringPublic(const wchar_t *name, const wchar_t *str)=0;
+ virtual int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_CONFIGX_H
diff --git a/Src/Wasabi/api/config/cfglist.cpp b/Src/Wasabi/api/config/cfglist.cpp
new file mode 100644
index 00000000..b6baaab5
--- /dev/null
+++ b/Src/Wasabi/api/config/cfglist.cpp
@@ -0,0 +1,50 @@
+#include <precomp.h>
+
+#include "cfglist.h"
+#include <bfc/ptrlist.h>
+
+void CfgList::addItem(CfgItem *cfgitem)
+{
+ if (cfgitem == NULL ||
+ cfgitem->getGuid() == INVALID_GUID ||
+ list.haveItem(cfgitem)) return;
+ viewer_addViewItem(cfgitem);
+ list.addItem(cfgitem);
+
+ cfgitem->onRegister(); // recurses children
+}
+
+void CfgList::delItem(CfgItem *cfgitem)
+{
+ if (cfgitem == NULL || !list.haveItem(cfgitem)) return;
+
+ list.removeItem(cfgitem);
+ viewer_delViewItem(cfgitem);
+
+ cfgitem->onDeregister(); // recurses children
+}
+
+int CfgList::getNumItems()
+{
+ return list.getNumItems();
+}
+
+CfgItem *CfgList::enumItem(int n)
+{
+ return list[n];
+}
+
+CfgItem *CfgList::getByGuid(GUID g)
+{
+ if (g == INVALID_GUID) return NULL;
+ foreach(list)
+ if (list.getfor()->getGuid() == g) return list.getfor();
+ endfor
+ return NULL;
+}
+
+int CfgList::viewer_onItemDeleted(CfgItem *item)
+{
+ list.removeItem(item);
+ return 1;
+}
diff --git a/Src/Wasabi/api/config/cfglist.h b/Src/Wasabi/api/config/cfglist.h
new file mode 100644
index 00000000..cf456ccc
--- /dev/null
+++ b/Src/Wasabi/api/config/cfglist.h
@@ -0,0 +1,23 @@
+#ifndef _CFGLIST_H
+#define _CFGLIST_H
+
+#include <bfc/wasabi_std.h>
+#include <bfc/depview.h>
+#include <api/config/items/cfgitem.h>
+
+class CfgList : public DependentViewerTPtr<CfgItem> {
+public:
+ void addItem(CfgItem *cfgitem);
+ void delItem(CfgItem *cfgitem);
+
+ int getNumItems();
+ CfgItem *enumItem(int n);
+ CfgItem *getByGuid(GUID g);
+
+ virtual int viewer_onItemDeleted(CfgItem *item);
+
+private:
+ PtrList<CfgItem> list;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/cfgscriptobj.cpp b/Src/Wasabi/api/config/cfgscriptobj.cpp
new file mode 100644
index 00000000..6d220f02
--- /dev/null
+++ b/Src/Wasabi/api/config/cfgscriptobj.cpp
@@ -0,0 +1,371 @@
+#include <precomp.h>
+#include "cfgscriptobj.h"
+
+#include <api/config/items/cfgitemi.h>
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(ConfigObject_Svc);
+DECLARE_SERVICE(ScriptObjectCreator<ConfigScriptObjectSvc>);
+END_SERVICES(ConfigObject_Svc, _ConfigObject_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_ConfigObjectSvc; }
+#else
+extern "C" { int __link_ConfigObjectSvc; }
+#endif
+
+#endif
+
+static ConfigScriptObjectController _configController;
+ScriptObjectController *configController = &_configController;
+
+static ConfigItemScriptObjectController _configItemController;
+ScriptObjectController *configItemController = &_configItemController;
+
+static ConfigAttributeScriptObjectController _configAttributeController;
+ScriptObjectController *configAttributeController = &_configAttributeController;
+
+
+// -----------------------------------------------------------------------------------------------------
+// Service
+
+ScriptObjectController *ConfigScriptObjectSvc::getController(int n)
+{
+ switch (n) {
+ case 0:
+ return configController;
+ case 1:
+ return configItemController;
+ case 2:
+ return configAttributeController;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------------------------------
+// ConfigObject
+
+ConfigObject::ConfigObject() {
+ numobjects++;
+ getScriptObject()->vcpu_setInterface(CONFIG_SCRIPTOBJECT_GUID, (void *)static_cast<ConfigObject *>(this));
+ getScriptObject()->vcpu_setClassName(L"Config");
+ getScriptObject()->vcpu_setController(configController);
+}
+
+ConfigObject::~ConfigObject() {
+ numobjects--;
+ mylist.deleteAll();
+ if (numobjects == 0) {
+ foreach(ouraddeditems)
+ WASABI_API_CONFIG->config_deregisterCfgItem(ouraddeditems.getfor());
+ endfor
+ ouraddeditems.deleteAll();
+ }
+}
+
+PtrList<CfgItemI> ConfigObject::ouraddeditems;
+int ConfigObject::numobjects=0;
+
+
+function_descriptor_struct ConfigScriptObjectController::exportedFunction[] = {
+ {L"getItem", 1, (void*)ConfigObject::config_getItem},
+ {L"getItemByGuid", 1, (void*)ConfigObject::config_getItemByGuid},
+ {L"newItem", 2, (void*)ConfigObject::config_newItem},
+};
+
+int ConfigScriptObjectController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+scriptVar ConfigObject::config_newItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name, scriptVar configitem_guid)
+{
+ SCRIPT_FUNCTION_INIT
+ ConfigObject *co = static_cast<ConfigObject*>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID));
+ ConfigItemObject *ret=getItem(GET_SCRIPT_STRING(configitem_name), co);
+ if (!ret)
+ ret = getItem(GET_SCRIPT_STRING(configitem_guid), co);
+ if (ret)
+ return MAKE_SCRIPT_OBJECT(ret->getScriptObject());
+ CfgItemI *item = new CfgItemI(GET_SCRIPT_STRING(configitem_name), nsGUID::fromCharW(GET_SCRIPT_STRING(configitem_guid)));
+ ConfigObject::ouraddeditems.addItem(item);
+ WASABI_API_CONFIG->config_registerCfgItem(item);
+ ret = new ConfigItemObject(item);
+ co->mylist.addItem(ret);
+ return MAKE_SCRIPT_OBJECT(ret->getScriptObject());
+}
+
+ConfigItemObject *ConfigObject::getItem(const wchar_t *nameorguid, ConfigObject *co) {
+ int i=0;
+ ConfigItemObject *ret=NULL;
+ GUID g = nsGUID::fromCharW(nameorguid);
+ for (i=0;;i++) {
+ CfgItem *item = WASABI_API_CONFIG->config_enumCfgItem(i);
+ if (!item) break;
+ GUID ig = item->getGuid();
+ if (g == ig || WCSCASEEQLSAFE(nameorguid, item->getName()))
+ {
+ ret = new ConfigItemObject(item);
+ co->mylist.addItem(ret);
+ break;
+ }
+#if 0//CUT
+ for (int j=0;j<item->getNumChildren();j++) {
+ if (STRCASEEQL(nameorguid, item->enumChild(j)->getName())) {
+ ret = new ConfigItemObject(item->enumChild(j));
+ co->mylist.addItem(ret);
+ break;
+ }
+ }
+#endif
+ }
+ return ret;
+}
+
+scriptVar ConfigObject::config_getItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cfgitem_name)
+{
+ SCRIPT_FUNCTION_INIT
+ ConfigObject *co = static_cast<ConfigObject*>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID));
+ ConfigItemObject *ret=getItem(GET_SCRIPT_STRING(cfgitem_name), co);
+ return MAKE_SCRIPT_OBJECT(ret ? ret->getScriptObject() : NULL);
+}
+
+scriptVar ConfigObject::config_getItemByGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cfgitem_guid)
+{
+ SCRIPT_FUNCTION_INIT
+// GUID g = nsGUID::fromChar(GET_SCRIPT_STRING(guid));
+// api->
+ int i=0;
+ ConfigItemObject *ret=NULL;
+ ConfigObject *co = static_cast<ConfigObject*>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID));
+
+ const wchar_t *p = GET_SCRIPT_STRING(cfgitem_guid);
+ if (p == NULL) {
+ RETURN_SCRIPT_ZERO;
+ }
+
+ GUID g = nsGUID::fromCharW(p);
+
+ for (i=0;;i++) {
+ CfgItem *item = WASABI_API_CONFIG->config_enumCfgItem(i);
+ if (!item) break;
+ if (g == item->getGuid()) {
+ ret = new ConfigItemObject(item);
+ co->mylist.addItem(ret);
+ break;
+ }
+#if 0//CUT
+ for (int j=0;j<item->getNumChildren();j++) {
+ if (g == item->enumChild(j)->getName()) {
+ ret = new ConfigItemObject(item->enumChild(j));
+ co->mylist.addItem(ret);
+ break;
+ }
+ }
+#endif
+ }
+ return MAKE_SCRIPT_OBJECT(ret ? ret->getScriptObject() : NULL);
+}
+
+ScriptObject *ConfigScriptObjectController::instantiate() {
+ ConfigObject *c = new ConfigObject;
+ if (!c) return NULL;
+ return c->getScriptObject();
+}
+
+void ConfigScriptObjectController::destroy(ScriptObject *o) {
+ ConfigObject *obj = static_cast<ConfigObject *>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *ConfigScriptObjectController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for config
+}
+
+void ConfigScriptObjectController::deencapsulate(void *) {
+}
+
+// -----------------------------------------------------------------------------------------------------
+// ConfigItem
+
+function_descriptor_struct ConfigItemScriptObjectController::exportedFunction[] = {
+ {L"getAttribute", 1, (void*)ConfigItemObject::configItem_getAttribute},
+ {L"getGuid", 0, (void*)ConfigItemObject::configItem_getGuid},
+ {L"newAttribute", 2, (void*)ConfigItemObject::configItem_newAttribute},
+};
+
+int ConfigItemScriptObjectController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+ConfigItemObject::ConfigItemObject(CfgItem *_item)
+{
+ getScriptObject()->vcpu_setInterface(CONFIGITEM_SCRIPTOBJECT_GUID, (void *)static_cast<ConfigItemObject *>(this));
+ getScriptObject()->vcpu_setClassName(L"ConfigItem");
+ getScriptObject()->vcpu_setController(configItemController);
+ wchar_t strguid[256];
+ nsGUID::toCharW(_item->getGuid(), strguid);
+ guid = strguid;
+ item = _item;
+}
+
+ConfigAttributeObject *ConfigItemObject::getAttribute(const wchar_t *name)
+{
+ if (!item) return NULL;
+ for (int i=0;i<item->getNumAttributes();i++)
+ {
+ if (!WCSICMP(item->enumAttribute(i), name))
+ {
+ ConfigAttributeObject *o = new ConfigAttributeObject(item, name, this);
+ mylist.addItem(o);
+ return o;
+ }
+ }
+ return NULL;
+}
+
+ConfigAttributeObject *ConfigItemObject::newAttribute(const wchar_t *name, const wchar_t *defaultvalue)
+{
+ if (!item) return NULL;
+ ConfigAttributeObject *o = getAttribute(name);
+ if (o != NULL) return o;
+
+ item->addAttribute(name, defaultvalue);
+
+ ConfigAttributeObject *cao = getAttribute(name);
+ cao->setAutoDelete();
+ return cao;
+}
+
+ConfigItemObject::~ConfigItemObject()
+{
+ mylist.deleteAll();
+}
+
+scriptVar ConfigItemObject::configItem_getAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+ ConfigItemObject *cio = static_cast<ConfigItemObject *>(o->vcpu_getInterface(CONFIGITEM_SCRIPTOBJECT_GUID));
+ ConfigAttributeObject *cao = NULL;
+ if (cio)
+ cao = cio->getAttribute(GET_SCRIPT_STRING(name));
+ return MAKE_SCRIPT_OBJECT(cao ? cao->getScriptObject() : NULL);
+}
+
+scriptVar ConfigItemObject::configItem_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ConfigItemObject *cio = static_cast<ConfigItemObject *>(o->vcpu_getInterface(CONFIGITEM_SCRIPTOBJECT_GUID));
+ if (cio) return MAKE_SCRIPT_STRING(cio->getGuid());
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar ConfigItemObject::configItem_newAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name, scriptVar defval) {
+ SCRIPT_FUNCTION_INIT
+ ConfigItemObject *cio = static_cast<ConfigItemObject *>(o->vcpu_getInterface(CONFIGITEM_SCRIPTOBJECT_GUID));
+ ConfigAttributeObject *cao = NULL;
+ if (cio)
+ cao = cio->newAttribute(GET_SCRIPT_STRING(name), GET_SCRIPT_STRING(defval));
+ return MAKE_SCRIPT_OBJECT(cao ? cao->getScriptObject() : NULL);
+}
+
+// -----------------------------------------------------------------------------------------------------
+// ConfigAttribute
+
+function_descriptor_struct ConfigAttributeScriptObjectController::exportedFunction[] = {
+ {L"getData", 0, (void*)ConfigAttributeObject::configAttr_getData},
+ {L"setData", 1, (void*)ConfigAttributeObject::configAttr_setData},
+ {L"onDataChanged", 0, (void*)ConfigAttributeObject::configAttr_onDataChanged},
+ {L"getParentItem", 0, (void*)ConfigAttributeObject::configAttr_getParentItem},
+ {L"getAttributeName", 0, (void*)ConfigAttributeObject::configAttr_getAttributeName},
+};
+
+int ConfigAttributeScriptObjectController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+void ConfigAttributeObject::setData(const wchar_t *data)
+{
+ if (!item || !attr) return;
+ item->setData(attr, data);
+}
+
+const wchar_t *ConfigAttributeObject::getData()
+{
+ if (!item || !attr) return NULL;
+ static wchar_t t[WA_MAX_PATH];
+ item->getData(attr, t, WA_MAX_PATH);
+ return t;
+}
+
+ConfigAttributeObject::ConfigAttributeObject(CfgItem *_item, const wchar_t *_attr, ConfigItemObject *_parent)
+{
+ getScriptObject()->vcpu_setInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID, (void *)static_cast<ConfigAttributeObject *>(this));
+ getScriptObject()->vcpu_setClassName(L"ConfigAttribute");
+ getScriptObject()->vcpu_setController(configAttributeController);
+ attr = _attr;
+ item = _item;
+ parent = _parent;
+ viewer_addViewItem(item);
+ autodelete = 0;
+}
+
+ConfigAttributeObject::~ConfigAttributeObject() {
+ if (autodelete) getParentItem()->getCfgItem()->delAttribute(attr);
+}
+
+int ConfigAttributeObject::viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (event == CfgItem::Event_ATTRIBUTE_CHANGED)
+ {
+ const wchar_t *_attr = reinterpret_cast<const wchar_t *>(ptr);
+ if (!WCSICMP(attr, _attr))
+ configAttr_onDataChanged(SCRIPT_CALL, getScriptObject());
+ }
+ return 1;
+}
+
+scriptVar ConfigAttributeObject::configAttr_setData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val)
+{
+ SCRIPT_FUNCTION_INIT
+ ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID));
+ if (cao)
+ cao->setData(GET_SCRIPT_STRING(val));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ConfigAttributeObject::configAttr_getData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID));
+ if (cao)
+ return MAKE_SCRIPT_STRING(cao->getData());
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar ConfigAttributeObject::configAttr_onDataChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, configAttributeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar ConfigAttributeObject::configAttr_getParentItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID));
+ if (cao) return MAKE_SCRIPT_OBJECT(cao->getParentItem()->getScriptObject());
+ return MAKE_SCRIPT_OBJECT(NULL);
+}
+
+scriptVar ConfigAttributeObject::configAttr_getAttributeName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID));
+
+ if (cao)
+ return MAKE_SCRIPT_STRING(cao->getAttributeName());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+
+
diff --git a/Src/Wasabi/api/config/cfgscriptobj.h b/Src/Wasabi/api/config/cfgscriptobj.h
new file mode 100644
index 00000000..e446b618
--- /dev/null
+++ b/Src/Wasabi/api/config/cfgscriptobj.h
@@ -0,0 +1,198 @@
+#ifndef __CFGSCRIPTOBJ_H
+#define __CFGSCRIPTOBJ_H
+
+#include <api/script/objects/rootobj.h>
+#include <api/script/objcontroller.h>
+#include <api/script/scriptobj.h>
+#include <bfc/depview.h>
+#include <api/service/svcs/svc_scriptobji.h>
+#include <api/config/items/attribs.h>
+
+class CfgItem;
+class ConfigObject;
+class ConfigItemObject;
+class ConfigAttributeObject;
+
+extern ScriptObjectController *configController;
+extern ScriptObjectController *configItemController;
+extern ScriptObjectController *configAttributeController;
+
+enum cfgtypes {
+ CFG_INT = 0,
+ CFG_BOOL = 1,
+ CFG_FLOAT = 2,
+ CFG_STRING = 3,
+};
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Provider Service
+
+class ConfigScriptObjectSvc : public svc_scriptObjectI {
+
+public:
+ ConfigScriptObjectSvc() {};
+ virtual ~ConfigScriptObjectSvc() {};
+
+ static const char *getServiceName() { return "Config maki object"; }
+ virtual ScriptObjectController *getController(int n);
+
+ static void addItemObject(ConfigItemObject *item);
+ static void addAttrObject(ConfigAttributeObject *attr);
+ static void removeItemObject(ConfigItemObject *item);
+ static void removeAttrObject(ConfigAttributeObject *attr);
+};
+
+// -----------------------------------------------------------------------------------------------------
+// Script classes GUIDS
+
+// {593DBA22-D077-4976-B952-F4713655400B}
+static const GUID CONFIG_SCRIPTOBJECT_GUID =
+{ 0x593dba22, 0xd077, 0x4976, { 0xb9, 0x52, 0xf4, 0x71, 0x36, 0x55, 0x40, 0xb } };
+
+// {D4030282-3AAB-4d87-878D-12326FADFCD5}
+static const GUID CONFIGITEM_SCRIPTOBJECT_GUID =
+{ 0xd4030282, 0x3aab, 0x4d87, { 0x87, 0x8d, 0x12, 0x32, 0x6f, 0xad, 0xfc, 0xd5 } };
+
+// {24DEC283-B76E-4a36-8CCC-9E24C46B6C73}
+static const GUID CONFIGATTRIBUTE_SCRIPTOBJECT_GUID =
+{ 0x24dec283, 0xb76e, 0x4a36, { 0x8c, 0xcc, 0x9e, 0x24, 0xc4, 0x6b, 0x6c, 0x73 } };
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Interfaces
+
+// Config
+class ConfigObject : public RootObjectInstance {
+
+ public:
+
+ ConfigObject();
+ virtual ~ConfigObject();
+
+ static scriptVar config_getItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name);
+ static scriptVar config_getItemByGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name);
+ static scriptVar config_newItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name, scriptVar guid);
+ private:
+ static ConfigItemObject *getItem(const wchar_t *nameorguid, ConfigObject *co);
+ PtrList<ConfigItemObject> mylist;
+ static PtrList<CfgItemI> ouraddeditems;
+ static int numobjects;
+};
+
+// ConfigItem
+class ConfigItemObject : public RootObjectInstance {
+
+ public:
+
+ ConfigItemObject(CfgItem *item);
+ virtual ~ConfigItemObject();
+
+ ConfigAttributeObject *getAttribute(const wchar_t *name);
+ const wchar_t *getGuid() { return guid; }
+ ConfigAttributeObject *newAttribute(const wchar_t *name, const wchar_t *defval);
+
+ CfgItem *getCfgItem() { return item; }
+
+ static scriptVar configItem_getAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar attr_name);
+ static scriptVar configItem_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar configItem_newAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar attr_name, scriptVar defval);
+
+ private:
+ CfgItem *item;
+ StringW guid;
+ PtrList<ConfigAttributeObject> mylist;
+};
+
+// ConfigAttribute
+class ConfigAttributeObject : public RootObjectInstance, public DependentViewerTPtr<CfgItem> {
+
+ public:
+
+ ConfigAttributeObject(CfgItem *item, const wchar_t *attr, ConfigItemObject *parent);
+ virtual ~ConfigAttributeObject();
+
+ void setData(const wchar_t *data);
+ const wchar_t *getData();
+ ConfigItemObject *getParentItem() { return parent; }
+ const wchar_t *getAttributeName() { return attr; }
+ void setAutoDelete() { autodelete = 1; }
+
+ virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen);
+
+ static scriptVar configAttr_getData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar configAttr_setData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static scriptVar configAttr_onDataChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar configAttr_getParentItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar configAttr_getAttributeName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+ CfgItem *item;
+ StringW attr;
+ ConfigItemObject *parent;
+ int autodelete;
+};
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObjectControllers for our script classes
+
+// Config
+class ConfigScriptObjectController : public ScriptObjectControllerI {
+ public:
+ virtual const wchar_t *getClassName() { return L"Config"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return NULL; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return CONFIG_SCRIPTOBJECT_GUID; }
+ virtual int getInstantiable() { return 0; }
+ virtual int getReferenceable() { return 0; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+// ConfigItem
+class ConfigItemScriptObjectController : public ScriptObjectControllerI {
+ public:
+ virtual const wchar_t *getClassName() { return L"ConfigItem"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return NULL; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return CONFIGITEM_SCRIPTOBJECT_GUID; }
+ virtual int getInstantiable() { return 0; }
+ virtual int getReferenceable() { return 1; }
+ virtual ScriptObject *instantiate() { return NULL; };
+ virtual void destroy(ScriptObject *o) { };
+ virtual void *encapsulate(ScriptObject *o) { return NULL; };
+ virtual void deencapsulate(void *o) { };
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+// ConfigAttribute
+class ConfigAttributeScriptObjectController : public ScriptObjectControllerI {
+ public:
+ virtual const wchar_t *getClassName() { return L"ConfigAttribute"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return NULL; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return CONFIGATTRIBUTE_SCRIPTOBJECT_GUID; }
+ virtual int getInstantiable() { return 0; }
+ virtual int getReferenceable() { return 1; }
+ virtual ScriptObject *instantiate() { return NULL; };
+ virtual void destroy(ScriptObject *o) { };
+ virtual void *encapsulate(ScriptObject *o) { return NULL; };
+ virtual void deencapsulate(void *o) { };
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/config/config.cpp b/Src/Wasabi/api/config/config.cpp
new file mode 100644
index 00000000..3b45d934
--- /dev/null
+++ b/Src/Wasabi/api/config/config.cpp
@@ -0,0 +1,329 @@
+#include <precomp.h>
+
+#include "config.h"
+#include <bfc/pair.h>
+#include <bfc/ptrlist.h>
+#include <bfc/parse/pathparse.h>
+#include <api/xml/xmlwrite.h>
+
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include "../xml/obj_xml.h"
+#include <bfc/string/url.h>
+#include <api/service/waservicefactory.h>
+
+static StringW iniFile;
+#define XNFNAME L"studio.xnf"
+
+class StringPairCompare
+{
+public:
+ static int compareItem(StringPair *p1, StringPair *p2)
+ {
+ int r = wcscmp(p1->a.getValue(), p2->a.getValue());
+ if (r == 0)
+ return CMP3(p1, p2);
+ else
+ return r;
+ }
+ static int compareAttrib(const wchar_t *attrib, StringPair *item)
+ {
+ return wcscmp(attrib, item->a.getValue());
+ }
+};
+
+static PtrListQuickSorted<StringPair, StringPairCompare> strings;
+
+class Reader : public ifc_xmlreadercallbackI
+{
+public:
+ ~Reader();
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+
+ void readem();
+
+private:
+ PtrList<StringW> sections;
+};
+
+Reader::~Reader()
+{
+ sections.deleteAll();
+}
+
+void Reader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ if (!WCSICMP(xmltag, L"section"))
+ {
+ const wchar_t *name = params->getItemValue(L"name");
+ if (name == NULL)
+ return ;
+
+ StringW *strName = new StringW(name);
+ Url::decode(*strName);
+ sections.addItem(strName);
+ }
+ else if (!WCSICMP(xmltag, L"entry"))
+ {
+ const wchar_t *name = params->getItemValue(L"name");
+ const wchar_t *value = params->getItemValue(L"value");
+
+ // just in case
+ if (!WCSICMP(name, L"(null)")) name = NULL;
+ if (!WCSICMP(value, L"(null)")) value = NULL;
+
+ if (name == NULL /*| !*name */ || value == NULL /*|| !*value*/) return ;
+ StringW strName = name;
+ Url::decode(strName);
+
+ StringW strValue = value;
+ Url::decode(strValue);
+
+ StringW n;
+ for (int i = 0; i < sections.getNumItems(); i++)
+ {
+ n.catPostSeparator(*sections[i], '/');
+ }
+ n += strName;
+
+ StringPair *p = new StringPair(n, strValue);
+ strings.addItem(p);
+ }
+}
+
+void Reader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ if (!WCSICMP(xmltag, L"section"))
+ {
+ StringW *last = sections.getLast();
+ sections.removeLastItem();
+ delete last;
+ }
+}
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+void Reader::readem()
+{
+ strings.deleteAll();
+
+ if (iniFile.isempty())
+ {
+ iniFile = StringPathCombine(WASABI_API_APP->path_getUserSettingsPath(), XNFNAME);
+ }
+
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+
+ parser->xmlreader_registerCallback(L"WinampXML\fconfiguration\f*", this);
+ parser->xmlreader_registerCallback(L"WasabiXML\fconfiguration\f*", this);
+ parser->xmlreader_open();
+ LoadXmlFile(parser, iniFile);
+
+ parser->xmlreader_unregisterCallback(this);
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+StringPair *ConfigFile::getPair(const wchar_t *name)
+{
+ ASSERT(!sectionname.isempty());
+ StringW nname;
+ nname.catPostSeparator(sectionname.getValue(), '/');
+ nname.cat(name);
+ return strings.findItem(nname.getValue()); // cast to make PtrListSorted happy
+}
+
+StringPair *ConfigFile::makePair(const wchar_t *name, const wchar_t *value)
+{
+ StringPair *ret = getPair(name);
+ if (ret == NULL)
+ {
+ StringW nname;
+ nname.catPostSeparator(sectionname.getValue(), '/');
+ nname.cat(name);
+
+ ret = new StringPair(nname, value);
+ strings.addItem(ret);
+ }
+ else
+ {
+ ret->b.setValue(value);
+ }
+ return ret;
+}
+
+static int ninstances, inited;
+
+ConfigFile::ConfigFile(const wchar_t *section, const wchar_t *name)
+{
+ sectionname = section;
+ prettyname = name;
+ ninstances++;
+}
+
+void ConfigFile::initialize()
+{
+ Reader().readem();
+}
+
+ConfigFile::~ConfigFile()
+{
+ ninstances--;
+ if (ninstances == 0)
+ {
+ FILE *fp = _wfopen(iniFile, WF_WRITE_TEXT);
+ if (fp != NULL)
+ {
+ // write out the file
+ XMLWrite xml(fp, L"WasabiXML");
+ const wchar_t *app = WASABI_API_APP->main_getVersionString();
+ if (!app)
+ app = L"thousands of irascible butt monkeys";
+ xml.comment(StringPrintfW(L"Generated by: %s (%d)", app, WASABI_API_APP->main_getBuildNumber()));
+ xml.pushCategory(L"configuration");
+
+ PtrList<StringW> cats;
+
+ for (int i = 0; i < strings.getNumItems(); i++)
+ {
+ StringPair *p = strings[i];
+ PathParserW pp(p->a);
+
+ int climit = MIN(pp.getNumStrings() - 1, cats.getNumItems());
+ int j;
+ for (j = 0; j < climit; j++)
+ {
+ if (WCSICMP(*cats[j], pp.enumString(j)))
+ {
+ climit = j;
+ break;
+ }
+ }
+
+ while (cats.getNumItems() > climit)
+ {
+ StringW *s = cats.getLast();
+ xml.popCategory();
+ cats.removeLastItem();
+ delete s;
+ }
+ for (j = climit; j < pp.getNumStrings() - 1; j++)
+ {
+ StringW *s = cats.addItem(new StringW(pp.enumString(j)));
+ xml.pushCategoryAttrib(L"section");
+ StringW enc = *s;
+ Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32);
+ xml.writeCategoryAttrib(L"name", enc);
+ xml.closeCategoryAttrib();
+ }
+
+ xml.pushCategoryAttrib(L"entry", TRUE);
+ StringW enc = pp.getLastString();
+ Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32);
+ xml.writeCategoryAttrib(L"name", enc);
+ enc = p->b;
+ Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32);
+ if (enc.iscaseequal(L"(null)") || enc.getValue() == NULL)
+ enc.setValue(L"");
+ xml.writeCategoryAttrib(L"value", enc);
+ xml.closeCategoryAttrib();
+ xml.popCategory();
+ }
+
+ while (xml.popCategory()) ;
+
+ strings.deleteAll();
+ fclose(fp);
+ } // fp != NULL
+ } // ninstances==0
+}
+
+int verifyName(const wchar_t *str)
+{
+ for (const wchar_t *p = str; *p; p++)
+ {
+ if (!ISALPHA(*p) &&
+ !ISDIGIT(*p) &&
+ !ISPUNCT(*p) &&
+ !ISSPACE(*p) &&
+ *p != '|' && *p != '_')
+ return 0;
+ }
+ return 1;
+}
+
+void ConfigFile::setInt(const wchar_t *name, int val)
+{
+ INCRITICALSECTION(cs);
+ if (name == NULL) return ;
+ if (!verifyName(name))
+ {
+ DebugStringW(L"illegal name given\n");
+ //__asm { int 3 };
+ return ;
+ }
+ makePair(name, StringPrintfW(val));
+}
+
+int ConfigFile::getInt(const wchar_t *name, int def_val)
+{
+ INCRITICALSECTION(cs);
+ if (name == NULL) return def_val;
+ StringPair *p = getPair(name);
+ if (p == NULL) return def_val;
+ return WTOI(p->b.getValue());
+}
+
+void ConfigFile::setString(const wchar_t *name, const wchar_t *str)
+{
+ INCRITICALSECTION(cs);
+ if (name == NULL) return ;
+ if (!verifyName(name))
+ {
+ DebugStringW(L"illegal name given\n");
+ return ;
+ }
+ if (str == NULL)
+ {
+ StringPair *p = getPair(name);
+ if (p != NULL)
+ {
+ strings.delItem(p);
+ delete p;
+ return ;
+ }
+ }
+ makePair(name, str);
+}
+
+int ConfigFile::getString(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *def_str)
+{
+ INCRITICALSECTION(cs);
+ if (name == NULL || buf == NULL) return -1;
+ if (def_str == NULL)
+ def_str = L"";
+ StringPair *p = getPair(name);
+ if (p == NULL)
+ WCSCPYN(buf, def_str, buf_len);
+ else
+ WCSCPYN(buf, p->b.getValueSafe(), buf_len);
+ return 1;
+}
+
+int ConfigFile::getStringLen(const wchar_t *name)
+{
+ INCRITICALSECTION(cs);
+ if (name == NULL) return -1;
+ StringPair *p = getPair(name);
+ if (p == NULL) return -1;
+ return wcslen(p->b.getValue());
+}
diff --git a/Src/Wasabi/api/config/config.h b/Src/Wasabi/api/config/config.h
new file mode 100644
index 00000000..0f027b61
--- /dev/null
+++ b/Src/Wasabi/api/config/config.h
@@ -0,0 +1,43 @@
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+#include <bfc/string/bfcstring.h>
+#include <bfc/pair.h>
+#include <bfc/critsec.h>
+#include <bfc/string/StringW.h>
+
+class StringPair : public Pair<StringW, StringW>
+{
+public:
+ StringPair(StringW &_a, const wchar_t *_b)
+ {
+ b=_b;
+ a.swap(_a);
+ }
+};
+
+class ConfigFile
+{
+public:
+ ConfigFile(const wchar_t *section, const wchar_t *name);
+ ~ConfigFile();
+
+ static void initialize();
+
+ void setInt(const wchar_t *name, int val);
+ int getInt(const wchar_t *name, int default_val);
+
+ void setString(const wchar_t *name, const wchar_t *str);
+ int getString(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+
+ int getStringLen(const wchar_t *name);
+
+private:
+ StringW sectionname;
+ StringW prettyname;
+ StringPair *getPair(const wchar_t *name);
+ StringPair *makePair(const wchar_t *name, const wchar_t *value);
+ CriticalSection cs;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/configapi.cpp b/Src/Wasabi/api/config/configapi.cpp
new file mode 100644
index 00000000..e66e00f8
--- /dev/null
+++ b/Src/Wasabi/api/config/configapi.cpp
@@ -0,0 +1,95 @@
+#include "precomp.h"
+#include "configapi.h"
+#include "../../studio/config.h"
+
+#include "../../studio/cfglist.h"
+
+config_api *configApi = NULL;
+
+static CfgList cfglist;
+
+void ConfigApi::config_registerCfgItem(CfgItem *cfgitem) {
+ cfglist.addItem(cfgitem);
+}
+
+void ConfigApi::config_deregisterCfgItem(CfgItem *cfgitem) {
+ cfglist.delItem(cfgitem);
+}
+
+int ConfigApi::config_getNumCfgItems() {
+ return cfglist.getNumItems();
+}
+
+CfgItem *ConfigApi::config_enumCfgItem(int n) {
+ return cfglist.enumItem(n);
+}
+
+CfgItem *ConfigApi::config_getCfgItemByGuid(GUID g) {
+ return NULL;//cfglist.getByGuid(g);
+}
+
+void ConfigApi::setIntPrivate(const char *name, int val) {
+ //config->setInt(name, val);
+}
+
+int ConfigApi::getIntPrivate(const char *name, int def_val) {
+/* int ret = config->getInt(name, def_val);
+ return ret;*/
+ return 0;
+}
+
+void ConfigApi::setIntArrayPrivate(const char *name, const int *val, int nval) {
+ /*if (nval > 256) return;
+ char buf[12*256]="";
+ for (int i = 0; i < nval; i++) {
+ STRCAT(buf, StringPrintf("%d", val[i]));
+ if (i != nval-1) STRCAT(buf, ",");
+ }
+ config->setString(name, buf);*/
+}
+
+int ConfigApi::getIntArrayPrivate(const char *name, int *val, int nval) {
+/* char buf[12*256]="";
+ config->getString(name, buf, sizeof(buf), "");
+ PathParser pp(buf, ",");
+ if (pp.getNumStrings() != nval) return 0;
+ for (int i = 0; i < nval; i++) {
+ *val = ATOI(pp.enumString(i));
+ val ++;
+ }
+ return 1;*/
+ return 1;
+}
+
+void ConfigApi::setStringPrivate(const char *name, const char *str) {
+ //config->setString(name, str);
+}
+
+int ConfigApi::getStringPrivate(const char *name, char *buf, int buf_len, const char *default_str) {
+/* int ret = config->getString(name, buf, buf_len, default_str);
+ return ret;*/
+ return 0;
+}
+
+int ConfigApi::getStringPrivateLen(const char *name) {
+ //return config->getStringLen(name);
+ return 0;
+}
+
+void ConfigApi::setIntPublic(const char *name, int val) {
+ //public_config->setInt(name, val);
+}
+
+int ConfigApi::getIntPublic(const char *name, int def_val) {
+ //return public_config->getInt(name, def_val);
+ return 0;
+}
+
+void ConfigApi::setStringPublic(const char *name, const char *str) {
+// public_config->setString(name, str);
+}
+int ConfigApi::getStringPublic(const char *name, char *buf, int buf_len, const char *default_str) {
+// return public_config->getString(name, buf, buf_len, default_str);
+ return 0;
+}
+
diff --git a/Src/Wasabi/api/config/configapi.h b/Src/Wasabi/api/config/configapi.h
new file mode 100644
index 00000000..2ea59f46
--- /dev/null
+++ b/Src/Wasabi/api/config/configapi.h
@@ -0,0 +1,32 @@
+#ifndef __CONFIG_API_H
+#define __CONFIG_API_H
+
+#include "../../bfc/api/api_configi.h"
+
+class ConfigApi : public config_apiI {
+ public:
+ ConfigApi() {}
+ virtual ~ConfigApi() {}
+
+ virtual void config_registerCfgItem(CfgItem *cfgitem);
+ virtual void config_deregisterCfgItem(CfgItem *cfgitem);
+ virtual int config_getNumCfgItems();
+ virtual CfgItem *config_enumCfgItem(int n);
+ virtual CfgItem *config_getCfgItemByGuid(GUID g);
+ virtual void setIntPrivate(const wchar_t *name, int val);
+ virtual int getIntPrivate(const wchar_t *name, int def_val);
+ virtual void setIntArrayPrivate(const wchar_t *name, const int *val, int nval);
+ virtual int getIntArrayPrivate(const wchar_t *name, int *val, int nval);
+ virtual void setStringPrivate(const wchar_t *name, const wchar_t *str);
+ virtual int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+ virtual int getStringPrivateLen(const wchar_t *name);
+ virtual void setIntPublic(const wchar_t *name, int val);
+ virtual int getIntPublic(const wchar_t *name, int def_val);
+ virtual void setStringPublic(const wchar_t *name, const wchar_t *str);
+ virtual int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str);
+
+ protected:
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/config/filetypes.cpp b/Src/Wasabi/api/config/filetypes.cpp
new file mode 100644
index 00000000..20298b99
--- /dev/null
+++ b/Src/Wasabi/api/config/filetypes.cpp
@@ -0,0 +1,576 @@
+#include "precomp.h"
+#include "filetypes.h"
+#include "api.h"
+#include "main.h"
+#include "core.h"
+
+#include <bfc/attribs/attribs.h>
+#include <bfc/attribs/attrcb.h>
+
+#include "../common/locales.h"
+#include "../bfc/paramparser.h"
+
+// {DB26AA7F-0CF4-4e48-8AC8-49F9B9855A98}
+static const GUID winampa_guid =
+{ 0xdb26aa7f, 0xcf4, 0x4e48, { 0x8a, 0xc8, 0x49, 0xf9, 0xb9, 0x85, 0x5a, 0x98 } };
+
+class Filetypes;
+
+class ExtensionAttrCallback : public AttrCallback {
+public:
+ ExtensionAttrCallback(const char *extname, Filetypes *ft) : ext(extname), filetypes(ft) {}
+ virtual void onValueChange(Attribute *attr) {
+ Filetypes::registerExtension(ext, attr->getValueAsInt());
+ api->cmd_sendCommand(winampa_guid,"extchange",0,0,attr,sizeof(attr)); // CT> notifies winampa.wac of the change
+ // (dunno if there is a better method)
+ filetypes->updateKeepers();
+ }
+private:
+ String ext;
+ Filetypes *filetypes;
+};
+
+class KeepersCB : public AttrCallback {
+public:
+ KeepersCB(CfgItemI *_par) : par(_par) { }
+ virtual void onValueChange(Attribute *attr) {
+ //CT> This is REAL SLOW, for each attribute modified, you reregister them all, this needs to have
+ // an old list and just register/unregister what's new
+ char bufero[WA_MAX_PATH]="";
+ char data[WA_MAX_PATH]="";
+ attr->getData(bufero, WA_MAX_PATH-1);
+ ParamParser pp(bufero);
+ const char *ext=api->core_getSupportedExtensions();
+ const char *p=ext;
+ while(*p!=0 && *(p+1)!=0) {
+ if(*p) {
+ int v = !!pp.hasString(p);
+ int r = par->cfgitem_getData(StringPrintf("extension/%s", p), data, WA_MAX_PATH-1);
+ if (r == 0 || (!!ATOI(data) != v)) {
+ par->cfgitem_setData(StringPrintf("extension/%s", p), StringPrintf(v));
+ }
+ }
+ while(*p!=0) p++;
+ p++;
+ }
+ }
+private:
+ CfgItemI *par;
+};
+
+#ifdef WIN32
+static void DCM_cb(int v) {
+ if (v) {
+ HKEY mp3Key;
+ char programname[MAX_PATH];
+ GetModuleFileName(Main::gethInstance(),programname,sizeof(programname));
+ if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Play",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("&Play in Winamp");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,(unsigned char*)str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Play\\command",&mp3Key) == ERROR_SUCCESS) {
+ StringPrintf mstr("\"%s\" \"%%1\"", programname);
+ const char *blah = mstr;
+ const unsigned char *microsoft_sucks_ass = (const unsigned char*)blah;
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,microsoft_sucks_ass,mstr.len() + 1);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Enqueue",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("&Enqueue in Winamp");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,(unsigned char*)str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Enqueue\\command",&mp3Key) == ERROR_SUCCESS) {
+ StringPrintf mstr("\"%s\" /ADD \"%%1\"", programname);
+ const char *blah = mstr;
+ const unsigned char *microsoft_sucks_ass = (const unsigned char*)blah;
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,microsoft_sucks_ass,mstr.len() + 1);
+ RegCloseKey(mp3Key);
+ }
+ } else {
+ Filetypes::myRegDeleteKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Play");
+ Filetypes::myRegDeleteKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Enqueue");
+ }
+}
+#endif
+
+// {C30C97E6-77E6-4da4-9F4F-C7F848F8F641}
+const GUID filetypes_guid =
+{ 0xc30c97e6, 0x77e6, 0x4da4, { 0x9f, 0x4f, 0xc7, 0xf8, 0x48, 0xf8, 0xf6, 0x41 } };
+
+Filetypes::Filetypes() : CfgItemI("Filetypes", filetypes_guid) { }
+
+void Filetypes::registerAttributes() {
+ const char *ext=api->core_getSupportedExtensions();
+ if (ext == NULL) return; //BU
+
+ _bool *wantExtensions;
+ registerAttribute(wantExtensions = new _bool("Register associations on Winamp startup", TRUE));
+
+ const char *p=ext;
+ while(*p!=0 && *(p+1)!=0) {
+ if(*p) {
+ _bool *extenabled;
+ registerAttribute(extenabled = new _bool(StringPrintf("extension/%s", p), FALSE), new ExtensionAttrCallback(p, this));
+ if (*wantExtensions) registerExtension(p, *extenabled);
+ } while(*p!=0) p++;
+ p++;
+ }
+
+ registerAttribute(new _string("keepers"), new KeepersCB(this));
+
+#ifdef WIN32
+ registerAttribute(new _bool("Directory context menus", TRUE), new int_attrCB(DCM_cb));
+#endif
+
+ // Always steal the ".wal" extension.
+ CfgItem *cift=WASABI_API_CONFIG->config_getCfgItemByGuid(filetypes_guid);
+ if (cift) {
+ cift->setDataAsInt("extension/wal",1);
+ }
+
+ updateKeepers();
+}
+
+void Filetypes::updateKeepers() {
+ static int reentry=0;
+ if (reentry) return;
+ const char *ext=api->core_getSupportedExtensions();
+ if (ext == NULL) return; //BU
+
+ reentry = 1;
+ const char *p=ext;
+ String kstr;
+ while(*p!=0 && *(p+1)!=0) {
+ if(*p) {
+ _bool *extenabled = static_cast<_bool *>(getAttributeByName(StringPrintf("extension/%s", p)));
+ if (*extenabled) {
+ if (!kstr.isempty()) kstr += ";";
+ kstr += p;
+ }
+ } while(*p!=0) p++;
+ p++;
+ }
+ _string *k = static_cast<_string *>(getAttributeByName("keepers"));
+ k->setValue(kstr);
+ reentry = 0;
+}
+
+LONG Filetypes::myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey)
+{
+#ifdef WIN32
+ HKEY key;
+ int retval=RegOpenKey(thiskey,lpSubKey,&key);
+ if (retval==ERROR_SUCCESS)
+ {
+ char buffer[1024];
+ while (RegEnumKey(key,0,buffer,1024)==ERROR_SUCCESS)
+ if ((retval=myRegDeleteKeyEx(key,buffer)) != ERROR_SUCCESS) break;
+ RegCloseKey(key);
+ retval=RegDeleteKey(thiskey,lpSubKey);
+ }
+ return retval;
+#else
+ DebugString( "portme -- Filetypes::myRegDeleteKeyEx\n" );
+ return 0;
+#endif
+}
+
+int Filetypes::isRegistered(const char *ext) {
+ char b[256];
+ int rval=0;
+ unsigned long vt,s=sizeof(b);
+ HKEY key;
+ SPRINTF(b,".%s",ext);
+#ifdef WIN32
+ if (RegOpenKey(HKEY_CLASSES_ROOT,b,&key) != ERROR_SUCCESS) return 0;
+ if (RegQueryValueEx(key,NULL,0,&vt,b,&s) == ERROR_SUCCESS) {
+ if (vt != REG_SZ || (strcmp(b,"Winamp3.File") && strcmp(b,"Winamp3.PlayList") && strcmp(b,"Winamp3.SkinZip"))) rval=0;
+ else rval=1;
+ } else rval=0;
+ RegCloseKey(key);
+#else
+DebugString( "portme -- FileTypes::isRegistered\n" );
+#endif
+ return rval;
+}
+
+void Filetypes::regmimetype(const char *mtype, const char *programname, const char *ext, int nsonly) {
+#ifdef WIN32
+ HKEY mp3Key;
+ if (!nsonly) {
+ char s[MAX_PATH];
+ // Changed these to create rather than just open the mimetypes in the database.
+ if (RegCreateKey(HKEY_CLASSES_ROOT,ext,&mp3Key) == ERROR_SUCCESS) {
+ RegSetValueEx(mp3Key,"Content Type",0,REG_SZ,mtype,STRLEN(mtype) + 1);
+ RegCloseKey(mp3Key);
+ }
+ wsprintf(s,"MIME\\Database\\Content Type\\%s",mtype);
+ if (RegCreateKey(HKEY_CLASSES_ROOT,s,&mp3Key) == ERROR_SUCCESS) {
+ RegDeleteValue(mp3Key,"CLSID");
+ RegSetValueEx(mp3Key,"Extension",0,REG_SZ,ext,strlen(ext) + 1);
+ RegCloseKey(mp3Key);
+ }
+ }
+ if (RegOpenKey(HKEY_CURRENT_USER,"Software\\Netscape\\Netscape Navigator\\Viewers",&mp3Key) == ERROR_SUCCESS) {
+ int x;
+ RegSetValueEx(mp3Key, mtype,0,REG_SZ,programname,strlen(programname) + 1);
+ for (x = 0; x < 999; x ++) {
+ char st[100];
+ DWORD vt;
+ DWORD s=128;
+ char b[128];
+ wsprintf(st,"TYPE%d",x);
+ if (RegQueryValueEx(mp3Key,st,0,&vt,b,&s) == ERROR_SUCCESS) {
+ if (!strcmp(b,mtype)) break;
+ } else {
+ RegSetValueEx(mp3Key,st,0,REG_SZ,mtype,strlen(mtype)+1);
+ break;
+ }
+ }
+ RegCloseKey(mp3Key);
+ }
+#else
+DebugString( "portme -- Filetypes::regmimetype\n" );
+#endif
+}
+
+void Filetypes::registerExtension(const char *ext, int reg) {
+#ifdef WIN32
+ createWinampTypes();
+
+ char b[128];
+ HKEY mp3Key;
+ char *which_str="Winamp3.File";
+
+ if (!_stricmp(ext,"m3u") || !_stricmp(ext,"pls")) which_str="Winamp3.PlayList";
+ if (!_stricmp(ext,"wsz") || !_stricmp(ext,"wpz") || !_stricmp(ext,"wal"))
+ which_str="Winamp3.SkinZip";
+ wsprintf(b,".%s",ext);
+ if (reg && !_stricmp(ext,"pls")) {
+ char programname[MAX_PATH];
+ GetModuleFileName(Main::gethInstance(),programname,sizeof(programname));
+ regmimetype("audio/x-scpls", programname,".pls",1);
+ regmimetype("audio/scpls", programname,".pls",1);
+ }
+ if (reg && !_stricmp(ext,"wma")) {
+ char programname[MAX_PATH];
+ GetModuleFileName(Main::gethInstance(),programname,sizeof(programname));
+ regmimetype("audio/x-ms-wma", programname,".wma",1);
+ regmimetype("application/x-msdownload", programname,".wma",1);
+ }
+ if (reg && !_stricmp(ext,"m3u")) {
+ char programname[MAX_PATH];
+ GetModuleFileName(Main::gethInstance(),programname,sizeof(programname));
+ regmimetype("audio/x-mpegurl", programname,".m3u",1);
+ regmimetype("audio/mpegurl", programname,".m3u",1);
+ }
+ if (reg && !_stricmp(ext,"mp3")) {
+ char programname[MAX_PATH];
+ GetModuleFileName(Main::gethInstance(),programname,sizeof(programname));
+ regmimetype("audio/x-mpeg", programname,".mp3",1);
+ regmimetype("audio/x-mp3", programname,".mp3",1);
+ regmimetype("audio/x-mpg", programname,".mp3",1);
+ regmimetype("audio/mp3", programname,".mp3",1);
+ regmimetype("audio/mpg", programname,".mp3",1);
+ regmimetype("audio/mpeg", programname,".mp3",1);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,b,&mp3Key) == ERROR_SUCCESS) {
+ if (reg) {
+ unsigned long s=sizeof(b);
+ if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS) {
+ if (strcmp(b,which_str)) {
+ RegSetValueEx(mp3Key,"Winamp_Back",0,REG_SZ,b,strlen(b)+1);
+ RegSetValueEx(mp3Key,NULL,0,REG_SZ,which_str,strlen(which_str)+1);
+ }
+ } else RegSetValueEx(mp3Key,NULL,0,REG_SZ,which_str,strlen(which_str)+1);
+ } else {
+ unsigned long s=sizeof(b);
+ if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS) {
+ if (!strcmp(b,which_str)) {
+ s=sizeof(b);
+ if (RegQueryValueEx(mp3Key,"Winamp_Back",0,NULL,b,&s) == ERROR_SUCCESS) {
+ if (RegSetValueEx(mp3Key, NULL,0,REG_SZ,b,strlen(b)+1) == ERROR_SUCCESS)
+ RegDeleteValue(mp3Key,"Winamp_Back");
+ } else {
+ RegDeleteValue(mp3Key,NULL);
+ RegCloseKey(mp3Key);
+ mp3Key=NULL;
+ wsprintf(b,".%s",ext);
+ myRegDeleteKeyEx(HKEY_CLASSES_ROOT,b);
+ }
+ }
+ }
+ }
+ if (mp3Key) RegCloseKey(mp3Key);
+ }
+#else
+DebugString( "portme -- Filetypes::registerExtensions\n" );
+#endif
+}
+
+void Filetypes::createWinampTypes() {
+#ifdef WIN32
+ HKEY mp3Key;
+ char programname[MAX_PATH];
+ char str[MAX_PATH+32];
+ char buf[128]="Winamp3.File";
+ char buf2[128]="Winamp3.PlayList";
+ char buf3[128]="Winamp3.SkinZip";
+ if (!GetModuleFileName(Main::gethInstance(),programname,sizeof(programname))) return;
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File",&mp3Key) == ERROR_SUCCESS) {
+ strcpy(str,"Winamp media file");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"%s,%d",programname,whichicon);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell",&mp3Key) == ERROR_SUCCESS) {
+ if (addtolist)
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Enqueue",8);
+ else
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Play",5);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Play",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("&Play in Winamp");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Play\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\open",&mp3Key) == ERROR_SUCCESS) {
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\open\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Enqueue",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("&Enqueue in Winamp");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Enqueue\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" /ADD \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\ListBookmark",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("Add to Winamp's &Bookmark list");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\ListBookmark\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" /BOOKMARK \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.Playlist",&mp3Key) == ERROR_SUCCESS) {
+ strcpy(str,"Winamp playlist file");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ str[0]=0;
+ str[1]=0;
+ str[2]=1;
+ str[3]=0;
+ RegSetValueEx(mp3Key, "EditFlags",0,REG_BINARY,str,4);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"%s,%d",programname,whichicon2);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell",&mp3Key) == ERROR_SUCCESS) {
+ if (addtolist)
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Enqueue",8);
+ else
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Play",5);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Play",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("&Play in Winamp");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Play\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\open",&mp3Key) == ERROR_SUCCESS) {
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\open\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Enqueue",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("&Enqueue in Winamp");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Enqueue\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" /ADD \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\ListBookmark",&mp3Key) == ERROR_SUCCESS) {
+ const char *str=_("Add to Winamp's &Bookmark list");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\ListBookmark\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" /BOOKMARK \"%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip",&mp3Key) == ERROR_SUCCESS) {
+ strcpy(str,"Winamp3 skin file");
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ str[0]=0;
+ str[1]=0;
+ str[2]=1;
+ str[3]=0;
+ RegSetValueEx(mp3Key, "EditFlags",0,REG_BINARY,str,4);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"%s,%d",programname,whichicon);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell",&mp3Key) == ERROR_SUCCESS) {
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Install and switch to",8);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\install",&mp3Key) == ERROR_SUCCESS) {
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\install\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" \"/installskin=%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\open",&mp3Key) == ERROR_SUCCESS) {
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1);
+ RegCloseKey(mp3Key);
+ }
+ if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\open\\command",&mp3Key) == ERROR_SUCCESS) {
+ wsprintf(str,"\"%s\" \"/installskin=%%1\"",programname);
+ RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1);
+ RegCloseKey(mp3Key);
+ }
+
+ // Register the mimetypes to act like .wal files?
+
+// regmimetype("interface/x-winamp-skin", programname,".wsz",0);
+ regmimetype("interface/x-winamp-skin", programname,".wal",0);
+// regmimetype("interface/x-winamp3-skin", programname,".wsz",0);
+ regmimetype("interface/x-winamp3-skin", programname,".wal",0);
+// regmimetype("application/x-winamp-plugin", programname,"wpz",0);
+#else
+DebugString( "portme -- Filetypes::createWinampTypes\n" );
+#endif
+}
+
+int Filetypes::isCdPlayer() {
+ int r=0;
+#ifdef WIN32
+ unsigned long s;
+ HKEY mp3Key;
+ char buf[MAX_PATH],buf2[MAX_PATH]="\"";
+ if (!GetModuleFileName(Main::gethInstance(),buf2+1,sizeof(buf2)-8)) return 0;
+ if (RegOpenKey(HKEY_CLASSES_ROOT,"AudioCD\\shell\\play\\command",&mp3Key) != ERROR_SUCCESS) return 0;
+ strcat(buf2,"\" /CDA:%1");
+ s=sizeof(buf);
+ if (RegQueryValueEx(mp3Key,NULL,0,NULL,buf,&s) == ERROR_SUCCESS)
+ {
+ if (!lstrcmpi(buf,buf2)) r=1;
+ }
+ RegCloseKey(mp3Key);
+#else
+DebugString( "portme -- Filetypes::isCdPlayer\n" );
+#endif
+ return r;
+}
+
+void Filetypes::registerCdPlayer(int reg) {
+#ifdef WIN32
+ char b[MAX_PATH];
+ char buf2[MAX_PATH]="\"";
+ HKEY mp3Key;
+ if (!GetModuleFileName(Main::gethInstance(),buf2+1,sizeof(buf2)-8)) return;
+ strcat(buf2,"\" /CDA:%1");
+ if (RegOpenKey(HKEY_CLASSES_ROOT,"AudioCD\\shell\\play\\command",&mp3Key) == ERROR_SUCCESS)
+ {
+ if (reg)
+ {
+ unsigned long s=sizeof(b);
+ if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS)
+ {
+ if (_stricmp(b,buf2))
+ {
+ char buf3[MAX_PATH];
+ unsigned long st=sizeof(buf3);
+ if (RegQueryValueEx(mp3Key,"Winamp_Back",0,NULL,buf3,&st) != ERROR_SUCCESS ||
+ _stricmp(buf3,b))
+ {
+ RegSetValueEx(mp3Key,"Winamp_Back",0,REG_SZ,b,strlen(b)+1);
+ }
+ RegSetValueEx(mp3Key,NULL,0,REG_SZ,buf2,strlen(buf2)+1);
+ }
+ } else RegSetValueEx(mp3Key,NULL,0,REG_SZ,buf2,strlen(buf2)+1);
+ }
+ else
+ {
+ unsigned long s=sizeof(b);
+ if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS)
+ {
+ if (!strcmp(b,buf2))
+ {
+ s=sizeof(b);
+ if (RegQueryValueEx(mp3Key,"Winamp_Back",0,NULL,b,&s) == ERROR_SUCCESS)
+ {
+ if (!_stricmp(b,buf2)) b[0]=0;
+ if (RegSetValueEx(mp3Key, NULL,0,REG_SZ,b,strlen(b)+1) == ERROR_SUCCESS)
+ RegDeleteValue(mp3Key,"Winamp_Back");
+ }
+ else
+ {
+ buf2[0]=0;
+ RegSetValueEx(mp3Key,NULL,0,REG_SZ,buf2,strlen(buf2)+1);
+ }
+ }
+ }
+ }
+ RegCloseKey(mp3Key);
+ }
+#else
+DebugString( "portme -- Filetypes::isCdPlayer\n" );
+#endif
+}
+
+int Filetypes::whichicon=1;
+int Filetypes::whichicon2=1;
+int Filetypes::addtolist=0;
diff --git a/Src/Wasabi/api/config/filetypes.h b/Src/Wasabi/api/config/filetypes.h
new file mode 100644
index 00000000..4d7e6891
--- /dev/null
+++ b/Src/Wasabi/api/config/filetypes.h
@@ -0,0 +1,46 @@
+#ifndef _FILETYPES_H
+#define _FILETYPES_H
+
+#include <api/config/items/cfgitemi.h>
+
+#define FILETYPES_PARENT CfgItemI
+class Filetypes : public FILETYPES_PARENT {
+public:
+ Filetypes();
+ void registerAttributes();
+
+ static int isRegistered(const char *ext);
+ static void registerExtension(const char *ext, int reg);
+ static int isCdPlayer();
+ static void registerCdPlayer(int reg);
+
+ void updateKeepers();
+
+private:
+
+ static void createWinampTypes();
+ static void regmimetype(const char *mtype, const char *programname, const char *ext, int nsonly);
+
+ // workaround for (damn) c++ type checking
+ static LONG RegQueryValueEx(HKEY hKey, LPTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, char *lpData, LPDWORD lpcbData) {
+#ifdef WIN32
+ return ::RegQueryValueEx(hKey, lpValueName, lpReserved, lpType, (unsigned char *)lpData, lpcbData);
+#endif
+ }
+ static LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, char *lpData, DWORD cbData) {
+#ifdef WIN32
+ return ::RegSetValueEx(hKey, lpValueName, Reserved, dwType, (const unsigned char *)lpData, cbData);
+#endif
+ }
+ static LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, const char *lpData, DWORD cbData) {
+#ifdef WIN32
+ return ::RegSetValueEx(hKey, lpValueName, Reserved, dwType, (const unsigned char *)lpData, cbData);
+#endif
+ }
+public:
+ static LONG myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey);
+
+ static int whichicon, whichicon2, addtolist;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrbool.h b/Src/Wasabi/api/config/items/attrbool.h
new file mode 100644
index 00000000..324a2e11
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrbool.h
@@ -0,0 +1,65 @@
+#ifndef _ATTRBOOL_H
+#define _ATTRBOOL_H
+
+#include "attribute.h"
+
+// inherit from this one, or just use it
+
+/**
+ Boolean configuration attributes have two values, true or false.
+ They can be used like any other config item.
+
+ @short Boolean configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see _int
+ @see _string
+ @see _float
+*/
+class _bool : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ _bool(const wchar_t *name=NULL, int default_val=0) : Attribute(name) {
+ setValueAsInt(!!default_val, true);
+ }
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator bool() { return !!getValueAsInt(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ bool operator =(int newval) { setValueAsInt(!!newval); return *this; }
+
+ // from Attribute
+
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::BOOL; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.bool"; }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrcb.h b/Src/Wasabi/api/config/items/attrcb.h
new file mode 100644
index 00000000..3aa0e41d
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrcb.h
@@ -0,0 +1,127 @@
+#ifndef _ATTRCB_H
+#define _ATTRCB_H
+
+#include "attribute.h"
+
+/**
+ Enables you to register callbacks on
+ a specific attribute to monitor if it's
+ value has been changed by the user or other.
+
+ This class is not meant to be used on it's own.
+ Please derive from it instead.
+
+ @short Attribute callback
+ @ver 1.0
+ @author Nullsoft
+ @see Attribute
+ @see int_attrCB
+ @see _int
+ @see _float
+ @see _string
+ @see _bool
+*/
+class AttrCallback {
+public:
+ /**
+ Does nothing.
+ */
+ virtual ~AttrCallback() {}
+
+ /**
+ Event triggered when the value of the attribute,
+ for which this callback has been registered, changes.
+
+ This is a pure virtual, please override to implement
+ your custom behavior.
+
+ @param attr Attribute for which the value has changed.
+ */
+ virtual void onValueChange(Attribute *attr)=0;
+};
+
+/**
+ Enables you to register callbacks on a specific
+ integer or boolean attribute to monitor if the
+ value has been changed by the user or other.
+
+ @short Integer or Boolean attribute Callback.
+ @ver 1.0
+ @author Nullsoft
+ @see Attribute
+ @see _int
+ @see _bool
+*/
+class int_attrCB : public AttrCallback {
+ typedef void (*fnPtrType)(int);
+public:
+ /**
+ Upon construction, you must specify which
+ function will be called when the value of
+ the attribute has indeed changed.
+
+ This is done using a pointer to the function.
+ The function must accept one parameter of type
+ int, like so: void myfunc(int val);
+
+ @param _fn Pointer to the function to use on value change.
+ */
+ int_attrCB(fnPtrType _fn) { fnptr = _fn; }
+
+ /**
+ Event triggered when the value of the attribute,
+ for which this callback has been registered, changes.
+
+ Override this to implement your own behavior.
+ The default is to send the new value of the attribute
+ to a function which you specify upon construction
+ of this object.
+
+ @param attr Attribute for which the value has changed.
+ */
+ virtual void onValueChange(Attribute *attr) {
+ ASSERT(attr->getAttributeType() == AttributeType::INT ||
+ attr->getAttributeType() == AttributeType::BOOL);
+ (*fnptr)(attr->getValueAsInt());
+ }
+private:
+ fnPtrType fnptr;
+};
+
+class string_attrCB : public AttrCallback {
+ typedef void (*fnPtrType)(const wchar_t *);
+public:
+ /**
+ Upon construction, you must specify which
+ function will be called when the value of
+ the attribute has indeed changed.
+
+ This is done using a pointer to the function.
+ The function must accept one parameter of type
+ int, like so: void myfunc(const char *val);
+
+ @param _fn Pointer to the function to use on value change.
+ */
+ string_attrCB(fnPtrType _fn) { fnptr = _fn; }
+
+ /**
+ Event triggered when the value of the attribute,
+ for which this callback has been registered, changes.
+
+ Override this to implement your own behavior.
+ The default is to send the name of the attribute
+ to a function which you specify upon construction
+ of this object.
+
+ @param attr Attribute for which the value has changed.
+ */
+ virtual void onValueChange(Attribute *attr)
+ {
+ ASSERT(attr->getAttributeType() == AttributeType::STRING);
+ (*fnptr)(attr->getAttributeName());
+ }
+private:
+ fnPtrType fnptr;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrfloat.h b/Src/Wasabi/api/config/items/attrfloat.h
new file mode 100644
index 00000000..056f0c46
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrfloat.h
@@ -0,0 +1,52 @@
+#ifndef _ATTRFLOAT_H
+#define _ATTRFLOAT_H
+
+#include "attribute.h"
+
+// actually it's a double :)
+
+class _float : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ _float(const wchar_t *name=NULL, double default_val=0.f) : Attribute(name) {
+ setValueAsDouble(default_val, true);
+ }
+
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::FLOAT; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.float"; }
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator double() { return getValueAsDouble(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ double operator =(double newval) { return setValueAsDouble(newval) ? newval : getValueAsDouble(); }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrfn.h b/Src/Wasabi/api/config/items/attrfn.h
new file mode 100644
index 00000000..54f46df0
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrfn.h
@@ -0,0 +1,15 @@
+#ifndef _ATTRFN_H
+#define _ATTRFN_H
+
+#include "attrstr.h"
+
+class _filename : public _string {
+public:
+ _filename(const wchar_t *name, const wchar_t *default_val=L"")
+ : _string(name, default_val) { }
+
+ virtual int getAttributeType() { return AttributeType::FILENAME; }
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.filename"; }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrhandler.h b/Src/Wasabi/api/config/items/attrhandler.h
new file mode 100644
index 00000000..c2624f46
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrhandler.h
@@ -0,0 +1,129 @@
+//!## An object to multiplex the callbacks of multiple attributes.
+#ifndef _ATTRHANDLER_H
+#define _ATTRHANDLER_H
+
+// This class is meant to be subclassed. The methods you must provide
+// are given as pure virtuals. See ExampleAttrib for more details, and
+// an example subclass that you can copy for your own use.
+
+#include "attrcb.h"
+#include "attribs.h"
+#include <bfc/map.h>
+
+//
+// Forward References
+class WAComponentClient;
+class Attribute;
+
+
+//
+// Class Definition
+template <class TCallback>
+class AttrHandler {
+protected:
+ // Heh, oops. Can't have one AttrCallback handle lots of different attribs, anymore. I fix.
+ class AttrHandlerChild : public AttrCallback {
+ public:
+ AttrHandlerChild(AttrHandler *_parent) : AttrCallback() {
+ ASSERT(_parent != NULL);
+ recursion = 0;
+ callback = NULL;
+ parent = _parent;
+ }
+
+ // Here is where we split out the different value types
+ virtual void onValueChange(Attribute *attr) {
+ if (!recursion) {
+ // protect our programmers from stack overflow, please.
+ recursion = 1;
+ if ((callback != NULL) && (parent != NULL)) {
+ int id;
+ // find the id from the map (friendly)
+ int success = parent->attribmap.getItem(attr,&id);
+ if (success) {
+ // and send it to the proper handling function (poorman's RTTI)
+ switch (attr->getAttributeType()) {
+ case AttributeType::INT:
+ callback->onIntChange(id,*static_cast<_int *>(attr));
+ break;
+ case AttributeType::BOOL:
+ callback->onBoolChange(id, *static_cast<_bool *>(attr));
+ break;
+ case AttributeType::FLOAT:
+ callback->onFloatChange(id, *static_cast<_float *>(attr));
+ break;
+ case AttributeType::STRING:
+ callback->onStringChange(id, *static_cast<_string *>(attr));
+ break;
+ }
+ }
+ }
+ recursion = 0;
+ }
+ }
+
+ virtual void bindCallbackObj(TCallback *callbackobj) {
+ // Be advised, this may be null. That's okay, we test for it above.
+ callback = callbackobj;
+ }
+ private:
+ int recursion;
+ TCallback *callback;
+ AttrHandler *parent;
+ };
+
+public:
+ AttrHandler() {
+ component = NULL;
+ callback = NULL;
+ }
+
+ // Call this method to bind your component (in your component's constructor)
+ virtual void bindComponent(WAComponentClient *parentcomponent) {
+ component = parentcomponent;
+ }
+
+ // Call this method to bind your callback object (usually your window in its constructor)
+ virtual void bindCallbackObj(TCallback *callbackobj) {
+ // Bind ourselves.
+ callback = callbackobj;
+
+ // Then go through and rebind any children.
+ int i, num = attrchildren.getNumItems();
+ for (i = 0; i < num; i++) {
+ AttrHandlerChild *child = attrchildren.enumItem(i);
+ child->bindCallbackObj(callback);
+ }
+ }
+
+ // Call this method to register each attribute.
+ virtual void registerAttribute(Attribute *attr, int id) {
+ ASSERTPR(component != NULL, "BIND YOUR COMPONENT before registering Attributes to a Handler.");
+ // register the attrib with a child object as its callback
+ AttrHandlerChild *child = new AttrHandlerChild(this);
+ attrchildren.addItem(child);
+ component->registerAttribute(attr, child);
+ // and save its id mapping
+ attribmap.addItem(attr, id);
+ }
+
+#if 0
+ // Your callback object (probably your primary window class) must implement
+ // its own versions of these methods here. They will be called by the
+ // switch statement below.
+ virtual void onIntChange(int id, int *attr);
+ virtual void onBoolChange(int id, bool *attr);
+ virtual void onFloatChange(int id, double *attr);
+ virtual void onStringChange(int id, const char *attr);
+#endif
+
+
+private:
+ friend AttrHandlerChild;
+ TCallback *callback;
+ WAComponentClient *component;
+ Map< Attribute *, int > attribmap;
+ PtrList<AttrHandlerChild> attrchildren;
+};
+
+#endif // _ATTRHANDLER_H
diff --git a/Src/Wasabi/api/config/items/attribs.h b/Src/Wasabi/api/config/items/attribs.h
new file mode 100644
index 00000000..1e35f78b
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attribs.h
@@ -0,0 +1,12 @@
+#ifndef _ATTRIBS_H
+#define _ATTRIBS_H
+
+// a convenience header to get all the attrib types in one whack
+
+#include "attrbool.h"
+#include "attrfloat.h"
+#include "attrint.h"
+#include "attrstr.h"
+#include "attrfn.h"
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attribute.cpp b/Src/Wasabi/api/config/items/attribute.cpp
new file mode 100644
index 00000000..27b519b6
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attribute.cpp
@@ -0,0 +1,131 @@
+#include <precomp.h>
+
+#include "attribute.h"
+#include <api/config/items/cfgitemi.h>
+
+
+Attribute::Attribute(const wchar_t *newname, const wchar_t *_desc) :
+ NamedW(newname), desc(_desc), cfgitemi(NULL), private_storage(NULL) { }
+
+Attribute::~Attribute() {
+ delete private_storage;
+}
+
+const wchar_t *Attribute::getAttributeName() {
+ return NamedW::getName();
+}
+
+const wchar_t *Attribute::getAttributeDesc() {
+ return desc;
+}
+
+int Attribute::getValueAsInt()
+{
+ wchar_t buf[1024]=L"";
+ getData(buf, 1024);
+ return WTOI(buf);
+}
+
+int Attribute::setValueAsInt(int newval, bool def)
+{
+ return setData(StringPrintfW(newval), def);
+}
+
+double Attribute::getValueAsDouble()
+{
+ wchar_t buf[1024] = {0};
+ getData(buf, 1024);
+ return WTOF(buf);
+}
+
+double Attribute::setValueAsDouble(double newval, bool def)
+{
+ return setData(StringPrintfW(newval), def);
+}
+
+int Attribute::getDataLen() {
+ if (private_storage != NULL)
+ return (int)private_storage->len()+1;
+
+ ASSERTPR(WASABI_API_CONFIG != NULL, "getDataLen() before API");
+ int r = WASABI_API_CONFIG->getStringPrivateLen(mkTag());
+ if (r < 0) {
+ r = (int)default_val.len()+1;
+ }
+ return r;
+}
+
+int Attribute::getData(wchar_t *data, int data_len)
+{
+ if (data == NULL || data_len < 0)
+ return 0;
+ if (private_storage != NULL)
+ {
+ if (private_storage->isempty())
+ {
+ if (data_len >= 1) {
+ *data = 0;
+ return 1;
+ }
+ return 0;
+ }
+ WCSCPYN(data, private_storage->getValue(), data_len);
+ return MIN((int)private_storage->len(), data_len);
+ }
+ ASSERTPR(WASABI_API_CONFIG != NULL, "can't get without api");
+ if (WASABI_API_CONFIG == NULL) return 0;
+ int r = WASABI_API_CONFIG->getStringPrivate(mkTag(), data, data_len, default_val.isempty() ? L"" : default_val.getValue());
+ return r;
+}
+
+int Attribute::setData(const wchar_t *data, bool def)
+{
+ if (def) { // setting default value
+ default_val = data;
+ return 1;
+ }
+ ASSERTPR(WASABI_API_CONFIG != NULL, "can't set data before api");
+ if (WASABI_API_CONFIG == NULL) return 0;
+
+ int r = setDataNoCB(data);
+ if (r && cfgitemi != NULL) cfgitemi->cfgitem_onAttribSetValue(this);
+ return r;
+}
+
+int Attribute::setDataNoCB(const wchar_t *data)
+{
+ if (private_storage != NULL) {
+ private_storage->setValue(data);
+ } else {
+ WASABI_API_CONFIG->setStringPrivate(mkTag(), data);
+ }
+ dependent_sendEvent(Attribute::depend_getClassGuid(), Event_DATACHANGE);
+ return 1;
+}
+
+void Attribute::setCfgItem(CfgItemI *item)
+{
+ delete private_storage; private_storage = NULL;
+ ASSERT(cfgitemi == NULL || item == NULL);
+ cfgitemi = item;
+ if (cfgitemi != NULL)
+ {
+ if (cfgitemi->cfgitem_usePrivateStorage())
+ private_storage = new StringW;
+ }
+}
+
+StringW Attribute::mkTag()
+{
+ StringW ret;
+ if (cfgitemi)
+ {
+ ret = cfgitemi->cfgitem_getPrefix();
+ }
+ ret.cat(getName());
+ return ret;
+}
+
+void Attribute::disconnect() {
+ setCfgItem(NULL);
+}
diff --git a/Src/Wasabi/api/config/items/attribute.h b/Src/Wasabi/api/config/items/attribute.h
new file mode 100644
index 00000000..c91e8065
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attribute.h
@@ -0,0 +1,218 @@
+#ifndef _ATTRIBUTE_H
+#define _ATTRIBUTE_H
+
+#include <bfc/depend.h>
+#include <bfc/named.h>
+#include <bfc/common.h>
+#include <bfc/string/StringW.h>
+
+class CfgItemI;
+
+// lowercase types are reserved for official Nullsoft use
+// uppercase are 3rd-party defined
+namespace AttributeType {
+ /**
+ Attribute types.
+ */
+ enum {
+ NONE = 0,
+ INT = MK3CC('i','n','t'), // attrint.h
+ STRING = MK3CC('s','t','r'), // attrstr.h
+ BOOL = MK4CC('b','o','o','l'), // attrbool.h
+ FLOAT = MK4CC('f','l','o','t'), // attrfloat.h
+ FILENAME = MK2CC('f','n'), // attrfn.h
+ };
+};
+
+/**
+ Generic configuration attribute.
+
+ Configuration attributes enable you to store
+ uniquely identifiable values that get pushed
+ to a configuration file automatically upon shutdown
+ of any Wasabi application.
+
+ You shouldn't normally use this on
+ it's own, look at the CfgItemI class
+ instead.
+
+ @short Generic configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see _float
+ @see _int
+ @see _bool
+ @see _string
+ @see CfgItemI
+*/
+class NOVTABLE Attribute : public DependentI, private NamedW
+{
+public:
+ static const GUID *depend_getClassGuid() {
+ // {5AB601D4-1628-4604-808A-7ED899849BEB}
+ static const GUID ret =
+ { 0x5ab601d4, 0x1628, 0x4604, { 0x80, 0x8a, 0x7e, 0xd8, 0x99, 0x84, 0x9b, 0xeb } };
+ return &ret;
+ }
+protected:
+
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ Attribute(const wchar_t *name=NULL, const wchar_t *desc=NULL);
+
+public:
+ virtual ~Attribute();
+
+ /**
+ Set the name of the configuration
+ attribute.
+
+ @param newname Name of the attribute.
+ */
+ void setName(const wchar_t *newname);
+
+ /**
+ Get the name of the configuration
+ attribute.
+
+ @ret Name of the attribute.
+ */
+ const wchar_t *getAttributeName();
+
+ /**
+ Get the attribute's description.
+
+ @ret Attribute's description.
+ */
+ const wchar_t *getAttributeDesc();
+
+ /**
+ Get the attribute type. Override
+ this for your custom attribute type.
+
+ @ret Attribute type.
+ */
+ virtual int getAttributeType()=0; // override me
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ This is only called if the kernel doesn't have a default
+ config group set for your type already.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return NULL; } // override me
+
+ /**
+ Get the attribute's value as signed integer.
+
+ @ret Attribute value, as a signed integer.
+ */
+ int getValueAsInt();
+
+ /**
+ Set the attribute's value with a signed integer while
+ also being able to replace the default value previously
+ set.
+
+ @param newval Attribute's new value.
+ @param def true, replace the current default value; false, leave the default value unchanged;
+ */
+ int setValueAsInt(int newval, bool def=false);
+
+ /**
+ Get the attribute's value as signed double.
+
+ @ret Attribute value, as a signed double.
+ */
+ double getValueAsDouble();
+
+ /**
+ Set the attribute's value with a signed double while
+ also being able to replace the default value previously
+ set.
+
+ @param newval Attribute's new value.
+ @param def true, replace the current default value; false, leave the default value unchanged;
+ */
+ double setValueAsDouble(double newval, bool def=false);
+
+ /**
+ Get the length of the attribute's value (data)
+ in bytes.
+
+ @ret Attribute value (data) length, in bytes.
+ */
+ int getDataLen();
+
+ /**
+ Get the attribute's raw data.
+
+ This will return the data the attribute is storing
+ in a char buffer you hand to it.
+
+ @ret Attribute value, as a signed double.
+ @param data Pointer to a char buffer.
+ @param data_len The maximum amount of bytes the char buffer can hold.
+ */
+ int getData(wchar_t *data, int data_len);
+
+ /**
+ Set the attribute's value with a zero terminated string. Also
+ enables you to replace the default value previously
+ set.
+
+ @param newval Attribute's new value.
+ @param def true, replace the current default value; false, leave the default value unchanged;
+ */
+ int setData(const wchar_t *data, bool def=false);
+
+ void disconnect();
+
+ enum {
+ Event_DATACHANGE=100,
+ };
+protected:
+ friend class CfgItemI;
+
+ /**
+ Set the attribute's value without causing
+ a callback.
+
+ @ret 1.
+ @param data Attribute's new value.
+ */
+ int setDataNoCB(const wchar_t *data);
+
+ /**
+ Set the configuration item associated with this
+ attribute.
+ */
+ void setCfgItem(CfgItemI *item);
+
+ StringW mkTag();
+
+private:
+ StringW desc;
+ StringW default_val, *private_storage;
+ CfgItemI *cfgitemi;
+};
+
+#define ATTR_PERM_READ 1
+#define ATTR_PERM_WRITE 2
+
+#define ATTR_PERM_ALL (~0)
+
+// render hints for getRenderHint
+enum {
+ ATTR_RENDER_HINT_INT_CHECKMARK
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrint.h b/Src/Wasabi/api/config/items/attrint.h
new file mode 100644
index 00000000..c63af8ce
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrint.h
@@ -0,0 +1,65 @@
+#ifndef _ATTRINT_H
+#define _ATTRINT_H
+
+#include "attribute.h"
+
+// inherit from this one, or just use it
+/**
+ Boolean configuration attributes have two values, true or false.
+ They can be used like any other config item.
+
+ @short Integer configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see CfgItemI
+ @see _bool
+ @see _string
+ @see _float
+*/
+class _int : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ _int(const wchar_t *name=NULL, int default_val=0) : Attribute(name) {
+ setValueAsInt(default_val, true);
+ }
+
+ // from AttributeI
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::INT; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.int"; }
+// virtual int getPermissions();
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator int() { return getValueAsInt(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ int operator =(int newval) { return setValueAsInt(newval) ? newval : getValueAsInt(); }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrstr.cpp b/Src/Wasabi/api/config/items/attrstr.cpp
new file mode 100644
index 00000000..1209e2f3
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrstr.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+#include "attrstr.h"
+
+#include <bfc/memblock.h>
+
+const wchar_t *_string::getValue()
+{
+ int l = getDataLen();
+ if (l <= 0) return L"";
+ MemBlock<wchar_t> mb(l+2);
+ getData(mb.getMemory(), l+2);
+ returnval = mb;
+ return returnval;
+}
diff --git a/Src/Wasabi/api/config/items/attrstr.h b/Src/Wasabi/api/config/items/attrstr.h
new file mode 100644
index 00000000..cde81a64
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrstr.h
@@ -0,0 +1,85 @@
+#ifndef _ATTRSTR_H
+#define _ATTRSTR_H
+
+#include "attribute.h"
+
+#include <bfc/string/bfcstring.h>
+#include <bfc/common.h>
+
+/**
+ String configuration attributes, can have any string value
+ of any length. They can be used like any other config item.
+
+ @short String configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see _int
+ @see _bool
+ @see _float
+*/
+class _string : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name
+ @param default_val
+ */
+ _string(const wchar_t *name=NULL, const wchar_t *default_val=NULL)
+ : Attribute(name) {
+ setData(default_val, true);
+ }
+
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::STRING; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.string"; }
+
+//CUT virtual int getPermissions() { return ATTR_PERM_ALL; }
+
+ /**
+ Get the value of the attribute.
+
+ @ret The value of the attribute
+ */
+ const wchar_t *getValue();
+
+ /**
+ Set the value of the attribute.
+
+ @param val The value you want to set.
+ @ret 1, success; 0, failure;
+ */
+ int setValue(const wchar_t *val) { return setData(val); }
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator const wchar_t *() { return getValue(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ const wchar_t *operator =(const wchar_t *newval) { return setValue(newval) ? newval : getValue(); }
+
+private:
+ StringW returnval;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/cfgitem.h b/Src/Wasabi/api/config/items/cfgitem.h
new file mode 100644
index 00000000..560198f0
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitem.h
@@ -0,0 +1,233 @@
+#ifndef _CFGITEM_H
+#define _CFGITEM_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include <bfc/platform/guid.h>
+#include <bfc/wasabi_std.h>
+
+class ifc_dependent;
+class ifc_window;
+
+/* A CfgItem is a named, possibly unique (if GUID is set) interface to
+an object with 0 or more named attributes. If offers api_dependent-based callbacks
+when those attributes change.
+*/
+
+// abstract base class presented to the world
+/**
+
+
+ @short Base Config Item
+ @ver 1.0
+ @author Nullsoft
+ @see CfgItemI
+*/
+class NOVTABLE CfgItem : public Dispatchable
+{
+public:
+ /**
+ */
+ static const GUID *depend_getClassGuid() {
+ // {B4BE480E-2005-457c-A445-294F12387E74}
+ static const GUID ret =
+ { 0xb4be480e, 0x2005, 0x457c, { 0xa4, 0x45, 0x29, 0x4f, 0x12, 0x38, 0x7e, 0x74 } };
+ return &ret;
+ }
+
+ const wchar_t *getName();
+
+ /**
+ Get the GUID
+ */
+ GUID getGuid();
+
+ /**
+ Get the number of attributes
+ associated with this configuration
+ item.
+
+ @ret Number of attributes for this configuration item.
+ */
+ int getNumAttributes();
+
+ const wchar_t *enumAttribute(int n);
+
+ // so people can watch you for changes
+ ifc_dependent *getDependencyPtr();
+
+ // return * to your config xml if you want to specify it
+ const wchar_t *getConfigXML();
+ void onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname=NULL);
+ void onCfgGroupDelete(ifc_window *cfggroup);
+
+ // if you have child cfgitems, list them here
+ int getNumChildren();
+ CfgItem *enumChild(int n);
+ GUID getParentGuid();
+
+ void onRegister(); // kernel calls these
+ void onDeregister();
+
+ int getAttributeType(const wchar_t *name);
+ const wchar_t *getAttributeConfigGroup(const wchar_t *name);
+ int getDataLen(const wchar_t *name);
+ int getData(const wchar_t *name, wchar_t *data, int data_len);
+ int setData(const wchar_t *name, const wchar_t *data);
+
+ int getDataAsInt(const wchar_t *name, int def_val=0)
+ {
+ wchar_t buf[256];
+ if (getData(name, buf, sizeof(buf))==-1) return def_val;
+ return WTOI(buf);
+ }
+ void setDataAsInt(const wchar_t *name, int val) {
+ wchar_t buf[256];
+ WCSNPRINTF(buf, 256, L"%d", val); // this uses SPRINTF ON PURPOSE, motherfucker BU
+ setData(name, buf);
+ }
+
+ double getDataAsFloat(const wchar_t *name, double def_val=0) {
+ wchar_t buf[256];
+ if (getData(name, buf, sizeof(buf))==-1) return def_val;
+ return WTOF(buf);
+ }
+ void setDataAsFloat(const wchar_t *name, double val) {
+ wchar_t buf[256];
+ WCSNPRINTF(buf, 256, L"%f", val); // this uses SPRINTF ON PURPOSE, motherfucker BU
+ setData(name, buf);
+ }
+
+ int addAttribute(const wchar_t *name, const wchar_t *defval);
+ int delAttribute(const wchar_t *name);
+
+ enum {
+ Event_ATTRIBUTE_ADDED=100, // ptr is name of attrib
+ Event_ATTRIBUTE_REMOVED=200,// ptr is name of attrib
+ Event_ATTRIBUTE_CHANGED=300, // ptr is name of attrib
+ Event_NAMECHANGE=400,
+ };
+
+protected:
+ enum {
+ CFGITEM_GETNAME=100,
+ CFGITEM_GETGUID=110,
+ CFGITEM_GETNUMATTRIBUTES=200,
+ CFGITEM_ENUMATTRIBUTE=210,
+ CFGITEM_GETDEPENDENCYPTR=300,
+ CFGITEM_GETNUMCHILDREN=400,
+ CFGITEM_ENUMCHILD=410,
+ CFGITEM_GETPARENTGUID=420,
+ CFGITEM_ONREGISTER=500,
+ CFGITEM_ONDEREGISTER=510,
+ CFGITEM_GETCONFIGXML=600,
+ CFGITEM_ONCFGGROUPCREATE=610,
+ CFGITEM_ONCFGGROUPDELETE=620,
+ CFGITEM_GETATTRIBUTETYPE=700,
+ CFGITEM_GETATTRIBUTECONFIGGROUP=710,
+ CFGITEM_GETDATALEN=800,
+ CFGITEM_GETDATA=810,
+ CFGITEM_SETDATA=820,
+ CFGITEM_ADDATTRIB=830,
+ CFGITEM_DELATTRIB=840,
+ };
+};
+
+inline const wchar_t *CfgItem::getName() {
+ return _call(CFGITEM_GETNAME, L"");
+}
+
+inline GUID CfgItem::getGuid() {
+ return _call(CFGITEM_GETGUID, INVALID_GUID);
+}
+
+inline int CfgItem::getNumAttributes() {
+ return _call(CFGITEM_GETNUMATTRIBUTES, 0);
+}
+
+inline const wchar_t *CfgItem::enumAttribute(int n) {
+ return _call(CFGITEM_ENUMATTRIBUTE, (const wchar_t *)NULL, n);
+}
+
+inline ifc_dependent *CfgItem::getDependencyPtr() {
+ return _call(CFGITEM_GETDEPENDENCYPTR, (ifc_dependent*)NULL);
+}
+
+inline const wchar_t *CfgItem::getConfigXML() {
+ return _call(CFGITEM_GETCONFIGXML, (const wchar_t*)NULL);
+}
+
+inline void CfgItem::onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname) {
+ _voidcall(CFGITEM_ONCFGGROUPCREATE, cfggroup, attrname);
+}
+
+inline void CfgItem::onCfgGroupDelete(ifc_window *cfggroup) {
+ _voidcall(CFGITEM_ONCFGGROUPDELETE, cfggroup);
+}
+
+inline int CfgItem::getNumChildren() {
+ return _call(CFGITEM_GETNUMCHILDREN, 0);
+}
+
+inline CfgItem *CfgItem::enumChild(int n) {
+ return _call(CFGITEM_ENUMCHILD, (CfgItem*)NULL, n);
+}
+
+inline
+GUID CfgItem::getParentGuid() {
+ return _call(CFGITEM_GETPARENTGUID, INVALID_GUID);
+}
+
+inline void CfgItem::onRegister() { _voidcall(CFGITEM_ONREGISTER); }
+inline void CfgItem::onDeregister() { _voidcall(CFGITEM_ONDEREGISTER); }
+
+inline
+int CfgItem::getAttributeType(const wchar_t *name) {
+ return _call(CFGITEM_GETATTRIBUTETYPE, 0, name);
+}
+
+inline
+const wchar_t *CfgItem::getAttributeConfigGroup(const wchar_t *name) {
+ return _call(CFGITEM_GETATTRIBUTECONFIGGROUP, (const wchar_t *)NULL, name);
+}
+
+inline
+int CfgItem::getDataLen(const wchar_t *name) {
+ return _call(CFGITEM_GETDATALEN, -1, name);
+}
+
+inline
+int CfgItem::getData(const wchar_t *name, wchar_t *data, int data_len) {
+ return _call(CFGITEM_GETDATA, -1, name, data, data_len);
+}
+
+inline
+int CfgItem::setData(const wchar_t *name, const wchar_t *data) {
+ return _call(CFGITEM_SETDATA, -1, name, data);
+}
+
+inline
+int CfgItem::addAttribute(const wchar_t *name, const wchar_t *defval) {
+ return _call(CFGITEM_ADDATTRIB, 0, name, defval);
+}
+
+inline
+int CfgItem::delAttribute(const wchar_t *name) {
+ return _call(CFGITEM_DELATTRIB, 0, name);
+}
+
+inline int _intVal(CfgItem *cfgitem, const wchar_t *name, int def_val=0) {
+ if (cfgitem == NULL) return def_val;
+ return cfgitem->getDataAsInt(name, def_val);
+}
+
+#define _int_getValue _intVal
+
+//CUT kill these
+inline void _int_setValue(CfgItem *cfgitem, const wchar_t *name, int val) {
+ cfgitem->setDataAsInt(name, val);
+}
+// CfgItemI is in cfgitemi.h if you need it
+
+
+#endif
diff --git a/Src/Wasabi/api/config/items/cfgitemi.cpp b/Src/Wasabi/api/config/items/cfgitemi.cpp
new file mode 100644
index 00000000..b8734031
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemi.cpp
@@ -0,0 +1,274 @@
+#include <precomp.h>
+
+#include "cfgitemi.h"
+#include <api/config/items/attrcb.h>
+#include <api/config/items/attribs.h>
+
+#include <bfc/wasabi_std.h>
+#include <bfc/memblock.h>
+
+CfgItemI::CfgItemI(const wchar_t *name, GUID guid)
+:NamedW(name), myguid(guid), parent_guid(INVALID_GUID) { }
+
+CfgItemI::~CfgItemI()
+{
+ deregisterAll();
+}
+
+const wchar_t *CfgItemI::cfgitem_getName()
+{
+ return NamedW::getName();
+}
+
+GUID CfgItemI::cfgitem_getGuid()
+{
+ return myguid;
+}
+
+void CfgItemI::cfgitem_setPrefix(const wchar_t *_prefix)
+{
+ prefix = _prefix;
+}
+
+const wchar_t *CfgItemI::cfgitem_getPrefix()
+{
+ return prefix.c_str();
+}
+
+int CfgItemI::cfgitem_getNumAttributes()
+{
+ return attributes.getNumItems();
+}
+
+const wchar_t *CfgItemI::cfgitem_enumAttribute(int n)
+{
+ Attribute *attr = attributes[n];
+ if (attr) return attr->getAttributeName();
+ return NULL;
+}
+
+const wchar_t *CfgItemI::cfgitem_getConfigXML()
+{
+ return cfgxml.c_str();
+}
+
+int CfgItemI::cfgitem_getNumChildren()
+{
+ return children.getNumItems();
+}
+
+CfgItem *CfgItemI::cfgitem_enumChild(int n)
+{
+ return children[n];
+}
+
+GUID CfgItemI::cfgitem_getParentGuid()
+{
+ return parent_guid;
+}
+
+void CfgItemI::cfgitem_onRegister()
+{
+ foreach(children)
+ WASABI_API_CONFIG->config_registerCfgItem(children.getfor());
+ endfor
+}
+void CfgItemI::cfgitem_onDeregister()
+{
+ foreach(children)
+ WASABI_API_CONFIG->config_deregisterCfgItem(children.getfor());
+ endfor
+}
+
+Attribute *CfgItemI::getAttributeByName(const wchar_t *name)
+{
+ Attribute *attr;
+ foreach(attributes)
+ attr = attributes.getfor();
+ if (!WCSICMP(name, attr->getAttributeName())) return attr;
+ endfor
+ return NULL;
+}
+
+int CfgItemI::cfgitem_getAttributeType(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return AttributeType::NONE;
+ return attr->getAttributeType();
+}
+
+const wchar_t *CfgItemI::cfgitem_getAttributeConfigGroup(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return NULL;
+ return attr->getConfigGroup();
+}
+
+int CfgItemI::cfgitem_getDataLen(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return -1;
+ return attr->getDataLen();
+}
+
+int CfgItemI::cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return -1;
+ return attr->getData(data, data_len);
+}
+
+int CfgItemI::cfgitem_setData(const wchar_t *name, const wchar_t *data)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return -1;
+ int ret = attr->setDataNoCB(data);
+ if (ret) cfgitem_onAttribSetValue(attr);
+ return ret;
+}
+
+int CfgItemI::cfgitem_onAttribSetValue(Attribute *attr)
+{
+ // notify dependency watchers that an attribute changed
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_CHANGED, 0, (void*)attr->getAttributeName());
+
+ //for (int i = 0; ; i++)
+ //{
+ // AttrCallback *acb;
+ // if (!callbacks.multiGetItem(attr, i, &acb))
+ // break;
+ //
+ // acb->onValueChange(attr);
+ //}
+ auto elements = callbacks.equal_range(attr);
+ for (auto& it = elements.first; it != elements.second; ++it)
+ {
+ AttrCallback* acb = it->second;
+ if (acb)
+ {
+ acb->onValueChange(attr);
+ }
+ }
+
+ return 0;
+}
+
+void CfgItemI::cfgitem_setGUID(GUID guid)
+{
+ myguid = guid;
+}
+
+int CfgItemI::setName(const wchar_t *name)
+{
+ NamedW::setName(name);
+ // notify dependency watchers that name changed?
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_NAMECHANGE);
+ return 1;
+}
+
+int CfgItemI::registerAttribute(Attribute *attr, AttrCallback *acb)
+{
+ if (attributes.haveItem(attr)) return 0;
+ int ret = attributes.addItem(attr) != NULL;
+ if (!ret) return ret;
+
+ attr->setCfgItem(this);
+
+ // set optional callback
+ if (acb != NULL)
+ {
+ addCallback(attr, acb);
+ }
+
+ // notify dependency watchers of new attribute
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_ADDED, 0, (void*)attr->getAttributeName());
+
+ return ret;
+}
+
+int CfgItemI::deregisterAttribute(Attribute *attr)
+{
+ if (!attributes.haveItem(attr)) return 0;
+ int ret = attributes.removeItem(attr);
+ // notify dependency watchers of attribute going away
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_REMOVED, 0, (void*)attr->getAttributeName());
+
+ // remove callbacks
+ //callbacks.multiDelAllForItem(attr, TRUE);
+ auto elements = callbacks.equal_range(attr);
+ for (auto& it = elements.first; it != elements.second; ++it)
+ {
+ AttrCallback* acb = it->second;
+ if (acb)
+ {
+ delete acb;
+ }
+ }
+ callbacks.erase(attr);
+
+
+ attr->disconnect();
+
+ return ret;
+}
+
+void CfgItemI::addCallback(Attribute *attr, AttrCallback *acb)
+{
+ ASSERT(attr != NULL);
+ ASSERT(acb != NULL);
+ //callbacks.multiAddItem(attr, acb);
+ callbacks.insert({ attr, acb });
+}
+
+void CfgItemI::deregisterAll()
+{
+ foreach(children)
+ children.getfor()->deregisterAll();
+ endfor
+ while (attributes.getNumItems()) deregisterAttribute(attributes[0]);
+}
+
+void CfgItemI::addChildItem(CfgItemI *child)
+{
+ ASSERT(child != NULL);
+ if (!children.haveItem(child))
+ {
+ children.addItem(child);
+ child->setParentGuid(myguid);
+ }
+}
+
+void CfgItemI::setCfgXml(const wchar_t *groupname)
+{
+ cfgxml = groupname;
+}
+
+void CfgItemI::setParentGuid(GUID guid)
+{
+ parent_guid = guid;
+}
+
+void *CfgItemI::dependent_getInterface(const GUID *classguid)
+{
+ HANDLEGETINTERFACE(CfgItem);
+ return NULL;
+}
+
+int CfgItemI::cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval)
+{
+ if (getAttributeByName(name)) return 0;
+ registerAttribute(newattribs.addItem(new _string(name, defval)));
+ return 1;
+}
+
+int CfgItemI::cfgitem_delAttribute(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (!newattribs.haveItem(attr)) return 0;
+ deregisterAttribute(attr);
+ delete attr;
+ newattribs.removeItem(attr);
+ return 1;
+}
+
+
diff --git a/Src/Wasabi/api/config/items/cfgitemi.h b/Src/Wasabi/api/config/items/cfgitemi.h
new file mode 100644
index 00000000..7824abf5
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemi.h
@@ -0,0 +1,158 @@
+#ifndef _CFGITEMI_H
+#define _CFGITEMI_H
+
+#include "cfgitemx.h"
+
+#include <bfc/named.h>
+#include <bfc/ptrlist.h>
+#include <bfc/depend.h>
+
+#include <map>
+#include <string>
+
+class AttrCallback;
+class Attribute;
+
+// this is the one you inherit from/use
+/**
+
+ @short Configuration Item
+ @ver 1.0
+ @author Nullsoft
+ @see Attribute
+ @see _bool
+ @see _int
+ @see _float
+ @see _string
+*/
+class CfgItemI : public CfgItemX, public DependentI, private NamedW
+{
+public:
+ /**
+ Optionally sets the name and the GUID of the
+ configuration item if they are specified
+ upon creation of the object.
+
+ @param name Name of the configuration item.
+ @param guid GUID of the configuration item.
+ */
+ CfgItemI(const wchar_t *name=NULL, GUID guid=INVALID_GUID);
+
+ /**
+ Does nothing.
+ */
+ virtual ~CfgItemI();
+
+ /**
+ Get the name of the configuration item.
+
+ @ret Name of the configuration item.
+ */
+ const wchar_t *cfgitem_getName();
+
+ /**
+ Get the GUID of the configuration item.
+
+ @ret GUID of the configuration item.
+ */
+ GUID cfgitem_getGuid();
+
+ /**
+ Sets the prefix to be prepended in the config file for all attributes
+ of this item.
+
+ @see cfgitem_getPrefix
+ @param prefix The prefix.
+ */
+ void cfgitem_setPrefix(const wchar_t *prefix);
+/**
+ Gets the config prefix, if any was set.
+
+ @see cfgitem_setPrefix
+ @ret Pointer to the config prefix.
+*/
+ const wchar_t *cfgitem_getPrefix();
+
+ /**
+ Get the number of attributes registered
+ to this configuration item.
+
+ @ret Number of attributes.
+ */
+ int cfgitem_getNumAttributes();
+
+ /**
+ Enumerate the attributes registered
+ with this configuration item.
+
+ @ret
+ */
+ const wchar_t *cfgitem_enumAttribute(int n);
+
+ const wchar_t *cfgitem_getConfigXML();
+ virtual void cfgitem_onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname) {}
+ virtual void cfgitem_onCfgGroupDelete(ifc_window *cfggroup) {}
+
+ virtual int cfgitem_getNumChildren();
+ virtual CfgItem *cfgitem_enumChild(int n);
+ virtual GUID cfgitem_getParentGuid();
+
+ virtual void cfgitem_onRegister();
+ virtual void cfgitem_onDeregister();
+
+ int cfgitem_getAttributeType(const wchar_t *name);
+ const wchar_t *cfgitem_getAttributeConfigGroup(const wchar_t *name);
+ int cfgitem_getDataLen(const wchar_t *name);
+ int cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len);
+ int cfgitem_setData(const wchar_t *name, const wchar_t *data);
+
+ // override these to catch notifications from attribs, call down
+ virtual int cfgitem_onAttribSetValue(Attribute *attr);
+
+ virtual int cfgitem_usePrivateStorage() { return 0; } //override and return 1 to keep stuff out of system settings
+
+protected:
+ void cfgitem_setGUID(GUID guid);
+
+public:
+ int setName(const wchar_t *name);
+ int registerAttribute(Attribute *attr, AttrCallback *acb=NULL);
+ // does not call delete on the attribute
+ int deregisterAttribute(Attribute *attr);
+ void deregisterAll();
+
+ void addCallback(Attribute *attr, AttrCallback *acb);
+
+ int cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval);
+ int cfgitem_delAttribute(const wchar_t *name);
+
+protected:
+
+ // derived classes can override this to catch name changes
+ virtual void cfgitem_onSetName() { }
+
+ Attribute *getAttributeByName(const wchar_t *name);
+
+ void addChildItem(CfgItemI *child);
+
+ void setCfgXml(const wchar_t *groupname);
+
+ void setParentGuid(GUID guid);
+
+private:
+ api_dependent *cfgitem_getDependencyPtr() { return this; };
+ virtual void *dependent_getInterface(const GUID *classguid);
+
+ // from Named
+ virtual void onSetName() { cfgitem_onSetName(); }
+
+ std::wstring prefix;
+ PtrList<Attribute> attributes;
+ std::multimap<Attribute*, AttrCallback*> callbacks; //CUT
+ PtrList<CfgItemI> children;
+ std::wstring cfgxml;
+ GUID myguid, parent_guid;
+ PtrList<Attribute> newattribs;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/cfgitemx.cpp b/Src/Wasabi/api/config/items/cfgitemx.cpp
new file mode 100644
index 00000000..b656dfc9
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemx.cpp
@@ -0,0 +1,27 @@
+#include <precomp.h>
+#include "cfgitemx.h"
+
+#define CBCLASS CfgItemX
+START_DISPATCH
+ CB(CFGITEM_GETNAME, cfgitem_getName);
+ CB(CFGITEM_GETGUID, cfgitem_getGuid);
+ CB(CFGITEM_GETNUMATTRIBUTES, cfgitem_getNumAttributes);
+ CB(CFGITEM_ENUMATTRIBUTE, cfgitem_enumAttribute);
+ CB(CFGITEM_GETCONFIGXML, cfgitem_getConfigXML);
+ VCB(CFGITEM_ONCFGGROUPCREATE, cfgitem_onCfgGroupCreate);
+ VCB(CFGITEM_ONCFGGROUPDELETE, cfgitem_onCfgGroupDelete);
+ CB(CFGITEM_GETNUMCHILDREN, cfgitem_getNumChildren);
+ CB(CFGITEM_ENUMCHILD, cfgitem_enumChild);
+ CB(CFGITEM_GETPARENTGUID, cfgitem_getParentGuid);
+ VCB(CFGITEM_ONREGISTER, cfgitem_onRegister);
+ VCB(CFGITEM_ONDEREGISTER, cfgitem_onDeregister);
+ CB(CFGITEM_GETATTRIBUTETYPE, cfgitem_getAttributeType);
+ CB(CFGITEM_GETATTRIBUTECONFIGGROUP, cfgitem_getAttributeConfigGroup);
+ CB(CFGITEM_GETDATALEN, cfgitem_getDataLen);
+ CB(CFGITEM_GETDATA, cfgitem_getData);
+ CB(CFGITEM_SETDATA, cfgitem_setData);
+ CB(CFGITEM_GETDEPENDENCYPTR, cfgitem_getDependencyPtr);
+ CB(CFGITEM_ADDATTRIB, cfgitem_addAttribute);
+ CB(CFGITEM_DELATTRIB, cfgitem_delAttribute);
+END_DISPATCH
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/config/items/cfgitemx.h b/Src/Wasabi/api/config/items/cfgitemx.h
new file mode 100644
index 00000000..6d5a9408
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemx.h
@@ -0,0 +1,42 @@
+#ifndef NULLSOFT_WASABI_CFGITEMX_H
+#define NULLSOFT_WASABI_CFGITEMX_H
+
+#include "cfgitem.h"
+
+class CfgItemX : public CfgItem
+{
+public:
+ virtual ~CfgItemX() {}
+ virtual const wchar_t *cfgitem_getName()=0;
+ virtual GUID cfgitem_getGuid()=0;
+ virtual int cfgitem_getNumAttributes()=0;
+ virtual const wchar_t *cfgitem_enumAttribute(int n)=0;
+ virtual const wchar_t *cfgitem_getConfigXML()=0;
+ virtual void cfgitem_onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname)=0;
+ virtual void cfgitem_onCfgGroupDelete(ifc_window *cfggroup)=0;
+
+ virtual int cfgitem_getNumChildren()=0;
+ virtual CfgItem *cfgitem_enumChild(int n)=0;
+ virtual GUID cfgitem_getParentGuid()=0;
+
+ virtual void cfgitem_onRegister()=0;
+ virtual void cfgitem_onDeregister()=0;
+
+ virtual int cfgitem_getAttributeType(const wchar_t *name)=0;
+ virtual const wchar_t *cfgitem_getAttributeConfigGroup(const wchar_t *name)=0;
+
+ virtual int cfgitem_getDataLen(const wchar_t *name)=0;
+ virtual int cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len)=0;
+ virtual int cfgitem_setData(const wchar_t *name, const wchar_t *data)=0;
+ virtual ifc_dependent *cfgitem_getDependencyPtr()=0;
+ virtual int cfgitem_delAttribute(const wchar_t *name)=0;
+ virtual int cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval)=0;
+
+protected:
+ RECVS_DISPATCH;
+
+
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/config/items/intarray.cpp b/Src/Wasabi/api/config/items/intarray.cpp
new file mode 100644
index 00000000..c6ba4676
--- /dev/null
+++ b/Src/Wasabi/api/config/items/intarray.cpp
@@ -0,0 +1,49 @@
+#include <precomp.h>
+
+#include "intarray.h"
+
+
+enum { MAX_ARRAY=8 };
+
+int IntArray::read(const wchar_t *name, int *x1, int *x2, int *x3, int *x4, int *x5, int *x6, int *x7, int *x8) {
+ PtrList<int> list;
+ if (x1) { list.addItem(x1); }
+ if (x2) { list.addItem(x2); }
+ if (x3) { list.addItem(x3); }
+ if (x4) { list.addItem(x4); }
+ if (x5) { list.addItem(x5); }
+ if (x6) { list.addItem(x6); }
+ if (x7) { list.addItem(x7); }
+ if (x8) { list.addItem(x8); }
+ ASSERT(list.getNumItems() >= 1);
+
+ int array[MAX_ARRAY]; // gcc rules, msvc drools
+ for (int i = 0; i < list.getNumItems(); i++) {
+ if (list[i]) array[i] = *list[i];
+ }
+ if (!WASABI_API_CONFIG->getIntArrayPrivate(name, array, list.getNumItems())) return 0;
+ for (int j = 0; j < list.getNumItems(); j++) {
+ if (list[j]) *list[j] = array[j];
+ }
+ return 1;
+}
+
+void IntArray::write(const wchar_t *name, int x1) {
+ int array[] = { x1 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
+
+void IntArray::write(const wchar_t *name, int x1, int x2) {
+ int array[] = { x1, x2 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
+
+void IntArray::write(const wchar_t *name, int x1, int x2, int x3) {
+ int array[] = { x1, x2, x3 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
+
+void IntArray::write(const wchar_t *name, int x1, int x2, int x3, int x4) {
+ int array[] = { x1, x2, x3, x4 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
diff --git a/Src/Wasabi/api/config/items/intarray.h b/Src/Wasabi/api/config/items/intarray.h
new file mode 100644
index 00000000..edb26322
--- /dev/null
+++ b/Src/Wasabi/api/config/items/intarray.h
@@ -0,0 +1,18 @@
+#ifndef _INTARRAY_H
+#define _INTARRAY_H
+
+#include <bfc/common.h>
+#include <bfc/named.h>
+#include <bfc/ptrlist.h>
+
+class IntArray
+{
+public:
+ static int read(const wchar_t *name, int *x1, int *x2=NULL, int *x3=NULL, int *x4=NULL, int *x5=NULL, int *x6=NULL, int *x7=NULL, int *x8=NULL);
+ static void write(const wchar_t *name, int x1);
+ static void write(const wchar_t *name, int x1, int x2);
+ static void write(const wchar_t *name, int x1, int x2, int x3);
+ static void write(const wchar_t *name, int x1, int x2, int x3, int x4);
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/options.cpp b/Src/Wasabi/api/config/options.cpp
new file mode 100644
index 00000000..e5c0d27a
--- /dev/null
+++ b/Src/Wasabi/api/config/options.cpp
@@ -0,0 +1,211 @@
+#include <precomp.h>
+
+#include "options.h"
+
+//#include <api/wac/main.h>//CUT!!
+#include <api/wnd/wndtrack.h>
+
+#include <bfc/util/inifile.h>
+#include <api/config/items/attribs.h>
+#include <api/config/items/attrcb.h>
+#include <bfc/wasabi_std_wnd.h>
+
+#include <api/locales/localesmgr.h>
+#include <api/font/font.h>
+
+#define ININAME "wasabi.ini"
+
+// {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+const GUID options_guid =
+{ 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+
+#ifndef GEN_FF
+
+static void setMultipleInstance(int val)
+{
+ StringPrintf fn("%s%s%s", WASABI_API_APP->path_getAppPath(), DIRCHARSTR, ININAME);
+ IniFile(fn).setBool("Wasabi", "MultipleInstance", val);
+}
+
+_int forward_skip_time("Forward skip time", 5000);
+_int reverse_skip_time("Reverse skip time", 5000);
+#endif
+
+_bool cfg_options_altfonts(L"Alternate Fonts", FALSE);
+_bool cfg_options_allowbitmapfonts(L"Use bitmap fonts (no international support)", FALSE);
+_string cfg_options_defaultfont(L"Default font", WASABI_DEFAULT_FONTNAMEW L".ttf");
+_int cfg_options_defaultfontscale(L"Default font scale", 100);
+_string cfg_options_ttfoverridefont(L"TTF font override", WASABI_DEFAULT_FONTNAMEW L".ttf");
+_int cfg_options_ttfoverridescale(L"TTF Override Scale", 100);
+_bool cfg_options_no7bitsttfoverride(L"No 7-bit TTF override", TRUE);
+_bool cfg_options_noalt7bitsttfoverride(L"No 7-bit TTF AltFonts", TRUE);
+_bool cfg_options_usefontmapper(L"Enable Font Mapper", FALSE);
+
+#ifdef USEAPPBAR
+_bool cfg_options_appbarondrag(L"Dock Appbars on Window Drag", FALSE);
+_int cfg_options_appbardockingdistance(L"Appbars Docking Distance", 5);
+#endif
+
+void invalidateAll(int b) {
+#ifdef WASABI_COMPILE_WNDMGR
+ WASABI_API_WNDMGR->wndTrackInvalidateAll();
+#endif
+}
+
+void onDefaultFontChanged(const wchar_t *attribute) {
+ Font::uninstallAll(1);
+ Wasabi::Std::setDefaultFont(cfg_options_defaultfont.getValue());
+ invalidateAll(1);
+}
+
+void onOverrideFontChanged(const wchar_t *attribute) {
+ Font::uninstallAll(1);
+ invalidateAll(1);
+}
+
+void onDefaultFontScaleChanged(int scale) {
+ Wasabi::Std::setDefaultFontScale(scale);
+ invalidateAll(1);
+}
+
+void onOverrideFontScaleChanged(int scale) {
+ invalidateAll(1);
+}
+
+void onFontRendererChanged(const wchar_t *s) {
+ Font::uninstallAll(1);
+ invalidateAll(1);
+}
+
+void onFontMapperChanged(int b) {
+ Font::uninstallAll(1);
+ invalidateAll(1);
+}
+
+_bool cfg_audiooptions_crossfader(L"Enable crossfading", DEFAULT_CROSSFADE_ENABLED);
+_bool cfg_options_alwaysontop(L"Always on top", FALSE);
+_bool cfg_options_docking(L"Enable docking", TRUE);
+_int cfg_options_dockingdistance(L"Docking distance", DEFAULT_DOCK_DIST);
+_string cfg_options_fontrenderer(L"Font Renderer", WASABI_FONT_RENDERER);
+_int cfg_options_freetypecharmap(L"Character mapping", -1);
+
+Options::Options() : CfgItemI(L"Options", options_guid)
+{
+#ifdef _WASABIRUNTIME
+ registerAttribute(&cfg_options_alwaysontop, new int_attrCB(Main::setOnTop));
+#else
+ extern void setOnTop(int ontop);
+ registerAttribute(&cfg_options_alwaysontop, new int_attrCB(setOnTop));
+#endif
+ /* TODO: benski> move to wndmgr.w5s (or wherever it's final home is */
+ registerAttribute(&cfg_options_dockingdistance, new int_attrCB(WindowTracker::setDockDistance));
+ registerAttribute(&cfg_options_docking, new int_attrCB(WindowTracker::setEnableDocking));
+ /* --- END TO MOVE --- */
+ registerAttribute(new _bool(L"Find open rect", FALSE));
+ registerAttribute(new _bool(L"Animated rects", TRUE));
+ registerAttribute(&cfg_options_fontrenderer, new string_attrCB(onFontRendererChanged));
+ registerAttribute(&cfg_options_allowbitmapfonts, new int_attrCB(invalidateAll));
+ registerAttribute(&cfg_options_altfonts, new int_attrCB(invalidateAll));
+ registerAttribute(&cfg_options_defaultfont, new string_attrCB(onDefaultFontChanged));
+ registerAttribute(&cfg_options_ttfoverridefont, new string_attrCB(onOverrideFontChanged));
+ registerAttribute(&cfg_options_ttfoverridescale, new int_attrCB(onOverrideFontScaleChanged));
+ registerAttribute(&cfg_options_defaultfontscale, new int_attrCB(onDefaultFontScaleChanged));
+ registerAttribute(&cfg_options_freetypecharmap, new int_attrCB(invalidateAll));
+ registerAttribute(&cfg_options_no7bitsttfoverride, new int_attrCB(invalidateAll));
+ registerAttribute(&cfg_options_noalt7bitsttfoverride, new int_attrCB(invalidateAll));
+ registerAttribute(&cfg_options_usefontmapper, new int_attrCB(onFontMapperChanged));
+#ifdef USEAPPBAR
+ registerAttribute(&cfg_options_appbarondrag);
+ registerAttribute(&cfg_options_appbardockingdistance);
+#endif
+#ifdef _WASABIRUNTIME
+ registerAttribute(new _bool(L"Allow multiple instances", FALSE), new int_attrCB(setMultipleInstance));
+ registerAttribute(new _int(L"Icon mode", 1), new int_attrCB(Main::setIconMode));
+ registerAttribute(new _bool(L"Auto-play at startup", FALSE));
+ registerAttribute(new _string(L"Language", "English"), new LanguageCB(this));
+#ifdef WIN32
+ registerAttribute(new _bool("Associate with audio CDs", TRUE), new int_attrCB(Filetypes::registerCdPlayer));
+#endif
+ registerAttribute(new _string("Monitor aspect ratio", "4:3"));
+ registerAttribute(new _int("Internet connection",3)); //3==autodetect
+ registerAttribute(&forward_skip_time);
+ registerAttribute(&reverse_skip_time);
+#endif
+
+ //registerAttribute(new _bool("Use Mozilla instead of IE for minibrowser", FALSE)); // TODO:move into minibrowser component
+/* registerAttribute(new _bool("Force antialias on all TTF", FALSE));*/
+ addChildItem(&audio_options);
+ addChildItem(&ui_options);
+}
+
+void Options::checkCd() {
+#ifdef _WASABIRUNTIME
+#ifdef WIN32
+ if(getDataAsInt("Associate with audio CDs") && !Filetypes::isCdPlayer()) setDataAsInt("Associate with audio CDs",false);
+#endif
+#endif
+}
+
+// {FC3EAF78-C66E-4ed2-A0AA-1494DFCC13FF}
+static const GUID audio_options_guid =
+{ 0xfc3eaf78, 0xc66e, 0x4ed2, { 0xa0, 0xaa, 0x14, 0x94, 0xdf, 0xcc, 0x13, 0xff } };
+
+AudioOptions::AudioOptions() : CfgItemI(L"Audio options", audio_options_guid)
+{
+#ifdef GEN_FF
+#ifdef WASABI_COMPILE_MEDIACORE
+ extern void setCrossfader(int crossfade);
+ registerAttribute(&cfg_audiooptions_crossfader, new int_attrCB(setCrossfader));
+#endif
+#endif
+#ifdef _WASABIRUNTIME
+ registerAttribute(&cfg_audiooptions_crossfader);
+ int use_dsound=0;
+#ifdef WIN32
+ //check for Windows version for whether we make DSOUND default
+ DWORD dwVersion = GetVersion();
+ DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ if (dwVersion < 0x80000000) {
+ if(dwWindowsMajorVersion<=4) use_dsound=0; // no dsound on NT4/3.51
+ else use_dsound=1; // dsound yes on 2000/XP
+ } else
+ use_dsound=0; // no dsound by default on win9x (per PP)
+#endif
+ registerAttribute(new _bool("DirectSound output", use_dsound));
+#endif
+}
+
+#ifdef _WASABIRUNTIME
+
+// {C1BD5354-5EC4-406c-B5C0-549718D3AF45}
+static const GUID setup_guid =
+{ 0xc1bd5354, 0x5ec4, 0x406c, { 0xb5, 0xc0, 0x54, 0x97, 0x18, 0xd3, 0xaf, 0x45 } };
+
+SetupOptions::SetupOptions() : CfgItemI("Setup", setup_guid) {
+#ifdef WIN32
+ addChildItem(&filetypes);
+#endif
+}
+
+// {99CFD75C-1CA7-49e5-B8C0-7D78AA443C10}
+static const GUID installed_guid =
+{ 0x99cfd75c, 0x1ca7, 0x49e5, { 0xb8, 0xc0, 0x7d, 0x78, 0xaa, 0x44, 0x3c, 0x10 } };
+
+InstalledComponents::InstalledComponents() : CfgItemI("Installed components", installed_guid) {
+//CUT setCfgXml("config.components");
+}
+
+void LanguageCB::onValueChange(Attribute *attr) {
+ char bufero[WA_MAX_PATH]="";
+ attr->getData(bufero, WA_MAX_PATH-1);
+ const char *locname;
+ for(int i=0;locname=LocalesManager::enumLoadableLocales(i);i++) {
+ if (STRCASEEQLSAFE(bufero, locname)) {
+ LocalesManager::setNewLocaleNum(i);
+ return;
+ }
+ }
+ WASABI_API_WNDMGR->messageBox(StringPrintf("Internal problem switching to language %s, the language name couldn't be found in the list of loaded resources", bufero), "Error", 0, NULL, NULL);
+}
+
+#endif
diff --git a/Src/Wasabi/api/config/options.h b/Src/Wasabi/api/config/options.h
new file mode 100644
index 00000000..c86a7f3a
--- /dev/null
+++ b/Src/Wasabi/api/config/options.h
@@ -0,0 +1,64 @@
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+#include <api/config/items/cfgitemi.h>
+#include <api/config/items/attrcb.h>
+
+//#include <api/config/filetypes.h>
+#include <api/config/uioptions.h>
+
+class Options;
+
+class _string;
+class _int;
+class _bool;
+
+extern _string cfg_options_defaultfont;
+extern _int cfg_options_ttfoverridescale;
+extern _bool cfg_options_no7bitsttfoverride;
+extern _bool cfg_options_allowbitmapfonts;
+extern _string cfg_options_fontrenderer;
+
+#ifdef _WASABIRUNTIME
+
+class SetupOptions : public CfgItemI {
+public:
+ SetupOptions();
+
+ Filetypes filetypes;
+};
+
+class InstalledComponents : public CfgItemI {
+public:
+ InstalledComponents();
+};
+#endif
+
+class AudioOptions : public CfgItemI {
+public:
+ AudioOptions();
+};
+
+#define OPTIONS_PARENT CfgItemI
+class Options : public OPTIONS_PARENT {
+public:
+ Options();
+ void checkCd();
+
+ AudioOptions audio_options;
+ UIOptions ui_options;
+};
+
+#ifdef _WASABIRUNTIME
+
+class LanguageCB : public AttrCallback {
+public:
+ LanguageCB(CfgItemI *_par) : par(_par) { }
+ virtual void onValueChange(Attribute *attr);
+private:
+ CfgItemI *par;
+};
+
+#endif
+
+#endif
diff --git a/Src/Wasabi/api/config/uioptions.cpp b/Src/Wasabi/api/config/uioptions.cpp
new file mode 100644
index 00000000..0ccc33f7
--- /dev/null
+++ b/Src/Wasabi/api/config/uioptions.cpp
@@ -0,0 +1,109 @@
+#include <precomp.h>
+
+#include "uioptions.h"
+
+#include <api/wndmgr/layout.h>
+
+#include <api/config/items/attribs.h>
+#include <api/config/items/attrcb.h>
+
+#include <api/skin/skinparse.h>
+#include <api/wndmgr/alphamgr.h>
+
+// {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+const GUID uioptions_guid =
+{ 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+
+_bool cfg_uioptions_desktopalpha(L"Enable desktop alpha", DEFAULT_DESKTOPALPHA);
+_bool cfg_uioptions_linkratio(L"Link layouts scale", DEFAULT_LINKLAYOUTSCALE);
+_bool cfg_uioptions_linkalpha(L"Link layouts alpha", DEFAULT_LINKLAYOUTSALPHA);
+_bool cfg_uioptions_linkallalpha(L"Link All layouts alpha", DEFAULT_LINKALLALPHA);
+_bool cfg_uioptions_linkallratio(L"Link All layouts scale", DEFAULT_LINKALLRATIO);
+_int cfg_uioptions_linkedalpha(L"Linked layouts alpha", DEFAULT_LINKEDALPHA);
+_int cfg_uioptions_autoopacitytime(L"Auto Opacity hold time", DEFAULT_AUTOOPACITYTIME);
+_int cfg_uioptions_autoopacityfadein(L"Auto Opacity fade in time", DEFAULT_AUTOOPACITYFADEIN);
+_int cfg_uioptions_autoopacityfadeout(L"Auto Opacity fade out time", DEFAULT_AUTOOPACITYFADEOUT);
+_int cfg_uioptions_autoopacitylinked(L"Use Auto Opacity", DEFAULT_AUTOOPACITYTYPE);
+_int cfg_uioptions_extendautoopacity(L"Auto Opacity extend by", DEFAULT_EXTENDAUTOOPACITY);
+_bool cfg_uioptions_uselocks(L"Use layout scale locks", DEFAULT_USERATIOLOCKS);
+_int cfg_uioptions_timerresolution(L"Multiplexed timers resolution", DEFAULT_TIMERRESOLUTION);
+_bool cfg_uioptions_tooltips(L"Enable tooltips", DEFAULT_TOOLTIPS);
+_float cfg_uioptions_textspeed(L"Text Ticker Speed", DEFAULT_TEXTSPEED);
+_int cfg_uioptions_textincrement(L"Text Ticker Increment", DEFAULT_TEXTINCREMENT);
+_int cfg_uioptions_appbarshidetime(L"Appbar Hide Time", DEFAULT_APPBARHIDETIME);
+_int cfg_uioptions_appbarsshowtime(L"Appbar Show Time", DEFAULT_APPBARSHOWTIME);
+
+void onSetOpacityTime(int n) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setHoldTime(n);
+}
+
+void onSetOpacityFadeIn(int n) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setFadeInTime(n);
+}
+
+void onSetOpacityFadeOut(int n) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setFadeOutTime(n);
+}
+
+void onSetAllRatio(int on) {
+ if (on) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->setRenderRatio(l->getRenderRatio());
+ }
+}
+
+void onSetAllAlpha(int on) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setAllLinked(on);
+}
+
+void onSetLinkedAlpha(int a) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setGlobalAlpha(a);
+}
+
+void onSetLinkedAuto100(int v) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setAutoOpacify(v);
+}
+
+void onSetExtendAutoOpacity(int v) {
+ Layout *l = SkinParser::getMainLayout();
+ if (l) l->getAlphaMgr()->setExtendAutoOpacity(v);
+}
+
+UIOptions::UIOptions(const wchar_t *name) : CfgItemI(name ? name : L"Skins and UI Tweaks", uioptions_guid)
+{
+ registerAttribute(&cfg_uioptions_linkratio);
+ registerAttribute(&cfg_uioptions_linkalpha);
+ registerAttribute(&cfg_uioptions_uselocks);
+ registerAttribute(&cfg_uioptions_autoopacitylinked, new int_attrCB(onSetLinkedAuto100));
+ registerAttribute(&cfg_uioptions_linkallratio, new int_attrCB(onSetAllRatio));
+ registerAttribute(&cfg_uioptions_linkallalpha, new int_attrCB(onSetAllAlpha));
+ registerAttribute(&cfg_uioptions_desktopalpha, new int_attrCB(Layout::onGlobalEnableDesktopAlpha));
+ registerAttribute(&cfg_uioptions_linkedalpha, new int_attrCB(onSetLinkedAlpha));
+ registerAttribute(&cfg_uioptions_tooltips);
+ registerAttribute(&cfg_uioptions_timerresolution);
+ registerAttribute(&cfg_uioptions_textspeed);
+ registerAttribute(&cfg_uioptions_textincrement);
+ registerAttribute(&cfg_uioptions_appbarshidetime);
+ registerAttribute(&cfg_uioptions_appbarsshowtime);
+ registerAttribute(&cfg_uioptions_autoopacitytime, new int_attrCB(onSetOpacityTime));
+ registerAttribute(&cfg_uioptions_autoopacityfadein, new int_attrCB(onSetOpacityFadeIn));
+ registerAttribute(&cfg_uioptions_autoopacityfadeout, new int_attrCB(onSetOpacityFadeOut));
+ registerAttribute(&cfg_uioptions_extendautoopacity, new int_attrCB(onSetExtendAutoOpacity));
+ registerAttribute(new _int(L"Timer refresh rate", 30), new int_attrCB(onTimerRefreshRate));
+ registerAttribute(new _int(L"Popup menu alpha", 240));
+ registerAttribute(new _int(L"Spectrum analyzer mode",1));
+}
+
+void UIOptions::onTimerRefreshRate(int rate) {
+ if(rate==0 || rate<9 || rate>70) return;
+ int res=1000/rate;
+ CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if(!ci) return;
+ ci->setDataAsInt(L"Multiplexed timers resolution",res);
+}
diff --git a/Src/Wasabi/api/config/uioptions.h b/Src/Wasabi/api/config/uioptions.h
new file mode 100644
index 00000000..bf2cb963
--- /dev/null
+++ b/Src/Wasabi/api/config/uioptions.h
@@ -0,0 +1,13 @@
+#ifndef _UIOPTIONS_H
+#define _UIOPTIONS_H
+
+#include <api/config/items/cfgitemi.h>
+
+#define UIOPTIONS_PARENT CfgItemI
+class UIOptions : public UIOPTIONS_PARENT {
+public:
+ UIOptions(const wchar_t *name=NULL);
+ static void onTimerRefreshRate(int rate);
+};
+
+#endif
diff --git a/Src/Wasabi/api/console/console.cpp b/Src/Wasabi/api/console/console.cpp
new file mode 100644
index 00000000..3188ac7d
--- /dev/null
+++ b/Src/Wasabi/api/console/console.cpp
@@ -0,0 +1,33 @@
+#include "console.h"
+#include <api/service/svcs/svc_console.h>
+#include <api/service/svc_enum.h>
+
+void Console::outputString(int severity, const char *string) {
+ if (!console) {
+ console = new ConsoleEnum;
+ }
+
+ if (needscan) {
+ needscan=0;
+ console->reset();
+ svc_console *con = console->getNext();
+ noconsole = (con == NULL);
+ }
+ if (noconsole) return;
+
+ console->reset();
+ svc_console *con = console->getNext();
+ while (con) {
+ con->outputString(severity, string);
+ con = console->getNext();
+ }
+}
+
+void Console::reset() {
+ needscan=1;
+}
+
+int Console::needscan=1;
+int Console::noconsole=0;
+
+ConsoleEnum *Console::console = NULL;
diff --git a/Src/Wasabi/api/console/console.h b/Src/Wasabi/api/console/console.h
new file mode 100644
index 00000000..bece619d
--- /dev/null
+++ b/Src/Wasabi/api/console/console.h
@@ -0,0 +1,19 @@
+#ifndef __CONSOLE_H
+#define __CONSOLE_H
+
+class ConsoleEnum;
+
+class Console {
+ public:
+
+ static void outputString(int severity, const char *string);
+ static void reset();
+
+ private:
+
+ static ConsoleEnum *console;
+ static int needscan;
+ static int noconsole;
+};
+
+#endif
diff --git a/Src/Wasabi/api/core/api_core.cpp b/Src/Wasabi/api/core/api_core.cpp
new file mode 100644
index 00000000..6fe6c484
--- /dev/null
+++ b/Src/Wasabi/api/core/api_core.cpp
@@ -0,0 +1,51 @@
+#include <precomp.h>
+#include "api_core.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_coreI
+START_DISPATCH;
+ CB(API_CORE_GETSUPPORTEDEXTENSIONS, core_getSupportedExtensions);
+ CB(API_CORE_GETEXTSUPPORTEDEXTENSIONS, core_getExtSupportedExtensions);
+ CB(API_CORE_CREATE, core_create);
+ CB(API_CORE_FREE, core_free);
+ CB(API_CORE_SETNEXTFILE, core_setNextFile);
+ CB(API_CORE_GETSTATUS, core_getStatus);
+ CB(API_CORE_GETCURRENT, core_getCurrent);
+ CB(API_CORE_GETCURPLAYBACKNUMBER, core_getCurPlaybackNumber);
+ CB(API_CORE_GETPOSITION, core_getPosition);
+ CB(API_CORE_GETWRITEPOSITION, core_getWritePosition);
+ CB(API_CORE_SETPOSITION, core_setPosition);
+ CB(API_CORE_GETLENGTH, core_getLength);
+ CB(API_CORE_GETPLUGINDATA, core_getPluginData);
+ CB(API_CORE_GETVOLUME, core_getVolume);
+ VCB(API_CORE_SETVOLUME, core_setVolume);
+ CB(API_CORE_GETPAN, core_getPan);
+ VCB(API_CORE_SETPAN, core_setPan);
+ VCB(API_CORE_ADDCALLBACK, core_addCallback);
+ VCB(API_CORE_DELCALLBACK, core_delCallback);
+ CB(API_CORE_GETVISDATA, core_getVisData);
+ CB(API_CORE_GETLEFTVUMETER, core_getLeftVuMeter);
+ CB(API_CORE_GETRIGHTVUMETER, core_getRightVuMeter);
+ CB(API_CORE_REGISTERSEQUENCER, core_registerSequencer);
+ CB(API_CORE_DEREGISTERSEQUENCER, core_deregisterSequencer);
+ VCB(API_CORE_USERBUTTON, core_userButton);
+ CB(API_CORE_GETEQSTATUS, core_getEqStatus);
+ VCB(API_CORE_SETEQSTATUS, core_setEqStatus);
+ CB(API_CORE_GETEQPREAMP, core_getEqPreamp);
+ VCB(API_CORE_SETEQPREAMP, core_setEqPreamp);
+ CB(API_CORE_GETEQBAND, core_getEqBand);
+ VCB(API_CORE_SETEQBAND, core_setEqBand);
+ CB(API_CORE_GETEQAUTO, core_getEqAuto);
+ VCB(API_CORE_SETEQAUTO, core_setEqAuto);
+ VCB(API_CORE_SETCUSTOMMSG, core_setCustomMsg);
+ VCB(API_CORE_REGISTEREXTENSION, core_registerExtension);
+ CB(API_CORE_GETEXTENSIONFAMILY, core_getExtensionFamily);
+ VCB(API_CORE_UNREGISTEREXTENSION, core_unregisterExtension);
+ CB(API_CORE_GETTITLE, core_getTitle);
+ CB(API_CORE_GETRATING, core_getRating);
+ VCB(API_CORE_SETRATING, core_setRating);
+ CB(API_CORE_GETDECODERNAME, core_getDecoderName);
+ VCB(API_CORE_SETTITLE, core_setTitle);
+END_DISPATCH; \ No newline at end of file
diff --git a/Src/Wasabi/api/core/api_core.h b/Src/Wasabi/api/core/api_core.h
new file mode 100644
index 00000000..759470a9
--- /dev/null
+++ b/Src/Wasabi/api/core/api_core.h
@@ -0,0 +1,371 @@
+#ifndef __API_CORE_H
+#define __API_CORE_H
+
+#include <bfc/dispatch.h>
+
+typedef unsigned int CoreToken;
+class CoreCallback;
+class ItemSequencer;
+
+class NOVTABLE api_core : public Dispatchable
+{
+public:
+ const wchar_t *core_getSupportedExtensions();
+ const wchar_t *core_getExtSupportedExtensions();
+ CoreToken core_create();
+ int core_free(CoreToken core);
+ int core_setNextFile(CoreToken core, const wchar_t *playstring);
+ int core_getStatus(CoreToken core);
+ const wchar_t *core_getCurrent(CoreToken core);
+ int core_getCurPlaybackNumber(CoreToken core);
+ int core_getPosition(CoreToken core);
+ int core_getWritePosition(CoreToken core);
+ int core_setPosition(CoreToken core, int ms);
+ int core_getLength(CoreToken core);
+ int core_getPluginData(const wchar_t *playstring, const wchar_t *name, wchar_t *data, int data_len, int data_type = 0);
+ unsigned int core_getVolume(CoreToken core);
+ void core_setVolume(CoreToken core, unsigned int vol);
+ int core_getPan(CoreToken core);
+ void core_setPan(CoreToken core, int val);
+ void core_addCallback(CoreToken core, CoreCallback *cb);
+ void core_delCallback(CoreToken core, CoreCallback *cb);
+ int core_getVisData(CoreToken core, void *dataptr, int sizedataptr);
+ int core_getLeftVuMeter(CoreToken core);
+ int core_getRightVuMeter(CoreToken core);
+ int core_registerSequencer(CoreToken core, ItemSequencer *seq);
+ int core_deregisterSequencer(CoreToken core, ItemSequencer *seq);
+ void core_userButton(CoreToken core, int button);
+ int core_getEqStatus(CoreToken core);
+ void core_setEqStatus(CoreToken core, int enable);
+ int core_getEqPreamp(CoreToken core);
+ void core_setEqPreamp(CoreToken core, int pre);
+ int core_getEqBand(CoreToken core, int band);
+ void core_setEqBand(CoreToken core, int band, int val);
+ int core_getEqAuto(CoreToken core);
+ void core_setEqAuto(CoreToken core, int enable);
+ void core_setCustomMsg(CoreToken core, const wchar_t *text);
+ void core_registerExtension(const wchar_t *extensions, const wchar_t *extension_name, const wchar_t *family = NULL);
+ const wchar_t *core_getExtensionFamily(const wchar_t *extension);
+ void core_unregisterExtension(const wchar_t *extensions);
+ const wchar_t *core_getTitle(CoreToken core);
+ void core_setTitle(const wchar_t *new_title);
+ const wchar_t *core_getDecoderName(const wchar_t *filename);
+ // these don't necessarily belong here, but api_core is already over-bloated :)
+ int core_getRating();
+ void core_setRating(int newRating);
+
+ enum
+ {
+ API_CORE_GETSUPPORTEDEXTENSIONS = 0,
+ API_CORE_GETEXTSUPPORTEDEXTENSIONS = 10,
+ API_CORE_CREATE = 20,
+ API_CORE_FREE = 30,
+ API_CORE_SETNEXTFILE = 40,
+ API_CORE_GETSTATUS = 50,
+ API_CORE_GETCURRENT = 60,
+ API_CORE_GETCURPLAYBACKNUMBER = 70,
+ API_CORE_GETPOSITION = 80,
+ API_CORE_GETWRITEPOSITION = 90,
+ API_CORE_SETPOSITION = 100,
+ API_CORE_GETLENGTH = 110,
+ API_CORE_GETPLUGINDATA = 120,
+ API_CORE_GETVOLUME = 130,
+ API_CORE_SETVOLUME = 140,
+ API_CORE_GETPAN = 150,
+ API_CORE_SETPAN = 160,
+ API_CORE_ADDCALLBACK = 170,
+ API_CORE_DELCALLBACK = 180,
+ API_CORE_GETVISDATA = 190,
+ API_CORE_GETLEFTVUMETER = 200,
+ API_CORE_GETRIGHTVUMETER = 210,
+ API_CORE_REGISTERSEQUENCER = 220,
+ API_CORE_DEREGISTERSEQUENCER = 230,
+ API_CORE_USERBUTTON = 240,
+ API_CORE_GETEQSTATUS = 250,
+ API_CORE_SETEQSTATUS = 260,
+ API_CORE_GETEQPREAMP = 270,
+ API_CORE_SETEQPREAMP = 280,
+ API_CORE_GETEQBAND = 290,
+ API_CORE_SETEQBAND = 300,
+ API_CORE_GETEQAUTO = 310,
+ API_CORE_SETEQAUTO = 320,
+ API_CORE_SETCUSTOMMSG = 330,
+ API_CORE_REGISTEREXTENSION = 340,
+ API_CORE_GETEXTENSIONFAMILY = 350,
+ API_CORE_UNREGISTEREXTENSION = 360,
+ API_CORE_GETTITLE = 370,
+ API_CORE_GETRATING = 380,
+ API_CORE_SETRATING = 390,
+ API_CORE_GETDECODERNAME = 400,
+ API_CORE_SETTITLE = 410,
+ };
+};
+
+inline const wchar_t *api_core::core_getSupportedExtensions()
+{
+ return _call(API_CORE_GETSUPPORTEDEXTENSIONS, (const wchar_t *)0);
+}
+
+inline const wchar_t *api_core::core_getExtSupportedExtensions()
+{
+ return _call(API_CORE_GETEXTSUPPORTEDEXTENSIONS, (const wchar_t *)0);
+}
+
+inline CoreToken api_core::core_create()
+{
+ return _call(API_CORE_CREATE, (CoreToken)NULL);
+}
+
+inline int api_core::core_free(CoreToken core)
+{
+ return _call(API_CORE_FREE, (int)0, core);
+}
+
+inline int api_core::core_setNextFile(CoreToken core, const wchar_t *playstring)
+{
+ return _call(API_CORE_SETNEXTFILE, (int)0, core, playstring);
+}
+
+inline int api_core::core_getStatus(CoreToken core)
+{
+ return _call(API_CORE_GETSTATUS, (int)0, core);
+}
+
+inline const wchar_t *api_core::core_getCurrent(CoreToken core)
+{
+ return _call(API_CORE_GETCURRENT, (const wchar_t *)0, core);
+}
+
+inline int api_core::core_getCurPlaybackNumber(CoreToken core)
+{
+ return _call(API_CORE_GETCURPLAYBACKNUMBER, (int)0, core);
+}
+
+inline int api_core::core_getPosition(CoreToken core)
+{
+ return _call(API_CORE_GETPOSITION, (int)0, core);
+}
+
+inline int api_core::core_getWritePosition(CoreToken core)
+{
+ return _call(API_CORE_GETWRITEPOSITION, (int)0, core);
+}
+
+inline int api_core::core_setPosition(CoreToken core, int ms)
+{
+ return _call(API_CORE_SETPOSITION, (int)0, core, ms);
+}
+
+inline int api_core::core_getLength(CoreToken core)
+{
+ return _call(API_CORE_GETLENGTH, (int)0, core);
+}
+
+inline int api_core::core_getPluginData(const wchar_t *playstring, const wchar_t *name, wchar_t *data, int data_len, int data_type)
+{
+ return _call(API_CORE_GETPLUGINDATA, (int)0, playstring, name, data, data_len, data_type);
+}
+
+inline unsigned int api_core::core_getVolume(CoreToken core)
+{
+ return _call(API_CORE_GETVOLUME, (unsigned int)0, core);
+}
+
+inline void api_core::core_setVolume(CoreToken core, unsigned int vol)
+{
+ _voidcall(API_CORE_SETVOLUME, core, vol);
+}
+
+inline int api_core::core_getPan(CoreToken core)
+{
+ return _call(API_CORE_GETPAN, (int)0, core);
+}
+
+inline void api_core::core_setPan(CoreToken core, int val)
+{
+ _voidcall(API_CORE_SETPAN, core, val);
+}
+
+inline void api_core::core_addCallback(CoreToken core, CoreCallback *cb)
+{
+ _voidcall(API_CORE_ADDCALLBACK, core, cb);
+}
+
+inline void api_core::core_delCallback(CoreToken core, CoreCallback *cb)
+{
+ _voidcall(API_CORE_DELCALLBACK, core, cb);
+}
+
+inline int api_core::core_getVisData(CoreToken core, void *dataptr, int sizedataptr)
+{
+ return _call(API_CORE_GETVISDATA, (int)0, core, dataptr, sizedataptr);
+}
+
+inline int api_core::core_getLeftVuMeter(CoreToken core)
+{
+ return _call(API_CORE_GETLEFTVUMETER, (int)0, core);
+}
+
+inline int api_core::core_getRightVuMeter(CoreToken core)
+{
+ return _call(API_CORE_GETRIGHTVUMETER, (int)0, core);
+}
+
+inline int api_core::core_registerSequencer(CoreToken core, ItemSequencer *seq)
+{
+ return _call(API_CORE_REGISTERSEQUENCER, (int)0, core, seq);
+}
+
+inline int api_core::core_deregisterSequencer(CoreToken core, ItemSequencer *seq)
+{
+ return _call(API_CORE_DEREGISTERSEQUENCER, (int)0, core, seq);
+}
+
+inline void api_core::core_userButton(CoreToken core, int button)
+{
+ _voidcall(API_CORE_USERBUTTON, core, button);
+}
+
+inline int api_core::core_getEqStatus(CoreToken core)
+{
+ return _call(API_CORE_GETEQSTATUS, (int)0, core);
+}
+
+inline void api_core::core_setEqStatus(CoreToken core, int enable)
+{
+ _voidcall(API_CORE_SETEQSTATUS, core, enable);
+}
+
+inline int api_core::core_getEqPreamp(CoreToken core)
+{
+ return _call(API_CORE_GETEQPREAMP, (int)0, core);
+}
+
+inline void api_core::core_setEqPreamp(CoreToken core, int pre)
+{
+ _voidcall(API_CORE_SETEQPREAMP, core, pre);
+}
+
+inline int api_core::core_getEqBand(CoreToken core, int band)
+{
+ return _call(API_CORE_GETEQBAND, (int)0, core, band);
+}
+
+inline void api_core::core_setEqBand(CoreToken core, int band, int val)
+{
+ _voidcall(API_CORE_SETEQBAND, core, band, val);
+}
+
+inline int api_core::core_getEqAuto(CoreToken core)
+{
+ return _call(API_CORE_GETEQAUTO, (int)0, core);
+}
+
+inline void api_core::core_setEqAuto(CoreToken core, int enable)
+{
+ _voidcall(API_CORE_SETEQAUTO, core, enable);
+}
+
+inline void api_core::core_setCustomMsg(CoreToken core, const wchar_t *text)
+{
+ _voidcall(API_CORE_SETCUSTOMMSG, core, text);
+}
+
+inline void api_core::core_registerExtension(const wchar_t *extensions, const wchar_t *extension_name, const wchar_t *family)
+{
+ _voidcall(API_CORE_REGISTEREXTENSION, extensions, extension_name, family);
+}
+
+inline const wchar_t *api_core::core_getExtensionFamily(const wchar_t *extension)
+{
+ return _call(API_CORE_GETEXTENSIONFAMILY, (const wchar_t *)0, extension);
+}
+
+inline void api_core::core_unregisterExtension(const wchar_t *extensions)
+{
+ _voidcall(API_CORE_UNREGISTEREXTENSION, extensions);
+}
+
+inline const wchar_t *api_core::core_getTitle(CoreToken core)
+{
+ return _call(API_CORE_GETTITLE, (const wchar_t *)0, core);
+}
+
+inline void api_core::core_setTitle(const wchar_t *new_title)
+{
+ _voidcall(API_CORE_SETTITLE, new_title);
+}
+
+inline int api_core::core_getRating()
+{
+ return _call(API_CORE_GETRATING, (int)0);
+}
+
+ inline void api_core::core_setRating(int newRating)
+ {
+ _voidcall(API_CORE_SETRATING, newRating);
+ }
+
+ inline const wchar_t *api_core::core_getDecoderName(const wchar_t *filename)
+ {
+ return _call(API_CORE_GETDECODERNAME, (const wchar_t *)0, filename);
+ }
+
+class api_coreI : public api_core
+{
+public:
+ virtual const wchar_t *core_getSupportedExtensions() = 0;
+ virtual const wchar_t *core_getExtSupportedExtensions() = 0;
+ virtual CoreToken core_create() = 0;
+ virtual int core_free(CoreToken core) = 0;
+ virtual int core_setNextFile(CoreToken core, const wchar_t *playstring) = 0;
+ virtual int core_getStatus(CoreToken core) = 0;
+ virtual const wchar_t *core_getCurrent(CoreToken core) = 0;
+ virtual int core_getCurPlaybackNumber(CoreToken core) = 0;
+ virtual int core_getPosition(CoreToken core) = 0;
+ virtual int core_getWritePosition(CoreToken core) = 0;
+ virtual int core_setPosition(CoreToken core, int ms) = 0;
+ virtual int core_getLength(CoreToken core) = 0;
+ virtual int core_getPluginData(const wchar_t *playstring, const wchar_t *name, wchar_t *data, int data_len, int data_type = 0) = 0;
+ virtual unsigned int core_getVolume(CoreToken core) = 0;
+ virtual void core_setVolume(CoreToken core, unsigned int vol) = 0;
+ virtual int core_getPan(CoreToken core) = 0;
+ virtual void core_setPan(CoreToken core, int val) = 0;
+ virtual void core_addCallback(CoreToken core, CoreCallback *cb) = 0;
+ virtual void core_delCallback(CoreToken core, CoreCallback *cb) = 0;
+ virtual int core_getVisData(CoreToken core, void *dataptr, int sizedataptr) = 0;
+ virtual int core_getLeftVuMeter(CoreToken core) = 0;
+ virtual int core_getRightVuMeter(CoreToken core) = 0;
+ virtual int core_registerSequencer(CoreToken core, ItemSequencer *seq) = 0;
+ virtual int core_deregisterSequencer(CoreToken core, ItemSequencer *seq) = 0;
+ virtual void core_userButton(CoreToken core, int button) = 0;
+ virtual int core_getEqStatus(CoreToken core) = 0;
+ virtual void core_setEqStatus(CoreToken core, int enable) = 0;
+ virtual int core_getEqPreamp(CoreToken core) = 0;
+ virtual void core_setEqPreamp(CoreToken core, int pre) = 0;
+ virtual int core_getEqBand(CoreToken core, int band) = 0;
+ virtual void core_setEqBand(CoreToken core, int band, int val) = 0;
+ virtual int core_getEqAuto(CoreToken core) = 0;
+ virtual void core_setEqAuto(CoreToken core, int enable) = 0;
+ virtual void core_setCustomMsg(CoreToken core, const wchar_t *text) = 0;
+ virtual void core_registerExtension(const wchar_t *extensions, const wchar_t *extension_name, const wchar_t *family = NULL) = 0;
+ virtual const wchar_t *core_getExtensionFamily(const wchar_t *extension) = 0;
+ virtual void core_unregisterExtension(const wchar_t *extensions) = 0;
+ virtual const wchar_t *core_getTitle(CoreToken core) = 0;
+ virtual void core_setTitle(const wchar_t *new_title) = 0;
+ virtual int core_getRating()=0;
+ virtual void core_setRating(int newRating)=0;
+ virtual const wchar_t *core_getDecoderName(const wchar_t *filename)=0;
+
+
+protected:
+ RECVS_DISPATCH;
+};
+
+// {966E3DA1-C2C5-43a9-A931-EB5F8B040A4F}
+static const GUID coreApiServiceGuid =
+ { 0x966e3da1, 0xc2c5, 0x43a9, { 0xa9, 0x31, 0xeb, 0x5f, 0x8b, 0x4, 0xa, 0x4f } };
+
+extern api_core *coreApi;
+
+#endif
diff --git a/Src/Wasabi/api/core/buttons.h b/Src/Wasabi/api/core/buttons.h
new file mode 100644
index 00000000..dbc43460
--- /dev/null
+++ b/Src/Wasabi/api/core/buttons.h
@@ -0,0 +1,18 @@
+#ifndef _BUTTONS_H
+#define _BUTTONS_H
+
+// codes for
+
+namespace UserButton {
+ enum {
+ PREV=0,
+ PLAY,
+ PAUSE,
+ STOP,
+ NEXT,
+ };
+ const int first = PREV;
+ const int last = NEXT;
+};
+
+#endif
diff --git a/Src/Wasabi/api/core/coreactions.cpp b/Src/Wasabi/api/core/coreactions.cpp
new file mode 100644
index 00000000..0a73ff77
--- /dev/null
+++ b/Src/Wasabi/api/core/coreactions.cpp
@@ -0,0 +1,181 @@
+#include <precomp.h>
+
+#include "coreactions.h"
+
+#include <api/config/items/cfgitem.h>
+#include <api/core/buttons.h>
+#include <api/api.h>
+#include <api/core/corehandle.h>
+#include <api/service/svcs/svc_player.h>
+#include <api/locales/xlatstr.h>
+
+CoreActions::CoreActions() {
+ registerAction("prev", ACTION_PREV);
+ registerAction("play", ACTION_PLAY);
+ registerAction("pause", ACTION_PAUSE);
+ registerAction("stop", ACTION_STOP);
+ registerAction("next", ACTION_NEXT);
+ registerAction("eject", ACTION_EJECT);
+ registerAction("eject_url", ACTION_EJECTURL);
+ registerAction("eject_dir", ACTION_EJECTDIR);
+ registerAction("seek", ACTION_SEEK);
+ registerAction("volume", ACTION_VOLUME);
+ registerAction("pan", ACTION_PAN);
+ registerAction("volume_up", ACTION_VOLUME_UP);
+ registerAction("volume_down", ACTION_VOLUME_DOWN);
+ registerAction("rewind_5s", ACTION_REWIND_5S);
+ registerAction("ffwd_5s", ACTION_FFWD_5S);
+ registerAction("toggle_repeat", ACTION_TOGGLE_REPEAT);
+ registerAction("toggle_shuffle", ACTION_TOGGLE_SHUFFLE);
+ registerAction("toggle_crossfader", ACTION_TOGGLE_CROSSFADER);
+ registerAction("mute", ACTION_MUTE);
+ registerAction("eq_preamp", ACTION_EQ_PREAMP);
+ registerAction("eq_band", ACTION_EQ_BAND);
+ registerAction("eq_auto", ACTION_EQ_AUTO);
+ registerAction("eq_reset", ACTION_EQ_RESET);
+ registerAction("toggle_repeat", ACTION_TOGGLE_REPEAT);
+ registerAction("toggle_shuffle", ACTION_TOGGLE_SHUFFLE);
+ registerAction("toggle_crossfader", ACTION_TOGGLE_CROSSFADER);
+ registerAction("eq_toggle", ACTION_EQ_TOGGLE);
+ for (int i=0;i<4;i++)
+ registerAction(StringPrintf("play_cd%d", i+1), ACTION_PLAY_CD+i);
+}
+
+CoreActions::~CoreActions() {
+}
+
+int CoreActions::onActionId(int pvtid, const char *action, const char *param/* =NULL */, int p1/* =0 */, int p2/* =0 */, void *data/* =NULL */, int datalen/* =0 */, api_window *source/* =NULL */) {
+ int d = ATOI(param);
+ CoreHandle ch("main");
+ switch(pvtid) {
+ case ACTION_PREV: { if (d==0) ch.prev(); } break;
+ case ACTION_PLAY: { if (d==0) ch.play(); } break;
+ case ACTION_PAUSE: { if (d==0) ch.pause(); } break;
+ case ACTION_STOP: { if (d==0) ch.stop(); } break;
+ case ACTION_NEXT: { if (d==0) ch.next(); } break;
+
+ case ACTION_EJECT: {
+ svc_player *sp = SvcEnumByGuid<svc_player>();
+ if (d == 0) {
+ if (sp) sp->openFiles(source, "files");
+ } else {
+ if (sp) sp->openFiles(source);
+ }
+ WASABI_API_SVC->service_release(sp);
+ }
+ break;
+ case ACTION_EJECTURL: if (d==0) {
+ svc_player *sp = SvcEnumByGuid<svc_player>();
+ if (sp) sp->openFiles(source, "location");
+ api->service_release(sp);
+ }
+ break;
+ case ACTION_EJECTDIR: if (d==0) {
+ svc_player *sp = SvcEnumByGuid<svc_player>();
+ if (sp) sp->openFiles(source, "directory");
+ api->service_release(sp);
+ }
+ break;
+
+ case ACTION_VOLUME_UP: if (d==0) {
+ int v=ch.getVolume();
+ ch.setVolume(MIN(255,(v+5)));
+ }
+ break;
+
+ case ACTION_VOLUME_DOWN: if (d==0) {
+ int v=ch.getVolume();
+ ch.setVolume(MAX(0,(v-5)));
+ }
+ break;
+
+ case ACTION_REWIND_5S: if (d==0) {
+ int p=ch.getPosition();
+ ch.setPosition(MAX(0,(p-5000)));
+ }
+ break;
+
+ case ACTION_FFWD_5S: if (d==0) {
+ int p=ch.getPosition();
+ int mp=ch.getLength();
+ ch.setPosition(MIN(mp,(p+5000)));
+ }
+ break;
+
+ case ACTION_EQ_AUTO:
+ if (d==0) ch.setEqAuto(!ch.getEqAuto());
+ break;
+
+ case ACTION_EQ_RESET: {
+ if (d==0) for(int i=0;i<10;i++) ch.setEqBand(i,0);
+ }
+ break;
+
+ case ACTION_EQ_TOGGLE: if (d==0) ch.setEqStatus(!ch.getEqStatus()); break;
+
+ case ACTION_MUTE: if (d==0) {
+ ch.setMute(!ch.getMute());;
+ }
+ break;
+
+ case ACTION_TOGGLE_REPEAT:
+ case ACTION_TOGGLE_SHUFFLE: if (d==0) {
+ // {45F3F7C1-A6F3-4ee6-A15E-125E92FC3F8D}
+ const GUID pledit_guid =
+ { 0x45f3f7c1, 0xa6f3, 0x4ee6, { 0xa1, 0x5e, 0x12, 0x5e, 0x92, 0xfc, 0x3f, 0x8d } };
+ CfgItem *pli=WASABI_API_CONFIG->config_getCfgItemByGuid(pledit_guid);
+ if(pli) {
+ if(pvtid==ACTION_TOGGLE_REPEAT) pli->setDataAsInt("Repeat",!pli->getDataAsInt("Repeat"));
+ if(pvtid==ACTION_TOGGLE_SHUFFLE) pli->setDataAsInt("Shuffle",!pli->getDataAsInt("Shuffle"));
+ }
+ }
+ break;
+
+ case ACTION_TOGGLE_CROSSFADER: if (d==0) {
+ // {FC3EAF78-C66E-4ED2-A0AA-1494DFCC13FF}
+ const GUID xfade_guid =
+ { 0xFC3EAF78, 0xC66E, 0x4ED2, { 0xA0, 0xAA, 0x14, 0x94, 0xDF, 0xCC, 0x13, 0xFF } };
+ CfgItem *pli=WASABI_API_CONFIG->config_getCfgItemByGuid(xfade_guid);
+ if(pli) pli->setDataAsInt("Enable crossfading",!pli->getDataAsInt("Enable crossfading"));
+ }
+ break;
+ }
+ if (pvtid >= ACTION_PLAY_CD && pvtid < ACTION_PLAY_CD+16) if (d==0) {
+ const GUID cdda_guid =
+ { 0x86b40069, 0x126f, 0x4e11, { 0xa8, 0x7f, 0x55, 0x8f, 0xfa, 0x3d, 0xff, 0xa8 } };
+#if 0//BU: need some api to send messages like this
+ ComponentManager::sendNotify(cdda_guid, 12345, pvtid-ACTION_PLAY_CD);
+#endif
+ }
+ return 1;
+}
+
+const char *CoreActions::getHelp(int action) {
+ static String name;
+ switch (action) {
+ case ACTION_PREV: name = _("Previous track"); break;
+ case ACTION_PAUSE: name = _("Pause/Resume playback"); break;
+ case ACTION_STOP: name = _("Stop playback"); break;
+ case ACTION_NEXT: name = _("Next track"); break;
+ case ACTION_EJECT: name = _("Load file"); break;
+ case ACTION_EJECTURL: name = _("Load URL"); break;
+ case ACTION_EJECTDIR: name = _("Load directory"); break;
+ case ACTION_SEEK: name = _("Seek"); break;
+ case ACTION_VOLUME: name = _("Volume"); break;
+ case ACTION_PAN: name = _("Panning"); break;
+ case ACTION_EQ_TOGGLE: name = _("Toggle equalizer"); break;
+ case ACTION_EQ_PREAMP: name = _("Toggle preamplifier"); break;
+ case ACTION_EQ_BAND: name = _("Change equalizer band"); break;
+ case ACTION_EQ_AUTO: name = _("Auto equalizer"); break;
+ case ACTION_EQ_RESET: name = _("Reset equalizer"); break;
+ case ACTION_VOLUME_UP: name = _("Volume up"); break;
+ case ACTION_VOLUME_DOWN: name = _("Volume down"); break;
+ case ACTION_REWIND_5S: name = _("Rewind 5 seconds"); break;
+ case ACTION_FFWD_5S: name = _("Fast forward 5 seconds"); break;
+ case ACTION_MUTE: name = _("Mute/Unmute sound"); break;
+ case ACTION_TOGGLE_REPEAT: name = _("Toggle repeat"); break;
+ case ACTION_TOGGLE_SHUFFLE: name = _("Toggle shuffle"); break;
+ case ACTION_TOGGLE_CROSSFADER: name = _("Toggle crossfader"); break;
+ }
+ return name;
+}
diff --git a/Src/Wasabi/api/core/coreactions.h b/Src/Wasabi/api/core/coreactions.h
new file mode 100644
index 00000000..81abc37d
--- /dev/null
+++ b/Src/Wasabi/api/core/coreactions.h
@@ -0,0 +1,47 @@
+#ifndef __COREACTIONS_H
+#define __COREACTIONS_H
+
+#include <api/service/svcs/svc_action.h>
+
+class CoreActions : public svc_actionI {
+ public :
+ CoreActions();
+ virtual ~CoreActions();
+
+ static const char *getServiceName() { return "Core Actions"; }
+ virtual int onActionId(int pvtid, const wchar_t *action, const wchar_t *param=NULL, int p1=0, int p2=0, void *data=NULL, int datalen=0, ifc_window *source=NULL);
+ virtual const wchar_t *getHelp(int action);
+
+ private:
+
+ enum {
+ ACTION_PREV = 0,
+ ACTION_PLAY,
+ ACTION_PAUSE,
+ ACTION_STOP,
+ ACTION_NEXT,
+ ACTION_EJECT,
+ ACTION_EJECTURL,
+ ACTION_EJECTDIR,
+ ACTION_SEEK,
+ ACTION_VOLUME,
+ ACTION_EQ_TOGGLE,
+ ACTION_EQ_PREAMP,
+ ACTION_EQ_BAND,
+ ACTION_VOLUME_UP,
+ ACTION_VOLUME_DOWN,
+ ACTION_REWIND_5S,
+ ACTION_FFWD_5S,
+ ACTION_PLAY_CD,
+ ACTION_EQ_AUTO = ACTION_PLAY_CD+16,
+ ACTION_EQ_RESET,
+ ACTION_PAN,
+ ACTION_MUTE,
+ ACTION_TOGGLE_REPEAT,
+ ACTION_TOGGLE_SHUFFLE,
+ ACTION_TOGGLE_CROSSFADER,
+ ACTION_PREFS,
+ };
+};
+
+#endif
diff --git a/Src/Wasabi/api/core/corehandle.cpp b/Src/Wasabi/api/core/corehandle.cpp
new file mode 100644
index 00000000..492ef910
--- /dev/null
+++ b/Src/Wasabi/api/core/corehandle.cpp
@@ -0,0 +1,304 @@
+#include <precomp.h>
+
+#include "corehandle.h"
+
+#include <api/api.h>
+#include <api/core/buttons.h>
+#include <api/service/svcs/svc_coreadmin.h>
+#include <api/service/svc_enum.h> // for castService
+
+using namespace UserButton;
+
+static svc_coreAdmin *da_coreadmin=NULL;
+static int instancecount=0;
+
+static void initDaCoreAdmin() {
+ if(!da_coreadmin) {
+ if (WASABI_API_SVC != NULL) {
+ waServiceFactory *s=WASABI_API_SVC->service_enumService(WaSvc::COREADMIN,0);
+ if (s != NULL) {
+//CUT ASSERTPR(s,"Core Admin non present!");
+ da_coreadmin=castService<svc_coreAdmin>(s);
+ }
+ }
+ }
+}
+
+CoreHandle::CoreHandle(CoreToken tok) {
+ initDaCoreAdmin();
+ instancecount++;
+ createdcore=0;
+ token = NO_CORE_TOKEN;
+ if (da_coreadmin) {
+ if(da_coreadmin->verifyToken(tok)) token=tok;
+ else {
+ token=da_coreadmin->createCore();
+ createdcore=1;
+ }
+ }
+}
+
+CoreHandle::CoreHandle(const char *name) {
+ initDaCoreAdmin();
+ instancecount++;
+ createdcore=0;
+ token = NO_CORE_TOKEN;
+ if (da_coreadmin) {
+ token=da_coreadmin->nameToToken(name);
+ if(token==-1) {
+ token=da_coreadmin->createCore(name);
+ createdcore=1;
+ }
+ }
+}
+
+CoreHandle::~CoreHandle() {
+ instancecount--;
+ if (da_coreadmin) {
+ if(createdcore) da_coreadmin->freeCoreByToken(token);
+ if(!instancecount) {
+ WASABI_API_SVC->service_release(da_coreadmin);
+ da_coreadmin=NULL;
+ }
+ }
+}
+
+int CoreHandle::isCoreLoaded() {
+ if (!da_coreadmin) return FALSE;
+ return TRUE;
+}
+
+int CoreHandle::setNextFile(const char *playstring, const char *destination) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->setNextFile(token, playstring, destination);
+}
+
+void CoreHandle::prev() {
+ userButton(PREV);
+}
+
+void CoreHandle::play() {
+ userButton(PLAY);
+}
+
+void CoreHandle::pause() {
+ userButton(PAUSE);
+}
+
+void CoreHandle::stop() {
+ userButton(STOP);
+}
+
+void CoreHandle::next() {
+ userButton(NEXT);
+}
+
+void CoreHandle::userButton(int button) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->userButton(token, button);
+}
+
+const char *CoreHandle::getSupportedExtensions() {
+ if (da_coreadmin == NULL) return "";
+ return da_coreadmin->getSupportedExtensions();
+}
+
+const char *CoreHandle::getExtSupportedExtensions() {
+ if (da_coreadmin == NULL) return "";
+ return da_coreadmin->getExtSupportedExtensions();
+}
+
+const char *CoreHandle::getExtensionFamily(const char *extension) {
+ if (da_coreadmin == NULL) return "";
+ return da_coreadmin->getExtensionFamily(extension);
+}
+
+void CoreHandle::registerExtension(const char *extensions, const char *extension_name) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->registerExtension(extensions, extension_name);
+}
+
+void CoreHandle::unregisterExtension(const char *extensions) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->unregisterExtension(extensions);
+}
+
+String CoreHandle::getTitle() {
+ if (da_coreadmin == NULL) return String("");
+ return String(da_coreadmin->getTitle(token));
+}
+
+int CoreHandle::getStatus() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getStatus(token);
+}
+
+const char *CoreHandle::getCurrent() {
+ if (da_coreadmin == NULL) return "";
+ return da_coreadmin->getCurrent(token);
+}
+
+int CoreHandle::getNumTracks() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getNumTracks(token);
+}
+
+int CoreHandle::getCurPlaybackNumber() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getCurPlaybackNumber(token);
+}
+
+int CoreHandle::getPosition() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getPosition(token);
+}
+
+int CoreHandle::getWritePosition() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getWritePosition(token);
+}
+
+int CoreHandle::setPosition(int ms) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->setPosition(token,ms);
+}
+
+int CoreHandle::getLength() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getLength(token);
+}
+
+int CoreHandle::getPluginData(const char *playstring, const char *name, char *data, int data_len, int data_type) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getPluginData(playstring, name, data, data_len, data_type);
+}
+
+unsigned int CoreHandle::getVolume() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getVolume(token);
+}
+
+void CoreHandle::setVolume(unsigned int vol) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setVolume(token, vol);
+}
+
+int CoreHandle::getPan() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getPan(token);
+}
+
+void CoreHandle::setPan(int bal) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setPan(token, bal);
+}
+
+void CoreHandle::setMute(int mute) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setMute(token, mute);
+}
+
+int CoreHandle::getMute() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getMute(token);
+}
+
+void CoreHandle::addCallback(CoreCallback *cb) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->addCallback(token, cb);
+}
+
+void CoreHandle::delCallback(CoreCallback *cb) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->delCallback(token, cb);
+}
+
+int CoreHandle::getVisData(void *dataptr, int sizedataptr) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getVisData(token, dataptr, sizedataptr);
+}
+
+int CoreHandle::getLeftVuMeter() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getLeftVuMeter(token);
+}
+
+int CoreHandle::getRightVuMeter() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getRightVuMeter(token);
+}
+
+int CoreHandle::registerSequencer(ItemSequencer *seq) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->registerSequencer(token, seq);
+}
+
+int CoreHandle::deregisterSequencer(ItemSequencer *seq) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->deregisterSequencer(token, seq);
+}
+
+ItemSequencer *CoreHandle::getSequencer() {
+ if (da_coreadmin == NULL) return NULL;
+ return da_coreadmin->getSequencer(token);
+}
+
+int CoreHandle::getEqStatus() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getEqStatus(token);
+}
+
+void CoreHandle::setEqStatus(int enable) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setEqStatus(token, enable);
+}
+
+int CoreHandle::getEqPreamp() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getEqPreamp(token);
+}
+
+void CoreHandle::setEqPreamp(int pre) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setEqPreamp(token, pre);
+}
+
+int CoreHandle::getEqBand(int band) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getEqBand(token, band);
+}
+
+void CoreHandle::setEqBand(int band, int val) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setEqBand(token, band, val);
+}
+
+int CoreHandle::getEqAuto() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getEqAuto(token);
+}
+
+void CoreHandle::setEqAuto(int enable) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setEqAuto(token, enable);
+}
+
+void CoreHandle::setPriority(int priority) {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->setPriority(token, priority);
+}
+
+int CoreHandle::getPriority() {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->getPriority(token);
+}
+
+void CoreHandle::rebuildConvertersChain() {
+ if (da_coreadmin == NULL) return;
+ da_coreadmin->rebuildConvertersChain(token);
+}
+
+int CoreHandle::sendConvertersMsg(const char *msg, const char *value) {
+ if (da_coreadmin == NULL) return 0;
+ return da_coreadmin->sendConvertersMsg(token, msg, value);
+}
diff --git a/Src/Wasabi/api/core/corehandle.h b/Src/Wasabi/api/core/corehandle.h
new file mode 100644
index 00000000..0dc09eac
--- /dev/null
+++ b/Src/Wasabi/api/core/corehandle.h
@@ -0,0 +1,560 @@
+#ifndef _COREHANDLE_H
+#define _COREHANDLE_H
+
+#include <api/syscb/callbacks/corecb.h>
+
+// a helper class to access the playback cores within an object for you
+
+typedef unsigned int CoreToken;
+#define NO_CORE_TOKEN (CoreToken)(0xffffffff)
+
+// Fwd References
+class CfgItem;
+class ItemSequencer;
+
+/**
+ Helper class to access the currently instantiated
+ playback cores.
+
+ To create a corehandle on the main playback core
+ use the core token value from the enum ("maincore_token") or
+ the core name "main".
+
+ Here is an example:
+ CoreHandle * ch = new CoreHandle("main");
+
+ @short Access playback cores.
+ @author Nullsoft
+ @ver 1.0
+ @see Core
+*/
+class CoreHandle {
+public:
+ enum { maincore_token=0 };
+
+ /**
+ Create a new CoreHandle while optionally
+ setting the core token to be used.
+
+ Core tokens are handles to cores
+ currently instantiated.
+
+ @see CoreHandle(const char *name)
+ @param token Core token of the core to attach to.
+ */
+ CoreHandle(CoreToken token=maincore_token);
+
+ /**
+ Create a new CoreHandle for a core
+ using it's name.
+
+ The main core name is "main".
+
+ @see CoreHandle(CoreToken toke=maincore_token)
+ @param name Name of the core to attach to.
+ */
+ CoreHandle(const wchar_t *name);
+
+ /**
+ Detaches the CoreHandle from the Core.
+ */
+ virtual ~CoreHandle();
+
+ int isCoreLoaded(); // are we attached to a core?
+
+ /**
+ Get the list of supported extensions
+ from the core. This is a zero delimited list
+ with double zero termination.
+
+ @see getExtSupportedExtensions()
+ @see getExtensionFamily()
+ @ret List of supported extensions.
+ */
+ const char *getSupportedExtensions(); //just the *.mp3 or whatever
+
+ /**
+ Get the extended list of supported extensions
+ from the core. This will include the proper
+ names of the extensions, for example:
+ "MP3 Files (*.mp3)".
+
+ This is returned as a zero delimited list with double
+ zero termination.
+
+ @see getSupportedExtensions()
+ @see getExtensionFamily()
+ @ret Extended list of supported extensions.
+ */
+ const char *getExtSupportedExtensions(); // including names
+
+ /**
+ Get the family name to which the extension
+ is associated with (Families are "Audio", "Video", etc.)
+
+ @see getExtSupportedExtensions()
+ @see getSupportedExtensions()
+ @ret Family name of the extension.
+ @param extension Extension to get family name of.
+ */
+ const wchar_t *getExtensionFamily(const wchar_t *extension);
+
+ /**
+ Register an extension with the core.
+
+ @see unregisterExtension()
+ @see getExtSupportedExtensions()
+ @see getSupportedExtensions()
+ @see getExtensionFamily()
+ @param extensions Extension to register.
+ @param extension_name Name of the extension.
+ */
+ void registerExtension(const char *extensions, const char *extension_name);
+
+ /**
+ Unregister an extension with the core.
+
+ @see registerExtension()
+ @see getExtSupportedExtensions()
+ @see getSupportedExtensions()
+ @see getExtensionFamily()
+ @param extensions Extension to unregister.
+ */
+ void unregisterExtension(const char *extensions);
+
+ String getTitle();
+
+ /**
+ Set the next file to be played by the core.
+
+ You can manually select the output of this
+ file. Either "WAVEOUT" or "DIRECTSOUND". If
+ you do not specify one, it will be automatically
+ selected for you.
+
+ @ret 1, success; 0, failure;
+ @param playstring Playstring of the next file to be played.
+ @param destination Output to be used for the next file.
+ */
+ int setNextFile(const char *playstring, const char *destination=NULL);
+
+ /**
+ Get the playback status of the core.
+
+ @see pause()
+ @see play()
+ @see stop()
+ @ret -1, Paused; 0, Stopped; 1, Playing;
+ */
+ int getStatus(); // returns -1 if paused, 0 if stopped and 1 if playing
+
+ /**
+ Get the playstring of the currently playing
+ item.
+
+ @ret Playstring of the currently playing item.
+ */
+ const char *getCurrent();
+
+ /**
+ Get the number of items (tracks) present
+ in the currently registered sequencer.
+
+ @see getCurPlaybackNumber()
+ @ret Number of items present in the sequencer.
+ */
+ int getNumTracks();
+
+ /**
+ Get the index number of the currently
+ playing item of the currently registered
+ sequencer.
+
+ @see getNumTracks()
+ @ret Index number (in the sequencer) of the item playing.
+ */
+ int getCurPlaybackNumber();
+
+ /**
+ Get the playback position of the currently
+ playing file.
+
+ @see getWritePosition()
+ @see getLength()
+ @see setPosition()
+ @ret Position in the file (in milliseconds).
+ */
+ int getPosition();
+
+ /**
+ Help?
+
+ @see getPosition()
+ @see getLength()
+ @see setPosition()
+ @ret Current write position (in milliseconds).
+ */
+ int getWritePosition();
+
+ /**
+ Seek to a specific position in the
+ currently playing item.
+
+ @see getPosition()
+ @see getLength()
+ @see getWritePosition()
+ @ret 1, Success; 0, Failure;
+ @param ms Position in the file (in milliseconds, 0 being the beginning).
+ */
+ int setPosition(int ms);
+
+ /**
+ Get the length of the currently
+ playing item.
+
+ @see getPosition()
+ @see setPosition()
+ @see getWritePosition()
+ @ret Length of the item (in milliseconds).
+ */
+ int getLength();
+
+ // this method queries the core plugins directly, bypassing the db
+ /**
+ */
+ int getPluginData(const char *playstring, const char *name,
+ char *data, int data_len, int data_type=0); // returns size of data
+
+ /**
+ Get the volume of the core.
+
+ @see setVolume()
+ @see getMute()
+ @see setMute()
+ @ret Volume (0 to 255).
+ */
+ unsigned int getVolume(); // 0..255
+
+ /**
+ Set the volume of the core.
+
+ @see getVolume()
+ @see getMute()
+ @see setMute()
+ @param vol Volume (0 to 255).
+ */
+ void setVolume(unsigned int vol); // 0..255
+
+ /**
+ Get the panning value of the core.
+
+ @see setPan()
+ @ret Panning value (-127 [left] to 127 [right]).
+ */
+ int getPan(); // -127..127
+
+ /**
+ Set the panning value of the core.
+
+ @see getPan()
+ @param bal Panning value (-127 [left] to 127 [right])
+ */
+ void setPan(int bal); // -127..127
+
+ /**
+ Mute the output.
+
+ @see getVolume()
+ @see setVolume()
+ @see getMute()
+ @param mute 0, No muting; 1, Mute;
+ */
+ void setMute(int mute);
+
+ /**
+ Get the mute state of the output.
+ @see getVolume()
+ @see setVolume()
+ @see setMute()
+ @ret 0, Not muted; 1, Muted;
+ */
+ int getMute();
+
+ // register here for general callbacks in core status.
+ /**
+ Register a callback with the core to
+ receive core status callbacks.
+
+ @see delCallback()
+ @param cb Core Callback to register.
+ */
+ void addCallback(CoreCallback *cb);
+
+ /**
+ Unregister a callback with the core.
+
+ @see addCallback()
+ @param cb Core Callback to unregister.
+ */
+ void delCallback(CoreCallback *cb);
+
+ // get visualization data, returns 0 if you should blank out
+ /**
+ Get visualization data for the currently
+ playing item.
+
+ We suggest using a struct like this to read the vis
+ data:
+
+ typedef struct {
+ enum {
+ LEFT = 0,
+ RIGHT = 1
+ };
+ unsigned char spectrumData[2][576];
+ char waveformData[2][576];
+ } VisData;
+
+ A call using this struct would like so:
+
+ getVisData(&myVisData, sizeof(VisData));
+
+ @see getLeftVuMeter()
+ @see getRightVuMeter()
+ @ret 0, If there is no VIS data; > 0, VIS data available;
+ @param dataptr Buffer to receive VIS data.
+ @param sizedataptr Size of the buffer.
+ */
+ int getVisData(void *dataptr, int sizedataptr);
+
+ /**
+ Get the value of the left VU meter.
+
+ @see getVisData()
+ @see getRightVuMeter()
+ @ret Value of the left VU meter (0 to 255).
+ */
+ int getLeftVuMeter();
+
+ /**
+ Get the value of the left VU meter.
+
+ @see getVisData()
+ @see getLeftVuMeter()
+ @ret Value of the right VU meter (0 to 255).
+ */
+ int getRightVuMeter();
+
+ /**
+ Register an item sequencer with the core.
+ The item sequencer feeds the playstrings
+ of the next item to be played to the core.
+
+ @see deregisterSequencer()
+ @ret 1, Success; 0, Failure;
+ @param seq Sequencer to register.
+ */
+ int registerSequencer(ItemSequencer *seq);
+
+ /**
+ Unregister a sequencer with the core.
+
+ @see registerSequencer()
+ @ret 1, Success; 0, Failure;
+ @param seq Sequencer to unregister.
+ */
+ int deregisterSequencer(ItemSequencer *seq);
+
+ ItemSequencer *getSequencer();
+
+ /**
+ Get the EQ status.
+
+ @see setEqStatus()
+ @see getEqPreamp()
+ @see setEqPreamp()
+ @see getEqBand()
+ @see setEqBand()
+ @ret 1, On; 0, Off;
+ */
+ int getEqStatus(); // returns 1 if on, 0 if off
+
+ /**
+ Set the EQ state.
+
+ @see getEqStatus()
+ @see getEqPreamp()
+ @see setEqPreamp()
+ @see getEqBand()
+ @see setEqBand()
+ @param enable 1, On; 0, Off;
+ */
+ void setEqStatus(int enable);
+
+ /**
+ Get the pre-amp value of the EQ.
+
+ @see setEqStatus()
+ @see getEqStatus()
+ @see setEqPreamp()
+ @see getEqBand()
+ @see setEqBand()
+ @ret Pre-amp value (-127 [-20dB] to 127 [+20dB]).
+ */
+ int getEqPreamp(); // -127 to 127 (-20db to +20db)
+
+ /**
+ Set the pre-amp value of the EQ.
+
+ @see setEqStatus()
+ @see getEqStatus()
+ @see getEqPreamp()
+ @see getEqBand()
+ @see setEqBand()
+ @param pre Pre-amp value (-127 [-20dB] to 127 [+20dB]).
+ */
+ void setEqPreamp(int pre);
+
+ /**
+ Get the value of an EQ band. There
+ are 10 bands available.
+
+ Here is the list:
+
+ 0 - 60 Hz 1 - 170 Hz
+ 2 - 310 Hz 3 - 600 Hz
+ 4 - 1 kHz 5 - 3 kHz
+ 6 - 6 kHz 7 - 12 kHz
+ 8 - 14 kHz 9 - 16 kHz
+
+ @see setEqStatus()
+ @see getEqStatus()
+ @see getEqPreamp()
+ @see setEqBand()
+ @ret EQ band value (-127 [-20dB] to 127 [+20dB]).
+ @param band EQ band to read (0 to 9).
+ */
+ int getEqBand(int band); // band=0-9
+
+ /**
+ Set the value of an EQ band. There
+ are 10 bands available.
+
+ Here is the list:
+
+ 0 - 60 Hz 1 - 170 Hz
+ 2 - 310 Hz 3 - 600 Hz
+ 4 - 1 kHz 5 - 3 kHz
+ 6 - 6 kHz 7 - 12 kHz
+ 8 - 14 kHz 9 - 16 kHz
+
+ @see setEqStatus()
+ @see getEqStatus()
+ @see getEqPreamp()
+ @see setEqBand()
+ @param band EQ band to set (0 to 9)
+ @param val EQ band value (-127 [-20dB] to 127 [+20dB]).
+ */
+ void setEqBand(int band, int val);
+
+ /**
+ Get the automatic EQ preset loading state.
+
+ @see setEqAuto()
+ @ret 1, On; 0, Off;
+ */
+ int getEqAuto(); // returns 1 if on, 0 if off
+
+ /**
+ Set the automatic EQ preset loading.
+
+ @see getEqAuto()
+ @param enable 1, On; 0, Off;
+ */
+ void setEqAuto(int enable);
+
+ /**
+ Trigger the previous event.
+
+ @see next()
+ @see play()
+ @see stop()
+ @see pause()
+ */
+ void prev();
+
+ /**
+ Trigger the play event.
+
+ @see prev()
+ @see next()
+ @see stop()
+ @see pause()
+ */
+ void play();
+
+ /**
+ Trigger the pause event.
+
+ @see prev()
+ @see next()
+ @see stop()
+ @see play()
+ */
+ void pause();
+
+ /**
+ Trigger the stop event.
+ */
+ void stop();
+
+ /**
+ Trigger the next event.
+
+ @see prev()
+ @see stop()
+ @see play()
+ @see pause()
+ */
+ void next();
+
+ /**
+ Set the thread priority of the core.
+
+ @see getPriority()
+ @param priority Thread priority.
+ */
+ void setPriority(int priority);
+
+ /**
+ Get the thread priority of the core.
+
+ @see setPriority()
+ @ret Thread priority level.
+ */
+ int getPriority();
+
+ /**
+ As the function name implies, rebuilds the converters chain (no shit?)
+ */
+ void rebuildConvertersChain();
+
+ /**
+ Send a message to all converters in the current
+ playback chain of a core.
+
+ It's possible to pass any pointer using this messanging
+ system, as long as the pointer is valid across dll boundries.
+
+ @param msg Message.
+ @param value Message value.
+ */
+ int sendConvertersMsg(const char *msg, const char *value);
+
+private:
+ void userButton(int button);
+ CoreToken token;
+ int createdcore;
+};
+
+#endif
diff --git a/Src/Wasabi/api/core/sequence.cpp b/Src/Wasabi/api/core/sequence.cpp
new file mode 100644
index 00000000..feea799a
--- /dev/null
+++ b/Src/Wasabi/api/core/sequence.cpp
@@ -0,0 +1,92 @@
+#include "precomp.h"
+
+#include "sequence.h"
+
+#define CBCLASS ItemSequencerI
+START_DISPATCH;
+ CB(GETDEPENDENCYPTR, getDependencyPtr);
+ CB(GETNEXTPLAYITEM, getNextPlayItem);
+ CB(GETCURRENTPLAYBACKNUMBER, getCurrentPlaybackNumber);
+ CB(GETNUMITEMS, getNumItems);
+ CB(REWIND, rewind);
+ CB(FORWARD, forward);
+ CB(ONNOTIFY, onNotify);
+END_DISPATCH;
+#undef CBCLASS
+
+int ItemSequencerI::onNotify(int msg, int param1, int param2) {
+ switch (msg) {
+ case SEQNOTIFY_ONREGISTER: return onRegister();
+ case SEQNOTIFY_ONDEREGISTER: return onDeregister();
+ case SEQNOTIFY_ONNEXTFILE: return onNextFile();
+ case SEQNOTIFY_ONTITLECHANGE: return onTitleChange();
+ case SEQNOTIFY_ONSTARTED: return onStarted();
+ case SEQNOTIFY_ONSTOPPED: return onStopped();
+ case SEQNOTIFY_ONPAUSED: return onPaused();
+ case SEQNOTIFY_ONUNPAUSED: return onUnpaused();
+ }
+ return 0;
+}
+
+const char *ListSequencer::getNextPlayItem() {
+ int pos;
+ const char *ret;
+
+ pos = getCurrent();
+
+ if (pos < 0) return NULL;
+
+ ret = enumItem(pos);
+
+ setCurrent(pos);
+
+ return ret;
+}
+
+int ListSequencer::rewind() {
+
+ int pos;
+
+ pos = getCurrent();
+
+ if (pos < 0) return 0;
+
+ pos--;
+
+ if (pos < 0) {
+ if (loop()) {
+ pos = getNumEntries()-1;
+ } else {
+ pos++;
+ }
+ }
+
+ setCurrent(pos);
+ return 1;
+}
+
+int ListSequencer::forward() {
+
+ int pos;
+
+ pos = getCurrent();
+
+ if (pos < 0) return 0;
+
+ pos++;
+
+ if (pos >= getNumEntries()) {
+ if (loop()) {
+ pos = 0;
+ } else {
+ return 0;
+ }
+ }
+
+ setCurrent(pos);
+ return 1;
+}
+
+int ListSequencer::getNumItems() {
+ return getNumEntries();
+}
diff --git a/Src/Wasabi/api/core/sequence.h b/Src/Wasabi/api/core/sequence.h
new file mode 100644
index 00000000..281cd541
--- /dev/null
+++ b/Src/Wasabi/api/core/sequence.h
@@ -0,0 +1,123 @@
+//PORTABLE
+#ifndef _SEQUENCE_H
+#define _SEQUENCE_H
+
+#include <bfc/dispatch.h>
+#include <bfc/depend.h>
+
+// abstracted version of a playback order
+class ItemSequencer : public Dispatchable {
+public:
+ api_dependent *getDependencyPtr();
+
+ const char *getNextPlayItem();
+ int getCurrentPlaybackNumber(); // 0-based, -1 if you don't know
+ int getNumItems(); // -1 if you don't know
+ int rewind();
+ int forward();
+
+ int onNotify(int msg, int param1=0, int param2=0);
+
+protected:
+ enum {
+ GETNEXTPLAYITEM=100,
+ GETCURRENTPLAYBACKNUMBER=101,
+ GETNUMITEMS=102,
+ REWIND=200,
+ FORWARD=210,
+ ONNOTIFY=300,
+ GETDEPENDENCYPTR=400,
+ };
+};
+
+inline api_dependent *ItemSequencer::getDependencyPtr() {
+ return _call(GETDEPENDENCYPTR, (api_dependent*)NULL);
+}
+
+inline const char *ItemSequencer::getNextPlayItem() {
+ return _call(GETNEXTPLAYITEM, (const char *)NULL);
+}
+
+inline
+int ItemSequencer::getCurrentPlaybackNumber() {
+ return _call(GETCURRENTPLAYBACKNUMBER, -1);
+}
+
+inline
+int ItemSequencer::getNumItems() {
+ return _call(GETNUMITEMS, -1);
+}
+
+inline int ItemSequencer::rewind() {
+ return _call(REWIND, 0);
+}
+
+inline int ItemSequencer::forward() {
+ return _call(FORWARD, 0);
+}
+
+inline int ItemSequencer::onNotify(int msg, int param1, int param2) {
+ return _call(ONNOTIFY, 0, msg, param1, param2);
+}
+
+#define SEQNOTIFY_ONREGISTER 10
+#define SEQNOTIFY_ONDEREGISTER 20
+#define SEQNOTIFY_ONNEXTFILE 30
+#define SEQNOTIFY_ONTITLECHANGE 40
+#define SEQNOTIFY_ONSTARTED 50
+#define SEQNOTIFY_ONSTOPPED 60
+#define SEQNOTIFY_ONPAUSED 70
+#define SEQNOTIFY_ONUNPAUSED 80
+
+// override this one
+class ItemSequencerI : public ItemSequencer, public DependentI {
+public:
+ api_dependent *getDependencyPtr() { return this; }
+
+ virtual int rewind()=0;
+ virtual int forward()=0;
+ virtual const char *getNextPlayItem()=0;
+ virtual int getCurrentPlaybackNumber() { return -1; }
+ virtual int getNumItems() { return -1; }
+
+ // these are optional callbacks
+ virtual int onRegister() { return 0; };
+ virtual int onDeregister() { return 0; };
+ virtual int onNextFile() { return 0; }// on transition
+ virtual int onTitleChange() { return 0; }
+ virtual int onStarted() { return 0; }
+ virtual int onStopped() { return 0; }
+ virtual int onPaused() { return 0; }
+ virtual int onUnpaused() { return 0; }
+
+protected:
+ // default implementation calls above callback methods based on msg
+ virtual int onNotify(int msg, int param1, int param2);
+
+ RECVS_DISPATCH;
+};
+
+// also somewhat abstract, but implements playing through some arbitrary
+// list. just override the protected stuff
+class ListSequencer : public ItemSequencerI {
+public:
+ virtual const char *getNextPlayItem();
+ virtual int rewind();
+ virtual int forward();
+
+protected:
+ // override these 4 only
+ virtual int getNumEntries()=0;
+ virtual const char *enumItem(int pos)=0;
+ virtual int getCurrent()=0;
+ virtual int setCurrent(int cur)=0;
+
+protected:
+ virtual int loop() { return 0; } // override as necessary
+
+private:
+ virtual int getNumItems(); // calls getNumEntries()
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/dependency/api_dependent.cpp b/Src/Wasabi/api/dependency/api_dependent.cpp
new file mode 100644
index 00000000..9ba862df
--- /dev/null
+++ b/Src/Wasabi/api/dependency/api_dependent.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "api_dependent.h" \ No newline at end of file
diff --git a/Src/Wasabi/api/dependency/api_dependent.h b/Src/Wasabi/api/dependency/api_dependent.h
new file mode 100644
index 00000000..23b7a54a
--- /dev/null
+++ b/Src/Wasabi/api/dependency/api_dependent.h
@@ -0,0 +1,54 @@
+#ifndef __WASABI_API_DEPENDENT_H
+#define __WASABI_API_DEPENDENT_H
+
+#include <bfc/dispatch.h>
+#include "api_dependentviewer.h"
+
+// we define some common event codes here. if your object needs more send
+// them as parameters to OBJECTSPECIFIC
+
+// some system-level codes for cb param. You can implement your own events
+// with DEPCB_EVENT and the parameters
+namespace DependentCB
+{
+ enum {
+ DEPCB_NOP = 0,
+ DEPCB_DELETED = 100, // object being deleted
+ DEPCB_EVENT = 1000, // object-specific event. use param1 etc to send your messages
+ };
+};
+
+class NOVTABLE ifc_dependent : public Dispatchable
+{
+protected:
+ ifc_dependent() {}
+ ~ifc_dependent() {}
+public:
+ void dependent_regViewer(ifc_dependentviewer *viewer, int add) ;
+ void *dependent_getInterface(const GUID *classguid);
+
+ DISPATCH_CODES
+ {
+ API_DEPENDENT_REGVIEWER = 10,
+ API_DEPENDENT_GETINTERFACE = 20,
+ };
+};
+
+inline void ifc_dependent::dependent_regViewer(api_dependentviewer *viewer, int add)
+ {
+ _voidcall(API_DEPENDENT_REGVIEWER, viewer, add);
+ }
+ inline void *ifc_dependent::dependent_getInterface(const GUID *classguid)
+ {
+ return _call(API_DEPENDENT_GETINTERFACE, (void *)0, classguid);
+ }
+
+
+// this is a helper for dependent_getInterface
+#define HANDLEGETINTERFACE(x) { \
+ if (*classguid == *x::depend_getClassGuid()) return static_cast<x *>(this); \
+ }
+
+typedef ifc_dependent api_dependent;
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/dependency/api_dependentviewer.cpp b/Src/Wasabi/api/dependency/api_dependentviewer.cpp
new file mode 100644
index 00000000..df550071
--- /dev/null
+++ b/Src/Wasabi/api/dependency/api_dependentviewer.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "api_dependentviewer.h" \ No newline at end of file
diff --git a/Src/Wasabi/api/dependency/api_dependentviewer.h b/Src/Wasabi/api/dependency/api_dependentviewer.h
new file mode 100644
index 00000000..160bac9d
--- /dev/null
+++ b/Src/Wasabi/api/dependency/api_dependentviewer.h
@@ -0,0 +1,30 @@
+#ifndef __WASABI_API_DEPENDENTVIEWER_H
+#define __WASABI_API_DEPENDENTVIEWER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+class ifc_dependent;
+
+class NOVTABLE ifc_dependentviewer : public Dispatchable
+{
+protected:
+ ifc_dependentviewer() {}
+ ~ifc_dependentviewer() {}
+public:
+ // item calls when it changes or disappears, or whatever
+ int dependentViewer_callback(ifc_dependent *item, const GUID *classguid, int cb, intptr_t param1 = 0, intptr_t param2 = 0, void *ptr = NULL, size_t ptrlen = 0);
+
+ DISPATCH_CODES
+ {
+ DEPENDENTVIEWER_CALLBACK = 10,
+ };
+};
+
+inline int ifc_dependentviewer::dependentViewer_callback(ifc_dependent *item, const GUID *classguid, int cb, intptr_t param1 , intptr_t param2 , void *ptr , size_t ptrlen)
+{
+ return _call(DEPENDENTVIEWER_CALLBACK, (int)0, item, classguid, cb, param1, param2, ptr, ptrlen);
+}
+
+typedef ifc_dependentviewer api_dependentviewer;
+
+#endif
diff --git a/Src/Wasabi/api/filereader/api_filereader.cpp b/Src/Wasabi/api/filereader/api_filereader.cpp
new file mode 100644
index 00000000..50b558b8
--- /dev/null
+++ b/Src/Wasabi/api/filereader/api_filereader.cpp
@@ -0,0 +1,20 @@
+#include <precomp.h>
+#include "api_filereader.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_fileReaderI
+START_DISPATCH;
+ CB(API_FILEREADER_FILEOPEN, fileOpen);
+ VCB(API_FILEREADER_FILECLOSE, fileClose);
+ CB(API_FILEREADER_FILEREAD, fileRead);
+ CB(API_FILEREADER_FILEWRITE, fileWrite);
+ CB(API_FILEREADER_FILESEEK, fileSeek);
+ CB(API_FILEREADER_FILETELL, fileTell);
+ CB(API_FILEREADER_FILEGETFILESIZE, fileGetFileSize);
+// CB(API_FILEREADER_FILEEXISTS, fileExists);
+ CB(API_FILEREADER_FILEREMOVE, fileRemove);
+ CB(API_FILEREADER_FILEREMOVEUNDOABLE, fileRemoveUndoable);
+ CB(API_FILEREADER_FILEMOVE, fileMove);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/filereader/api_filereader.h b/Src/Wasabi/api/filereader/api_filereader.h
new file mode 100644
index 00000000..427c276f
--- /dev/null
+++ b/Src/Wasabi/api/filereader/api_filereader.h
@@ -0,0 +1,104 @@
+#ifndef __API_FILEREADER_H
+#define __API_FILEREADER_H
+
+#include <bfc/dispatch.h>
+
+class NOVTABLE api_fileReader : public Dispatchable
+{
+ public:
+ void *fileOpen(const wchar_t *filename, OSFNCSTR mode);
+ void fileClose(void *fileHandle);
+ size_t fileRead(void *buffer, size_t size, void *fileHandle);
+ size_t fileWrite(const void *buffer, int size, void *fileHandle);
+ int fileSeek(int64_t offset, int origin, void *fileHandle);
+ uint64_t fileTell(void *fileHandle);
+ uint64_t fileGetFileSize(void *fileHandle);
+ //int fileExists(const wchar_t *filename);
+ int fileRemove(const wchar_t *filename);
+ int fileRemoveUndoable(const wchar_t *filename);
+ int fileMove(const wchar_t *filename, const wchar_t *destfilename);
+
+ enum {
+ API_FILEREADER_FILEOPEN = 0,
+ API_FILEREADER_FILECLOSE = 10,
+ API_FILEREADER_FILEREAD = 20,
+ API_FILEREADER_FILEWRITE = 30,
+ API_FILEREADER_FILESEEK = 40,
+ API_FILEREADER_FILETELL = 50,
+ API_FILEREADER_FILEGETFILESIZE = 60,
+ //API_FILEREADER_FILEEXISTS = 70,
+ API_FILEREADER_FILEREMOVE = 80,
+ API_FILEREADER_FILEREMOVEUNDOABLE = 90,
+ API_FILEREADER_FILEMOVE = 100,
+ };
+};
+
+inline void *api_fileReader::fileOpen(const wchar_t *filename, OSFNCSTR mode) {
+ return _call(API_FILEREADER_FILEOPEN, (void *)NULL, filename, mode);
+}
+
+inline void api_fileReader::fileClose(void *fileHandle) {
+ _voidcall(API_FILEREADER_FILECLOSE, fileHandle);
+}
+
+inline size_t api_fileReader::fileRead(void *buffer, size_t size, void *fileHandle) {
+ return _call(API_FILEREADER_FILEREAD, (size_t)0, buffer, size, fileHandle);
+}
+
+inline size_t api_fileReader::fileWrite(const void *buffer, int size, void *fileHandle) {
+ return _call(API_FILEREADER_FILEWRITE, (size_t)0, buffer, size, fileHandle);
+}
+
+inline int api_fileReader::fileSeek(int64_t offset, int origin, void *fileHandle) {
+ return _call(API_FILEREADER_FILESEEK, (int)0, offset, origin, fileHandle);
+}
+
+inline uint64_t api_fileReader::fileTell(void *fileHandle) {
+ return _call(API_FILEREADER_FILETELL, (uint64_t)0, fileHandle);
+}
+
+inline uint64_t api_fileReader::fileGetFileSize(void *fileHandle) {
+ return _call(API_FILEREADER_FILEGETFILESIZE, (uint64_t)0, fileHandle);
+}
+
+/*inline int api_fileReader::fileExists(const wchar_t *filename) {
+ return _call(API_FILEREADER_FILEEXISTS, (int)0, filename);
+}*/
+
+inline int api_fileReader::fileRemove(const wchar_t *filename) {
+ return _call(API_FILEREADER_FILEREMOVE, (int)0, filename);
+}
+
+inline int api_fileReader::fileRemoveUndoable(const wchar_t *filename) {
+ return _call(API_FILEREADER_FILEREMOVEUNDOABLE, (int)0, filename);
+}
+
+inline int api_fileReader::fileMove(const wchar_t *filename, const wchar_t *destfilename) {
+ return _call(API_FILEREADER_FILEMOVE, (int)0, filename, destfilename);
+}
+
+class api_fileReaderI : public api_fileReader {
+ public:
+ virtual void *fileOpen(const wchar_t *filename, const wchar_t *mode)=0;
+ virtual void fileClose(void *fileHandle)=0;
+ virtual size_t fileRead(void *buffer, size_t size, void *fileHandle)=0;
+ virtual int fileWrite(const void *buffer, int size, void *fileHandle)=0;
+ virtual int fileSeek(int64_t offset, int origin, void *fileHandle)=0;
+ virtual uint64_t fileTell(void *fileHandle)=0;
+ virtual uint64_t fileGetFileSize(void *fileHandle)=0;
+ //virtual int fileExists(const wchar_t *filename)=0;
+ virtual int fileRemove(const wchar_t *filename)=0;
+ virtual int fileRemoveUndoable(const wchar_t *filename)=0;
+ virtual int fileMove(const wchar_t *filename, const wchar_t *destfilename)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {E357E736-4967-4279-B948-5073A186F565}
+static const GUID fileReaderApiServiceGuid =
+{ 0xe357e736, 0x4967, 0x4279, { 0xb9, 0x48, 0x50, 0x73, 0xa1, 0x86, 0xf5, 0x65 } };
+
+extern api_fileReader *fileApi;
+
+#endif
diff --git a/Src/Wasabi/api/filereader/api_readercallback.h b/Src/Wasabi/api/filereader/api_readercallback.h
new file mode 100644
index 00000000..8d88a440
--- /dev/null
+++ b/Src/Wasabi/api/filereader/api_readercallback.h
@@ -0,0 +1,22 @@
+#ifndef __WASABI_API_READERCALLBACK_H
+#define __WASABI_API_READERCALLBACK_H
+
+#include <bfc/dispatch.h>
+
+class NOVTABLE api_readercallback : public Dispatchable
+{
+public:
+ void metaDataReader_onData(const char *data, int size);
+
+ enum
+ {
+ METADATAREADERONDATA = 10,
+ };
+};
+
+inline void api_readercallback::metaDataReader_onData(const char *data, int size)
+{
+ _voidcall(METADATAREADERONDATA, data, size);
+}
+
+#endif
diff --git a/Src/Wasabi/api/filereader/filereaderapi.cpp b/Src/Wasabi/api/filereader/filereaderapi.cpp
new file mode 100644
index 00000000..b6fec99c
--- /dev/null
+++ b/Src/Wasabi/api/filereader/filereaderapi.cpp
@@ -0,0 +1,53 @@
+#include <precomp.h>
+#include "filereaderapi.h"
+#include <api/filereader/local/fileread.h>
+
+api_fileReader *fileApi = NULL;
+
+
+FileReaderApi::FileReaderApi() {
+}
+
+FileReaderApi::~FileReaderApi() {
+}
+
+void *FileReaderApi::fileOpen(const wchar_t *filename, const wchar_t *mode) {
+ return FileReaders::open(filename, mode);
+}
+
+void FileReaderApi::fileClose(void *fileHandle) {
+ FileReaders::close(fileHandle);
+}
+
+size_t FileReaderApi::fileRead(void *buffer, size_t size, void *fileHandle) {
+ return FileReaders::read(buffer, size, fileHandle);
+}
+
+int FileReaderApi::fileWrite(const void *buffer, int size, void *fileHandle) {
+ return FileReaders::write(buffer, size, fileHandle);
+}
+
+int FileReaderApi::fileSeek(int64_t offset, int origin, void *fileHandle) {
+ return FileReaders::seek(offset, origin, fileHandle);
+}
+
+uint64_t FileReaderApi::fileTell(void *fileHandle) {
+ return FileReaders::tell(fileHandle);
+}
+
+uint64_t FileReaderApi::fileGetFileSize(void *fileHandle) {
+ return FileReaders::getFileSize(fileHandle);
+}
+
+int FileReaderApi::fileRemove(const wchar_t *filename) {
+ return FileReaders::remove(filename);
+}
+
+int FileReaderApi::fileRemoveUndoable(const wchar_t *filename) {
+ return FileReaders::removeUndoable(filename);
+}
+
+int FileReaderApi::fileMove(const wchar_t *filename, const wchar_t *destfilename) {
+ return FileReaders::move(filename, destfilename);
+}
+
diff --git a/Src/Wasabi/api/filereader/filereaderapi.h b/Src/Wasabi/api/filereader/filereaderapi.h
new file mode 100644
index 00000000..ad3e30a0
--- /dev/null
+++ b/Src/Wasabi/api/filereader/filereaderapi.h
@@ -0,0 +1,25 @@
+#ifndef _FILEREADERAPI_H
+#define _FILEREADERAPI_H
+
+#include <api/filereader/api_filereader.h>
+
+class FileReaderApi : public api_fileReaderI
+{
+ public:
+ FileReaderApi();
+ virtual ~FileReaderApi();
+
+ virtual void *fileOpen(const wchar_t *filename, const wchar_t *mode);
+ virtual void fileClose(void *fileHandle);
+ virtual size_t fileRead(void *buffer, size_t size, void *fileHandle);
+ virtual int fileWrite(const void *buffer, int size, void *fileHandle);
+ virtual int fileSeek(int64_t offset, int origin, void *fileHandle);
+ virtual uint64_t fileTell(void *fileHandle);
+ virtual uint64_t fileGetFileSize(void *fileHandle);
+ //virtual int fileExists(const wchar_t *filename);
+ virtual int fileRemove(const wchar_t *filename);
+ virtual int fileRemoveUndoable(const wchar_t *filename);
+ virtual int fileMove(const wchar_t *filename, const wchar_t *destfilename);
+};
+
+#endif
diff --git a/Src/Wasabi/api/filereader/local/fileread.cpp b/Src/Wasabi/api/filereader/local/fileread.cpp
new file mode 100644
index 00000000..f1107f47
--- /dev/null
+++ b/Src/Wasabi/api/filereader/local/fileread.cpp
@@ -0,0 +1,132 @@
+#include <precomp.h>
+#include "fileread.h"
+#include <api/service/svc_enum.h>
+
+void *FileReaders::open(const wchar_t *filename, const wchar_t *mode) {
+ int m=0;
+
+ const wchar_t *p=mode;
+ wchar_t c;
+ while(c=*(p++))
+ {
+ switch(c)
+ {
+ case 'r': m=SvcFileReader::READ; break;
+ case 'w': m=SvcFileReader::WRITE; break;
+ case 'a': m=SvcFileReader::APPEND; break;
+ case '+': m|=SvcFileReader::PLUS; break;
+ case 'b': m|=SvcFileReader::BINARY; break;
+ case 't': m|=SvcFileReader::TEXT; break;
+ }
+ }
+
+ return FileReaderEnum(filename, m).getFirst();
+}
+
+void FileReaders::close(void *handle)
+{
+ svc_fileReader *fr=(svc_fileReader *)handle;
+ fr->close();
+ SvcEnum::release(fr);
+}
+
+size_t FileReaders::read(void *buffer, size_t size, void *handle)
+{
+ svc_fileReader *fr=(svc_fileReader *)handle;
+ return fr->read((int8_t *)buffer,size);
+}
+
+size_t FileReaders::write(const void *buffer, size_t size, void *handle)
+{
+ svc_fileReader *fr=(svc_fileReader *)handle;
+ return fr->write((int8_t *)buffer,size);
+}
+
+int FileReaders::seek(int64_t offset, int origin, void *handle)
+{
+ svc_fileReader *fr=(svc_fileReader *)handle;
+ if(!fr->canSeek()) return -1;
+ if(origin==SEEK_SET) return fr->seek(offset);
+ if(origin==SEEK_CUR) return fr->seek(fr->getPos()+offset);
+ return fr->seek(fr->getLength()-offset);
+}
+
+uint64_t FileReaders::tell(void *handle)
+{
+ svc_fileReader *fr=(svc_fileReader *)handle;
+ return fr->getPos();
+}
+
+uint64_t FileReaders::getFileSize(void *handle)
+{
+ svc_fileReader *fr=(svc_fileReader *)handle;
+ return fr->getLength();
+}
+
+int FileReaders::exists(const wchar_t *filename) {
+ // Note that we do not do a system lock on the service since we can just
+ // release it directly via the factory
+ waService *s;
+ for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
+ svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
+ if(fr->isMine(filename) == 1 || fr->open(filename)) {
+ int ret=fr->exists(filename);
+ fr->close();
+ s->releaseInterface(fr); fr = NULL;
+ return ret;
+ }
+ s->releaseInterface(fr); fr = NULL;
+ }
+ return 0;
+}
+
+int FileReaders::remove(const wchar_t *filename) {
+ // Note that we do not do a system lock on the service since we can just
+ // release it directly via the factory
+ waService *s;
+ for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
+ svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
+ if (fr->isMine(filename) == 1 || fr->open(filename)) {
+ fr->close();
+ int ret = fr->remove(filename);
+ s->releaseInterface(fr); fr = NULL;
+ return ret;
+ }
+ s->releaseInterface(fr); fr = NULL;
+ }
+ return 0;
+}
+
+int FileReaders::removeUndoable(const wchar_t *filename) {
+ // Note that we do not do a system lock on the service since we can just
+ // release it directly via the factory
+ waService *s;
+ for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
+ svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
+ if(fr->isMine(filename) == 1 || fr->open(filename)) {
+ fr->close();
+ int ret = fr->removeUndoable(filename);
+ s->releaseInterface(fr); fr = NULL;
+ return ret;
+ }
+ s->releaseInterface(fr); fr = NULL;
+ }
+ return 0;
+}
+
+int FileReaders::move(const wchar_t *filename, const wchar_t *destfilename) {
+ // Note that we do not do a system lock on the service since we can just
+ // release it directly via the factory
+ waService *s;
+ for(int i=0;s=WASABI_API_SVC->service_enumService(WaSvc::FILEREADER,i);i++) {
+ svc_fileReader *fr=(svc_fileReader *)s->getInterface(FALSE);
+ if(fr->isMine(filename) == 1 || fr->open(filename)) {
+ fr->close();
+ int ret = fr->move(filename,destfilename);
+ s->releaseInterface(fr); fr = NULL;
+ return ret;
+ }
+ s->releaseInterface(fr); fr = NULL;
+ }
+ return 0;
+}
diff --git a/Src/Wasabi/api/filereader/local/fileread.h b/Src/Wasabi/api/filereader/local/fileread.h
new file mode 100644
index 00000000..14c22f46
--- /dev/null
+++ b/Src/Wasabi/api/filereader/local/fileread.h
@@ -0,0 +1,23 @@
+#ifndef _FILEREADERS_H
+#define _FILEREADERS_H
+
+#include <api/filereader/svc_filereadI.h>
+#include <api/service/servicei.h>
+
+class FileReaders
+{
+public:
+ static void *open(const wchar_t *filename, const wchar_t *mode);
+ static void close(void *handle);
+ static size_t read(void *buffer, size_t size, void *handle);
+ static size_t write(const void *buffer, size_t size, void *handle);
+ static int seek(int64_t offset, int origin, void *handle);
+ static uint64_t tell(void *handle);
+ static uint64_t getFileSize(void *handle);
+ static int exists(const wchar_t *filename);
+ static int remove(const wchar_t *filename);
+ static int removeUndoable(const wchar_t *filename);
+ static int move(const wchar_t *filename, const wchar_t *destfilename);
+};
+
+#endif//_FILEREADERS_H
diff --git a/Src/Wasabi/api/filereader/svc_filereadI.h b/Src/Wasabi/api/filereader/svc_filereadI.h
new file mode 100644
index 00000000..27d4768b
--- /dev/null
+++ b/Src/Wasabi/api/filereader/svc_filereadI.h
@@ -0,0 +1,100 @@
+#ifndef __WASABI_SVC_FILEREADI_H
+#define __WASABI_SVC_FILEREADI_H
+
+#include <api/service/svcs/svc_fileread.h>
+#include <api/filereader/api_readercallback.h>
+// derive from this one
+class NOVTABLE svc_fileReaderI : public svc_fileReader
+{
+public:
+ virtual int isMine(const wchar_t *filename, int mode = SvcFileReader::READ) { return -1; }
+ virtual int open(const wchar_t *filename, int mode = SvcFileReader::READ) = 0; // return 1 on success
+ virtual size_t read(int8_t *buffer, size_t length) = 0; // return number of bytes read (if < length then eof)
+ virtual size_t write(const int8_t *buffer, size_t length) = 0; // return number of bytes written
+ virtual void close() = 0; //must be safe to call even when not open
+
+ virtual int canSetEOF() { return 0; }
+ virtual int setEOF(uint64_t newlen) { return -1; }
+
+ virtual void abort() { } // tells the reader to abort its current prebuffering/reader
+
+ virtual int getLength() { return -1; } // return -1 on unknown/infinite
+ virtual int getPos() = 0;
+
+ virtual int canSeek() { return 0; }
+ virtual int seek(uint64_t position) { return 0; }
+ virtual uint64_t bytesAvailable(uint64_t requested) { return requested; }
+
+ virtual int hasHeaders() { return 0; }
+ virtual const char *getHeader(const char *header) { return (const char *)NULL; }
+
+ virtual int exists(const wchar_t *filename) { return 0; } // return 1 if true, 0 if not, -1 if unknown
+
+ virtual int remove(const wchar_t *filename) { return 0; } // return 1 on success, 0 on error
+
+ virtual int removeUndoable(const wchar_t *filename) { return -1; }
+
+ virtual int move(const wchar_t *filename, const wchar_t *destfilename) { return 0; } // return 1 on success, 0 on error
+
+ virtual void setMetaDataCallback(api_readercallback *cb) { }
+
+ virtual int canPrefetch() { return 1; } // return 1 if your reader should prefetch infos about the file in pledit
+ // (HTTP reader will return 0 here for instance)
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+// derive from this one
+class NOVTABLE MetaDataReaderCallbackI : public api_readercallback {
+public:
+ virtual void metaDataReader_onData(const char *data, int size)=0;
+
+protected:
+#undef CBCLASS
+#define CBCLASS MetaDataReaderCallbackI
+START_DISPATCH_INLINE;
+ VCB(METADATAREADERONDATA, metaDataReader_onData);
+END_DISPATCH;
+#undef CBCLASS
+};
+
+#include <api/service/svcs/svc_redir.h>
+#include <bfc/std_file.h> // for WA_MAX_PATH but this needs to be in a better place
+
+#define MAX_FILEREADER_REDIRECT 256
+
+// note: this class handles both redirection and calling open()
+class FileReaderEnum : public SvcEnumT<svc_fileReader> {
+public:
+ FileReaderEnum(const wchar_t *filename, int mode=SvcFileReader::READ, int allow_redirect=FALSE) :
+ fn(filename), m(mode)
+ {
+ if (allow_redirect) {
+ for (int done = 0, c = 0; !done && c < MAX_FILEREADER_REDIRECT; done = 1, c++) {
+ RedirectEnum re(fn);
+ svc_redirect *svc;
+ while ((svc = re.getNext(FALSE)) != NULL) {
+ wchar_t buf[WA_MAX_PATH]=L"";
+ if (svc->redirect(fn, L"Filename", buf, WA_MAX_PATH)) {
+ fn = buf;
+ done = 0;
+ }
+ re.getLastFactory()->releaseInterface(svc);
+ }
+ }
+ }
+ }
+ virtual int testService(svc_fileReader *svc) {
+ if (!svc->isMine(fn)) return 0;
+ return !!svc->open(fn, m);
+ }
+
+private:
+ const wchar_t *fn;
+ int m;
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/filereader/zip/zipread.cpp b/Src/Wasabi/api/filereader/zip/zipread.cpp
new file mode 100644
index 00000000..f8c66c92
--- /dev/null
+++ b/Src/Wasabi/api/filereader/zip/zipread.cpp
@@ -0,0 +1,176 @@
+#include <precomp.h>
+#define REAL_STDIO
+#include "zipread.h"
+#include <zlib/unzip.h>
+#include <bfc/parse/pathparse.h>
+#include <api/skin/api_skin.h>
+
+#define UNZIPBUFSIZE 65536
+
+int ZipRead::open(const char *filename, int mode) {
+ unzFile f=NULL;
+ int success=0;
+
+ if (WASABI_API_SKIN == NULL) return 0;
+ PathParser pp1(WASABI_API_SKIN->getSkinsPath());
+ PathParser pp2(filename);
+ int v;
+ for (v=0;v<pp1.getNumStrings();v++)
+ if (!STRCASEEQLSAFE(pp1.enumString(v), pp2.enumString(v))) return 0;
+ String walName = pp2.enumString(v);
+ String file;
+ for (v=v+1;v<pp2.getNumStrings();v++) {
+ if (!file.isempty()) file.cat(DIRCHARSTR);
+ file += pp2.enumString(v);
+ }
+
+ // is there a zip file?
+ String zipName;
+ Std::fileInfoStruct zipFi;
+ if(!Std::getFileInfos(zipName=StringPrintf("%s%s.wal",WASABI_API_SKIN->getSkinsPath(),walName.getValue()),&zipFi) &&
+ !Std::getFileInfos(zipName=StringPrintf("%s%s.wsz",WASABI_API_SKIN->getSkinsPath(),walName.getValue()),&zipFi) &&
+ !Std::getFileInfos(zipName=StringPrintf("%s%s.zip",WASABI_API_SKIN->getSkinsPath(),walName.getValue()),&zipFi))
+ return 0; // zip not found
+
+ if(zipTmpDir.isempty()) {
+ char tmpPath[WA_MAX_PATH];
+ Std::getTempPath(sizeof(tmpPath)-1,tmpPath);
+ zipTmpDir=StringPrintf("%s_wa3sktmp",tmpPath);
+ Std::createDirectory(zipTmpDir);
+ }
+
+ // check in cached opened zip dirs
+ int badcrc=0;
+ for(int i=0;i<openedZipHandles.getNumItems();i++) {
+ if(!STRICMP(openedZipHandles[i].name->getValue(), walName)) {
+ if(!MEMCMP(&openedZipHandles[i].checksum,&zipFi,sizeof(zipFi))) {
+ // try to find it in the dezipped temp dir
+ handle=openInTempDir(walName,file);
+ if(handle) return 1;
+ else return 0;
+ } else {
+ // bad checksum
+ badcrc=1;
+ break;
+ }
+ }
+ }
+
+ // is the dezipped dir is here?
+ if(!badcrc) {
+ StringPrintf tmpf("%s%s%s%s_wa3chksum",zipTmpDir.getValue(),DIRCHARSTR,walName.getValue(),DIRCHARSTR);
+ FILE *fh=fopen(tmpf,"rb");
+ if(fh) {
+ Std::fileInfoStruct tmpFi={0,};
+ fread(&tmpFi,1,sizeof(tmpFi),fh);
+ fclose(fh);
+ if(!MEMCMP(&tmpFi,&zipFi,sizeof(tmpFi))) {
+ // checksum correct
+ openedZipEntry ze={new String(walName), new String(zipName)};
+ ze.checksum=tmpFi;
+ openedZipHandles.addItem(ze);
+ handle=openInTempDir(walName,file);
+ if(handle) return 1;
+ else return 0;
+ }
+ }
+ }
+
+ // not found, so try to find it in a zip file
+ f = unzOpen(zipName);
+ if(!f) return 0;
+
+ StringPrintf zDir("%s%s%s",zipTmpDir.getValue(),DIRCHARSTR,walName.getValue());
+ Std::removeDirectory(zDir,1);
+
+ // unpack the zip in temp folder
+ String dirmask;
+ unzGoToFirstFile(f);
+ Std::createDirectory(zDir);
+ do {
+ char filename[MAX_PATH];
+ unzGetCurrentFileInfo(f,NULL,filename,sizeof(filename),NULL,0,NULL,0);
+ if (unzOpenCurrentFile(f) == UNZ_OK) {
+ int l;
+ dirmask.printf("%s%s%s",zDir.getValue(),DIRCHARSTR,filename);
+ if (Std::isDirChar(dirmask.lastChar())) {
+ // create dir
+ Std::createDirectory(dirmask);
+ } else {
+ // create file
+ FILE *fp = fopen(dirmask,"wb");
+ if(!fp) {
+ String dir=dirmask;
+ char *p=(char *)Std::filename(dir);
+ if(p) {
+ *p=0;
+ Std::createDirectory(dir);
+ fp = fopen(dirmask,"wb");
+ }
+ }
+ if (fp) {
+ do {
+ MemBlock<char> buf(UNZIPBUFSIZE);
+ l=unzReadCurrentFile(f,buf.getMemory(),buf.getSizeInBytes());
+ if (l > 0) fwrite(buf.getMemory(),1,l,fp);
+ } while (l > 0);
+ fclose(fp);
+ success=1;
+ }
+ }
+ if (unzCloseCurrentFile(f) == UNZ_CRCERROR) success=0;
+ }
+ } while (unzGoToNextFile(f) == UNZ_OK);
+ unzClose(f);
+
+ // write the checksum file
+ Std::fileInfoStruct fi;
+ Std::getFileInfos(zipName, &fi);
+ FILE *fh=fopen(StringPrintf("%s%s_wa3chksum",zDir.getValue(),DIRCHARSTR),"wt");
+ fwrite(&fi,1,sizeof(fi),fh);
+ fclose(fh);
+
+ openedZipEntry ze={new String(walName), new String(zipName)};
+ ze.checksum=fi;
+ openedZipHandles.addItem(ze);
+
+ // try to find it (again) in the dezipped temp dir
+ handle=openInTempDir(walName,file);
+ if(handle) return 1;
+ return 0;
+}
+
+FILE *ZipRead::openInTempDir(const char *walName, const char *file) {
+ StringPrintf tmpf("%s%s%s%s%s",zipTmpDir.getValue(),DIRCHARSTR,walName,DIRCHARSTR,file);
+ FILE *fh=fopen(tmpf,"rb");
+ if(fh) return fh;
+ // okay maybe the file isn't in the root dir of the zip file
+ fh=fopen(StringPrintf("%s%s%s%s%s%s%s",zipTmpDir.getValue(),DIRCHARSTR,walName,DIRCHARSTR,walName,DIRCHARSTR,file),"rb");
+ if(fh) return fh;
+ // definitely not here
+ return 0;
+}
+
+void ZipRead::close() {
+ fclose(handle);
+}
+
+int ZipRead::read(char *buffer, int size) {
+ return fread(buffer,1,size,handle);
+}
+
+int ZipRead::getPos() {
+ return ftell(handle);
+}
+
+int ZipRead::getLength() {
+ int pos=ftell(handle);
+ fseek(handle,0,SEEK_END);
+ int length=ftell(handle);
+ fseek(handle,pos,SEEK_SET);
+ return length;
+}
+
+using namespace wasabi;
+
+TList<ZipRead::openedZipEntry> ZipRead::openedZipHandles;;
diff --git a/Src/Wasabi/api/filereader/zip/zipread.h b/Src/Wasabi/api/filereader/zip/zipread.h
new file mode 100644
index 00000000..7210e6bd
--- /dev/null
+++ b/Src/Wasabi/api/filereader/zip/zipread.h
@@ -0,0 +1,39 @@
+#ifndef _ZIPREAD_H
+#define _ZIPREAD_H
+
+#include <api/service/svcs/svc_fileread.h>
+#include <api/service/servicei.h>
+#include <bfc/memblock.h>
+#include <bfc/string/string.h>
+#include <bfc/ptrlist.h>
+#include <bfc/tlist.h>
+
+class ZipRead : public svc_fileReaderI {
+public:
+ // service
+ static const char *getServiceName() { return "ZIP file reader"; }
+
+ int open(const char *filename, int mode=SvcFileReader::READ);
+ int read(char *buffer, int length);
+ int write(const char *buffer, int length) { return 0; }
+ void close();
+ int getPos();
+ int getLength();
+
+private:
+ FILE *openInTempDir(const char *walName, const char *file);
+
+ typedef struct {
+ String *name;
+ String *zipName;
+ Std::fileInfoStruct checksum;
+ } openedZipEntry;
+
+ static wasabi::TList<openedZipEntry> openedZipHandles;
+
+ String zipTmpDir;
+
+ FILE *handle;
+};
+
+#endif//_ZIPREAD_H
diff --git a/Src/Wasabi/api/font/FontCreator.h b/Src/Wasabi/api/font/FontCreator.h
new file mode 100644
index 00000000..086ea933
--- /dev/null
+++ b/Src/Wasabi/api/font/FontCreator.h
@@ -0,0 +1,7 @@
+#include <api/service/svcs/svc_font.h>
+template <class T>
+class FontCreator : public waServiceFactoryT<svc_font, T>
+{
+public:
+ FontCreator(GUID myGuid = INVALID_GUID) : waServiceFactoryT<svc_font, T>(myGuid) {}
+};
diff --git a/Src/Wasabi/api/font/FontSvcEnum.h b/Src/Wasabi/api/font/FontSvcEnum.h
new file mode 100644
index 00000000..c01cc9cc
--- /dev/null
+++ b/Src/Wasabi/api/font/FontSvcEnum.h
@@ -0,0 +1,18 @@
+#include <bfc/string/StringW.h>
+#include <api/service/svc_enum.h>
+
+class FontSvcEnum : public SvcEnumT<svc_font> {
+public:
+ FontSvcEnum(const wchar_t *_svc_name = NULL) : svc_name(_svc_name) {}
+protected:
+ virtual int testService(svc_font *svc)
+ {
+ if (!svc_name.len())
+ return 1; // blank name returns all services.
+ return (!WCSICMP(svc->getFontSvcName(),svc_name));
+ }
+private:
+ StringW svc_name;
+};
+
+
diff --git a/Src/Wasabi/api/font/api_font.cpp b/Src/Wasabi/api/font/api_font.cpp
new file mode 100644
index 00000000..1fd7c551
--- /dev/null
+++ b/Src/Wasabi/api/font/api_font.cpp
@@ -0,0 +1,11 @@
+#include <precomp.h>
+#include "api_font.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_fontI
+START_DISPATCH;
+ VCB(API_FONT_FONT_TEXTOUT, font_textOut);
+ CB(API_FONT_FONT_GETINFO, font_getInfo);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/font/api_font.h b/Src/Wasabi/api/font/api_font.h
new file mode 100644
index 00000000..cea0bac1
--- /dev/null
+++ b/Src/Wasabi/api/font/api_font.h
@@ -0,0 +1,36 @@
+#ifndef __API_FONT_H
+#define __API_FONT_H
+
+#include <bfc/dispatch.h>
+
+class ifc_canvas;
+
+class NOVTABLE api_font : public Dispatchable
+{
+ public:
+ void font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt);
+ int font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h);
+
+ enum {
+ API_FONT_FONT_TEXTOUT = 0,
+ API_FONT_FONT_GETINFO = 10,
+ };
+};
+
+inline void api_font::font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt)
+{
+ _voidcall(API_FONT_FONT_TEXTOUT, c, style, x, y, w, h, txt);
+}
+
+inline int api_font::font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h)
+{
+ return _call(API_FONT_FONT_GETINFO, (int)0, c, font, infoid, txt, w, h);
+}
+
+// {1FCA9C7E-5923-4b9c-8906-0F8C331DF21C}
+static const GUID fontApiServiceGuid =
+{ 0x1fca9c7e, 0x5923, 0x4b9c, { 0x89, 0x6, 0xf, 0x8c, 0x33, 0x1d, 0xf2, 0x1c } };
+
+extern api_font *fontApi;
+
+#endif
diff --git a/Src/Wasabi/api/font/bitmapfont.cpp b/Src/Wasabi/api/font/bitmapfont.cpp
new file mode 100644
index 00000000..fe85abda
--- /dev/null
+++ b/Src/Wasabi/api/font/bitmapfont.cpp
@@ -0,0 +1,394 @@
+#include "precomp.h"
+// ============================================================================================================================================================
+// Font abstract class + statics to install TT fonts and Bitmap fonts
+// ============================================================================================================================================================
+#include "bitmapfont.h"
+#include <api/wnd/fontdef.h>
+#include <api/config/items/cfgitem.h>
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/skin.h>
+#endif
+#ifdef WA3COMPATIBILITY
+#endif
+
+#include <tataki/canvas/ifc_canvas.h>
+#include <tataki/region/api_region.h>
+#include <api/skin/skinparse.h>
+
+// ============================================================================================================================================================
+// BitmapFont implementation.
+// ============================================================================================================================================================
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+BitmapFont::BitmapFont() : scriptid(0), char_width(0), char_height(0), hor_spacing(0), vert_spacing(0) {
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+BitmapFont::~BitmapFont() {
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::isBitmap() {
+ return 1;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+const wchar_t *BitmapFont::getFaceName() {
+ return getFontId();
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, -1, -1, txt, size, bold, opaque, underline, italic, STDFONT_LEFT, color, WA_FONT_TEXTOUT_NORMAL);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOut2(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, y+yoffset+h, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_RECT);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, y+yoffset+h, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_ELLIPSED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, y+yoffset+h, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_WRAPPED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, x+xoffset, y+yoffset, x+xoffset+w, -1, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_WRAPPEDPATHED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased) {
+ do_textOut(this, c, r->left, r->top, r->right-r->left, r->bottom-r->top, txt, size, bold, opaque, underline, italic, align, color, WA_FONT_TEXTOUT_CENTERED);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
+{
+ return wcslen(text) * char_width + wcslen(text)*hor_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
+{
+ return char_height;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased)
+{
+ return char_height;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialiased)
+{
+ if (w) *w = getTextWidth(c, text, size, bold, underline, italic, antialiased);
+ if (h) *h = char_height;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::setFontBitmap(const wchar_t *name_or_element, const wchar_t *path)
+{
+ StringW pathfile;
+ if (!wcschr(name_or_element, L':'))
+ {
+ pathfile = path;
+ pathfile.AddBackslash();
+ }
+ pathfile.cat(name_or_element);
+ if (!WACCESS(pathfile, 0))
+ table = pathfile;
+ else
+ table = name_or_element;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::setFontMetrics(int _char_width, int _char_height, int _hor_spacing, int _vert_spacing) {
+ char_width = _char_width;
+ char_height = _char_height;
+ hor_spacing = _hor_spacing;
+ vert_spacing = _vert_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getHorizontalSpacing() {
+ return hor_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getVerticalSpacing() {
+ return vert_spacing;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getCharWidth() {
+ return char_width;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getCharHeight() {
+ return char_height;
+}
+
+AutoSkinBitmap *BitmapFont::getCharTable() {
+ return &table;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::getXYfromChar(wchar_t ic, int *x, int *y)
+{
+ int c,c2=0;
+ switch (ic)
+ {
+ case L'\u00B0': /*¡*/ ic = L'0'; break;
+ case L'\u00C6':/*®*/ ic = L'A'; break;
+ // case '\u00C1':/*ç*/ ic = L'A'; break;
+ // case '\u00C2': ic = L'A'; break;
+ case L'\u00C7': /*‚*/ ic = L'C'; break;
+ case L'\u00C9':/*ƒ*/ ic = L'E'; break;
+
+ case L'\u00E0': /*ˆ*/ case L'\u00E1': /*‡*/ case L'\u00E2': /*‰*/ ic = L'a'; break;
+ case L'\u00E6':/*¾*/ ic = L'a'; break;
+ case L'\u00E7': /**/ ic = L'c'; break;
+ case L'\u00E8': /**/ case L'\u00E9': /*Ž*/ case L'\u00EB': /*‘*/case L'\u00EA':/**/ ic = L'e'; break;
+ case L'\u00EC':/*“*/ case L'\u00ED':/*’*/ case L'\u00EE':/*”*/ case L'\u00EF':/*•*/ ic = L'i'; break;
+
+#ifdef _WIN32
+ case L'—':/*—*/ case L'˜':/*˜*/ case L'™':/*™*/ ic = L'o'; break;
+ case L'œ':/*œ*/ case L'':/**/ case L'ž':/*ž*/ ic = L'u'; break;
+ case L'Ø':/*Ø*/ ic = L'y'; break;
+ case L'†':/*†*/ ic = L'U'; break;
+#else
+#warning change these to \u
+#endif
+ case L'\u00D1':/*„*/ ic = L'N'; break;
+ case L'\u00F1':/*–*/ ic = L'n'; break;
+ case L'\u00FC': /*Ÿ*/ ic = L'u'; break;
+ case L'\u0192':/*Ä*/ ic = L'f'; break;
+ default: break;
+ } // quick relocations
+ if (ic <= L'Z' && ic >= L'A') c = (ic-'A');
+ else if (ic <= L'z' && ic >= L'a') c = (ic-'a');
+ else if (ic == L' ') c = 30;
+ else {
+ c2 += char_height;
+ if (ic == L'\1') c=10;
+ else if (ic == L'.') c = 11;
+ else if (ic <= L'9' && ic >= L'0') c = ic - L'0';
+ else if (ic == L':') c = 12;
+ else if (ic == L'(') c = 13;
+ else if (ic == L')') c = 14;
+ else if (ic == L'-') c = 15;
+ else if (ic == L'\'' || ic=='`') c = 16;
+ else if (ic == L'!') c = 17;
+ else if (ic == L'_') c = 18;
+ else if (ic == L'+') c = 19;
+ else if (ic == L'\\') c = 20;
+ else if (ic == L'/') c = 21;
+ else if (ic == L'[' || ic == L'{' || ic == L'<') c = 22;
+ else if (ic == L']' || ic == L'}' || ic == L'>') c = 23;
+ else if (ic == L'~' || ic == L'^') c = 24;
+ else if (ic == L'&') c = 25;
+ else if (ic == L'%') c = 26;
+ else if (ic == L',') c = 27;
+ else if (ic == L'=') c = 28;
+ else if (ic == L'$') c = 29;
+ else if (ic == L'#') c = 30;
+ else
+ {
+ c2 += char_height;
+#ifdef _WIN32
+ if (ic == L'' || ic == L'Œ') c = 0;
+ else if (ic == L'…' || ic == L'š') c = 1;
+ else if (ic == L'€' || ic == L'Š') c = 2;
+ else
+#else
+#warning change these to \u
+#endif
+ if (ic == L'?') c = 3;
+ else if (ic == L'*') c = 4;
+ else {
+ c2 = 0;
+ if (ic == L'"') c = 26;
+ else if (ic == L'@') c = 27;
+ else c = 30;
+ }
+ }
+ }
+ c*=char_width;
+ *x=c;
+ *y=c2;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int BitmapFont::getWordLength(const wchar_t *p) {
+ int n=0;
+ while (p && *p && *p != L' ') {
+ p++;
+ n++;
+ }
+ return n;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+wchar_t *BitmapFont::makeLine(const wchar_t *t, BitmapFont *font, int line, int width, int style) {
+
+ static wchar_t str[4096];
+ wchar_t *p = (wchar_t *)t;
+ size_t len = wcslen(t);
+
+ switch (style) {
+ case WA_FONT_TEXTOUT_NORMAL:
+ case WA_FONT_TEXTOUT_RECT:
+ case WA_FONT_TEXTOUT_ELLIPSED:
+ case WA_FONT_TEXTOUT_CENTERED:
+ return line == 0 ? (wchar_t *)t : NULL;
+ case WA_FONT_TEXTOUT_WRAPPEDPATHED:
+ case WA_FONT_TEXTOUT_WRAPPED: {
+ size_t maxchar = width / (font->getCharWidth() + font->getVerticalSpacing());
+ for (int i = 0; i < line; i++) {
+ wchar_t *oldp = p;
+ p += maxchar;
+ if ((size_t)(p-t) >= len) return NULL;
+ while (p >= t) {
+ if (p == t || *(p-1) == L' ')
+ break;
+ p--;
+ }
+ if (p == oldp) {
+ p += maxchar;
+ while (p && *p && *p != L' ')
+ p++;
+ }
+ }
+ WCSCPYN(str, p, maxchar);
+ wchar_t *d = &str[maxchar-1];
+ int wr=0;
+ if (wcslen(p) > maxchar && *(p+maxchar) != L' ' && wcschr(str, L' '))
+ while (d >= str) {
+ if (*d == L' ') {
+ *d = 0;
+ wr=1;
+ }
+ else {
+ if (wr) break;
+ d--;
+ }
+ }
+ return str;
+ }
+ }
+ return NULL;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void BitmapFont::do_textOut(BitmapFont *font, ifc_canvas *c, int x, int y, int x2, int y2, const wchar_t *text, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, int style)
+{
+ static wchar_t *dotdotdot=L"...";
+ if (!text) return;
+
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(c);
+ if (!ret) return;
+
+ RECT bounds;
+
+ RECT defbounds={x,y,x2,y2};
+ int __w, __h;
+ c->getDim(&__w, &__h, NULL);
+ if (x2 == -1) defbounds.right = defbounds.left + __w;
+ if (y2 == -1) defbounds.bottom = defbounds.top + __h;
+#ifdef _WIN32
+ RegionI oldclip(&canvas, &defbounds); // get clipping region in oldclip
+ RegionI *andclip=NULL;
+ oldclip.getBox(&bounds); // get boundaries
+#else
+ bounds = defbounds;
+#warning port me
+#endif
+
+/* if (x2 != -1 && y2 != -1) {
+ andclip = new RegionI(x, y, x2, y2); // create region for rect
+ andclip->andRegion(oldclip); // and them
+ canvas.selectClipRgn(andclip); // select new clipping rect
+ andclip->getBox(&bounds); // update boundaries
+ }*/
+
+ int lc=-1;
+ wchar_t *p = dotdotdot+3; // just a zero to triger next line
+
+ int _x = x+(font->getHorizontalSpacing()/2);
+ int _y = y;
+
+ if (style == WA_FONT_TEXTOUT_CENTERED) {
+ _y += (y2 - y - font->getCharHeight()) / 2;
+ }
+
+ _y -= font->getCharHeight() + font->getVerticalSpacing();
+
+ int xp, yp;
+
+ while (p) {
+
+ if (!*p) {
+ lc++;
+ p = makeLine(text, font, lc, x2-x, style);
+ if (!p || !*p) break;
+
+ _x = x+(font->getHorizontalSpacing()/2);
+ _y += font->getCharHeight() + font->getVerticalSpacing();
+ if ((align == STDFONT_RIGHT || align == STDFONT_CENTER) && x2 != -1) {
+ int l = wcslen(p);
+ _x -= l * (font->getCharWidth() + font->getHorizontalSpacing()) - (x2-x);
+ }
+ if (align == STDFONT_CENTER)
+ _x = x + (_x - x) / 2;
+
+ }
+
+ if ((style == WA_FONT_TEXTOUT_ELLIPSED || style == WA_FONT_TEXTOUT_WRAPPEDPATHED) && x2 != -1) {
+ if (_x > x2 - 4 * (font->getCharWidth() + font->getHorizontalSpacing()) && wcslen(p) > 3) {
+ p = dotdotdot;
+ }
+ }
+
+ font->getXYfromChar(*p, &xp, &yp);
+
+ RECT r;
+ r.left = xp;
+ r.top = yp;
+ r.right = xp + font->getCharWidth();
+ r.bottom = yp + font->getCharHeight();
+
+ RECT dst;
+ dst.left = _x;
+ dst.top = _y;
+ dst.right = _x + font->getCharWidth();
+ dst.bottom = _y + font->getCharHeight();
+
+ if (Wasabi::Std::rectIntersect(dst, bounds))
+// if (IntersectRect(&dummy, &dst, &bounds)) // port me / checks clipping, not passed x,y,x2,y2
+ font->getCharTable()->stretchToRectAlpha(&canvas, &r, &dst, 255);
+
+ p++;
+ _x += font->getCharWidth();
+ _x += font->getHorizontalSpacing();
+ }
+
+#ifdef _WIN32
+ if (andclip) {
+ canvas.selectClipRgn(&oldclip); // restore previously saved clipping region
+ delete andclip;
+ }
+#else
+#warning port me
+#endif
+}
+
diff --git a/Src/Wasabi/api/font/bitmapfont.h b/Src/Wasabi/api/font/bitmapfont.h
new file mode 100644
index 00000000..0bedae86
--- /dev/null
+++ b/Src/Wasabi/api/font/bitmapfont.h
@@ -0,0 +1,70 @@
+#ifndef __BITMAPFONT_H
+#define __BITMAPFONT_H
+
+#include <api/font/svc_fonti.h>
+
+//#include "font.h"
+
+#include <bfc/platform/platform.h>
+#include <bfc/ptrlist.h>
+#include <bfc/stack.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <bfc/string/StringW.h>
+
+class Font;
+
+class BitmapFont : public svc_fontI
+{
+friend class Font;
+ public:
+
+ virtual void textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased);
+ virtual void textOut2(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased);
+ virtual void textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased);
+ virtual void textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased);
+ virtual void textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased);
+ virtual void textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialiased);
+ virtual int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased);
+ virtual int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased);
+ virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased);
+ virtual void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialiased);
+ virtual int isBitmap();
+
+ virtual void setFontBitmap(const wchar_t *name_or_element, const wchar_t *path);
+ virtual void setFontMetrics(int char_width, int char_height, int hor_spacing, int vert_spacing);
+ virtual const wchar_t *getFaceName();
+
+ virtual void setFontId(const wchar_t *id) { font_id = id; }
+ virtual const wchar_t *getFontId() { return font_id; }
+ virtual int getScriptId() { return scriptid; }
+ virtual void setScriptId(int id) { scriptid = id; }
+ virtual void setFontFace(const wchar_t *face) {}
+ virtual int addFontResource(OSFILETYPE f, const wchar_t *name) { return 0; /*failure*/}
+ virtual int addFontResource2(void *mem, int datalen, const wchar_t *name) { return 0; /*failure*/}
+
+ virtual const wchar_t *getFontSvcName() { return L"Bitmap Font"; }
+
+ protected:
+ BitmapFont();
+ virtual ~BitmapFont();
+
+ AutoSkinBitmap *getCharTable();
+ int getCharWidth();
+ int getCharHeight();
+ int getHorizontalSpacing();
+ int getVerticalSpacing();
+ void getXYfromChar(wchar_t ic, int *x, int *y);
+
+ protected:
+ StringW font_id;
+ int scriptid;
+
+ private:
+ AutoSkinBitmap table;
+ int char_width, char_height, hor_spacing, vert_spacing;
+ static void do_textOut(BitmapFont *font, ifc_canvas *c, int x, int y, int x2, int y2, const wchar_t *text, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, int style);
+ static int getWordLength(const wchar_t *p);
+ static wchar_t *makeLine(const wchar_t *t, BitmapFont *font, int line, int physwidth, int style);
+};
+
+#endif
diff --git a/Src/Wasabi/api/font/font.cpp b/Src/Wasabi/api/font/font.cpp
new file mode 100644
index 00000000..e45994ce
--- /dev/null
+++ b/Src/Wasabi/api/font/font.cpp
@@ -0,0 +1,637 @@
+#include "precomp.h"
+// ============================================================================================================================================================
+// Font abstract class + statics to install TT fonts and Bitmap fonts
+// ============================================================================================================================================================
+
+#include <api/font/font.h>
+#include <api/font/bitmapfont.h>
+#include <bfc/parse/pathparse.h>
+
+#ifdef WASABI_COMPILE_SKIN
+ #include <api/skin/skin.h>
+ #include <api/skin/skinparse.h>
+#endif
+
+#include <tataki/canvas/ifc_canvas.h>
+#include <api/wnd/fontdef.h>
+
+#ifdef WASABI_COMPILE_FONT
+#include <api/service/svcs/svc_font.h>
+//#include "services/svc_fontmaker.h"
+#endif
+
+#ifdef WASABI_API_CONFIG
+#include <api/config/options.h>
+#include <api/config/items/attrint.h>
+#include <api/config/items/attrstr.h>
+#include <api/config/items/attrbool.h>
+#endif
+#include <api/memmgr/api_memmgr.h>
+#include <api/font/FontSvcEnum.h>
+
+extern _bool cfg_options_usefontmapper;
+extern _string cfg_options_ttfoverridefont;
+extern _int cfg_options_defaultfontscale;
+
+PtrList<svc_font> Font::fontlist;
+PtrList<FontDef> Font::fontdefs;
+
+void Font::init()
+{
+#ifdef WASABI_API_CONFIG
+ Wasabi::Std::setDefaultFont(cfg_options_defaultfont.getValue());
+ Wasabi::Std::setDefaultFontScale(cfg_options_defaultfontscale.getValueAsInt());
+#endif
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void Font::dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt)
+{
+ int isoverride = 0;
+ if (WASABI_API_APP->main_isShuttingDown()) return;
+
+ int size = c->getTextSize();
+
+ svc_font *f = requestSkinFont(c->getTextFont(), &size);
+
+ ASSERT(f != NULL);
+
+ // After we get the font we want, check to see if it is bitmap.
+ // If bitmap fonts are disallowed, use the truetype override font.
+ if (f->isBitmap() && useTrueTypeOverride(txt))
+ {
+ int gotdefault=0;
+ svc_font *ttFont = requestSkinFont(getTrueTypeOverride(), &size, &gotdefault);
+ if (ttFont != NULL)
+ {
+ if (!gotdefault)
+ isoverride = 1;
+ f = ttFont;
+ }
+ }
+
+ if (isoverride)
+ {
+ double f = (double)getTrueTypeOverrideScale() / 100.0f;
+ size = (int)(size*f);
+ }
+ int bold = c->getTextBold();
+ int opaque = c->getTextOpaque();
+ int underline = c->getTextUnderline();
+ int italic = c->getTextItalic();
+ int align = c->getTextAlign();
+ int antialiased = c->getTextAntialias();
+ ARGB32 color = c->getTextColor();
+ ARGB32 bkcolor = c->getTextBkColor();
+ int xoffset=0, yoffset=0;
+ c->getOffsets(&xoffset, &yoffset);
+/* if (!f->isBitmap() && _intVal(Main::enumRootCfgItem(0), "Force antialias on all TTF"))
+ antialiased = 1;*/
+ switch (style)
+ {
+ case WA_FONT_TEXTOUT_NORMAL:
+ f->textOut(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, antialiased);
+ break;
+ case WA_FONT_TEXTOUT_RECT:
+ f->textOut(c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
+ break;
+ case WA_FONT_TEXTOUT_ELLIPSED:
+ f->textOutEllipsed(c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
+ break;
+ case WA_FONT_TEXTOUT_WRAPPED:
+ f->textOutWrapped(c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
+ break;
+ case WA_FONT_TEXTOUT_WRAPPEDPATHED:
+ f->textOutWrappedPathed(c, x, y, w, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
+ break;
+ case WA_FONT_TEXTOUT_CENTERED:
+ RECT r;
+ r.left = x;
+ r.top = y;
+ r.right = w;
+ r.bottom = h;
+ f->textOutCentered(c, &r, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialiased);
+ break;
+ }
+}
+
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int Font::dispatchGetInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h)
+{
+ int isoverride = 0;
+ if (WASABI_API_APP->main_isShuttingDown()) return 0;
+ // mig: Let's not crash if we want to see how big a NULL pointer is.
+ if (txt == NULL) {
+ if ( infoid == WA_FONT_GETINFO_WIDTHHEIGHT ) {
+ if (w != NULL) {
+ *w = 0;
+ }
+ if (h != NULL) {
+ *h = 0;
+ }
+ }
+ return 0;
+ }
+
+ int size = c->getTextSize();
+
+ svc_font *f = requestSkinFont(font, &size);
+ ASSERT(f != NULL);
+
+ // After we get the font we want, check to see if it is bitmap.
+ // If bitmap fonts are disallowed, use the truetype override font.
+ if (f->isBitmap() && useTrueTypeOverride(txt))
+ {
+ int gotdefault = 0;
+ svc_font *ttFont = requestSkinFont(getTrueTypeOverride(), &size, &gotdefault);
+ if (ttFont != NULL)
+ {
+ if (!gotdefault)
+ isoverride = 1;
+ f = ttFont;
+ }
+ }
+
+ if (isoverride) {
+ double f = (double)getTrueTypeOverrideScale() / 100.0f;
+ size = (int)(size*f);
+ }
+ int bold = c->getTextBold();
+ int underline = c->getTextUnderline();
+ int italic = c->getTextItalic();
+ int antialiased = c->getTextAntialias();
+ switch (infoid) {
+ case WA_FONT_GETINFO_WIDTH:
+ return f->getTextWidth(c, txt, size, bold, underline, italic, antialiased);
+ case WA_FONT_GETINFO_HEIGHT:
+ return f->getTextHeight(c, txt, size, bold, underline, italic, antialiased);
+ case WA_FONT_GETINFO_WIDTHHEIGHT:
+ f->getTextExtent(c, txt, w, h, size, bold, underline, italic, antialiased);
+ return 0;
+ }
+ return 0;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Install a truetype font from its filename and associate a script_id to it
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+svc_font *Font::installTrueTypeFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int scriptid, int allowmapping, int isttfreload) {
+
+ if (!isttfreload)
+ {
+ FontDef *fd = new FontDef;
+ fd->filename = filename;
+ fd->path = path;
+ fd->id = id;
+ fd->scriptid = scriptid;
+ fd->isbitmap = 0;
+ fd->allowmapping = allowmapping;
+ fontdefs.addItem(fd);
+ }
+
+ StringW file;
+
+ OSFILETYPE ff=OPEN_FAILED;
+ if (wcschr(filename, ':'))
+ ff = WFOPEN(filename, WF_READONLY_BINARY);
+
+ if (ff == OPEN_FAILED)
+ {
+ file = StringPathCombine(path, filename);
+ ff = WFOPEN(file, WF_READONLY_BINARY);
+ }
+#ifdef WASABI_COMPILE_SKIN
+ if (ff == OPEN_FAILED)
+ {
+ file = StringPathCombine(SkinParser::getXmlRootPath(), filename);
+ ff = WFOPEN(file, WF_READONLY_BINARY);
+ if (ff == OPEN_FAILED)
+ {
+ file = StringPathCombine(Skin::getDefaultSkinPath(), filename);
+ ff = WFOPEN(file, WF_READONLY_BINARY);
+ if (ff == OPEN_FAILED)
+ {
+ DebugString("Font not found %s\n", filename);
+ // todo: do something if still not found
+ }
+ }
+ }
+#endif
+ if (ff == OPEN_FAILED) {
+ DebugString("Could not install font %s\n", filename);
+ return 0;
+ }
+
+ StringW fs = filename;
+ wchar_t *p = wcschr(fs.getNonConstVal(), '.');
+ if (p)
+ *p = 0;
+ PathParserW pp(fs);
+ fs = pp.getLastString();
+
+ svc_font *f = newTrueTypeFont();
+ if (f && f->addFontResource( ff, fs) )
+ {
+ f->setFontId(id);
+ f->setScriptId(scriptid);
+ fontlist.addItem(f);
+ } else {
+ DebugString("font.cpp ====== CAN'T LOAD FONT FILE.\n");
+ }
+
+ FCLOSE(ff);
+ return f;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Uninstall all installed fonts
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void Font::uninstallAll(int ttfreload) {
+ int i;
+ // delete all by hand
+ for (i = 0; i < fontlist.getNumItems(); i++) {
+ svc_font *f = fontlist.enumItem(i);
+ if (ttfreload && f->isBitmap()) continue;
+ deleteFont(f);
+ fontlist.removeByPos(i);
+ i--;
+ }
+ if (!ttfreload) fontdefs.deleteAll();
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Uninstall by scriptid
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void Font::uninstallByScriptId(int scriptid) {
+ for (int i=0;i<fontlist.getNumItems();i++) {
+ svc_font *f = fontlist.enumItem(i);
+ if (f->getScriptId() == scriptid) {
+ fontlist.removeByPos(i);
+ deleteFont(f);
+ i--;
+ }
+ }
+ for (int i=0;i<fontdefs.getNumItems();i++) {
+ FontDef *fd = fontdefs.enumItem(i);
+ if (fd->scriptid == scriptid) {
+ fontdefs.removeByPos(i);
+ delete fd;
+ i--;
+ }
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Install a bitmap font and associates a script_id to it
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void Font::installBitmapFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int cw, int ch, int hs, int vs, int scriptid, int allowmapping)
+{
+ FontDef *fd = new FontDef;
+ fd->filename = filename;
+ fd->path = path;
+ fd->id = id;
+ fd->scriptid = scriptid;
+ fd->isbitmap = 1;
+ fd->allowmapping = allowmapping;
+ fontdefs.addItem(fd);
+
+ BitmapFont *f = new BitmapFont;
+ f->setFontBitmap(filename, path);
+ f->setFontId(id);
+ f->setFontMetrics(cw, ch, hs, vs);
+ f->setScriptId(scriptid);
+ fontlist.addItem(f);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Requests a Font* from its id
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+svc_font *Font::requestSkinFont(const wchar_t *id, int *size, int *gotdefault)
+{
+ if (gotdefault) *gotdefault = 0;
+ int oldsize = size ? *size : -1;
+ const wchar_t *mapped_id = getFontMapping(id, size);
+ if (mapped_id != NULL)
+ id = mapped_id;
+
+ // First try to get a font by that id
+ foreach_reverse(fontlist)
+ const wchar_t *thisid = fontlist.getfor()->getFontId();
+ if (thisid && !WCSICMP(thisid, id))
+ return fontlist.getfor();
+ endfor
+ // if it wasnt found, try to load a wa-installed ttfont with this face name
+ foreach_reverse(fontlist)
+ const wchar_t *facename=fontlist.getfor()->getFaceName();
+ if (facename && !WCSICMP(facename, id)) return fontlist.getfor();
+ endfor
+
+ // not found, try to reload it front the list of fonts defined by the skin
+ foreach(fontdefs)
+ FontDef *fd = fontdefs.getfor();
+ if (!WCSICMP(fd->id, id))
+ {
+ if (!fd->isbitmap)
+ {
+ svc_font *f = installTrueTypeFont(fd->filename, fd->path, fd->id, fd->scriptid, fd->allowmapping, 1);
+ if (f) return f;
+ }
+ }
+ endfor;
+
+ /*
+ for (i=fontlist.getNumItems()-1;i>=0;i--) {
+ const char *thisid = fontlist.enumItem(i)->getFontId();
+ if (thisid && STRCASEEQL(thisid, "wasabi.font.ttf.default" ))
+ return fontlist.enumItem(i);
+ }
+ */
+
+ // not found ? try to find it in the windows fonts directory
+ {
+ wchar_t *fp = WMALLOC(WA_MAX_PATH);
+ Wasabi::Std::getFontPath(WA_MAX_PATH, fp);
+ StringW file;
+ file.own(fp);
+// FREE(fp); // benski> no need because we now own it
+ file.AppendPath(StringPrintfW(L"%s%s", id, WCSCASESTR(id, L".ttf") == NULL ? L".ttf":L""));
+
+ if (!WACCESS(file, 0))
+ {
+ svc_font *f = newTrueTypeFont();
+ f->setFontFace(id);
+ f->setFontId(id);
+ OSFILETYPE ff = WFOPEN(file, WF_READONLY_BINARY);
+ if (ff != OPEN_FAILED)
+ {
+ if (f->addFontResource(ff, id))
+ {
+ DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. USING WIN FONT FILE:\n%s\n", id, file.getValue());
+ fontlist.addItem(f);
+ }
+ } else {
+ DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. CANNOT OPEN WIN FONT FILE:\n%s\n", id, file.getValue());
+ delete f;
+ f = NULL;
+ }
+ return f;
+ }
+ }
+
+ // not found ? ask the Std:: interface for the folder and the
+ // default fontname (ie: one you know will always be in the OS)
+ svc_font *f = newTrueTypeFont();
+ if (f) {
+ if (gotdefault) *gotdefault = 1;
+ if (oldsize != -1 && size) {
+ *size = oldsize;
+ double f = (double)Wasabi::Std::getDefaultFontScale() / 100.0;
+ *size = (int)(*size*f);
+ }
+ // Query Std:: and build the path to the default font file.
+ wchar_t *fontPath = WMALLOC(WA_MAX_PATH);
+ Wasabi::Std::getFontPath(WA_MAX_PATH, fontPath);
+ wchar_t fontFile[WA_MAX_PATH] = {0};
+ Wasabi::Std::getDefaultFont(WA_MAX_PATH, fontFile);
+ StringW defaultFont;
+ defaultFont.own(fontPath);
+ defaultFont.AppendPath(fontFile);
+// FREE(fontFile);
+ StringW fs = defaultFont;
+ wchar_t *p = wcschr(fs.getNonConstVal(), '.');
+ if (p) *p = 0;
+ PathParserW pp(fs);
+ fs = pp.getLastString();
+ f->setFontFace(fs);
+ f->setFontId(id);
+ // Open it and load it as the font resource.
+ OSFILETYPE ff = WFOPEN(defaultFont, WF_READONLY_BINARY);
+ if (ff != OPEN_FAILED) {
+ if (f->addFontResource(ff, fs))
+ {
+ DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. USING DEFAULT FONT FILE:\n%s\n", id, defaultFont);
+ fontlist.addItem(f);
+ }
+ } else {
+ DebugStringW(L"font.cpp ====== FONT FOR ID=%s NOT FOUND. CANNOT OPEN FONT FILE:\n%s\n", id, defaultFont);
+ delete f;
+ f = NULL;
+ }
+ } else {
+ DebugString("font.cpp ====== CAN'T GET NEW FONT FILE.\n");
+ delete f;
+ f = NULL;
+ }
+
+
+#ifdef _WIN32
+ if (f == NULL) {
+ // not found :((((( grab the default font data and use this, whatever it is
+ f = newTrueTypeFont();
+ if (f)
+ {
+ HDC dc = GetDC(GetDesktopWindow());
+ HDC dc2 = CreateCompatibleDC(dc);
+ SelectObject(dc2, GetStockObject(DEFAULT_GUI_FONT));
+
+ int datalen = GetFontData(dc2, 0, 0, NULL, 0);
+ if (datalen > 0) {
+ void *mem = WASABI_API_MEMMGR->sysMalloc(datalen+1); // freed by the service !!
+ ASSERT(mem != NULL);
+ GetFontData(dc2, 0, 0, mem, datalen);
+
+ f->setFontFace(id);
+ f->setFontId(id);
+ f->addFontResource2(mem, datalen, id);
+
+ ReleaseDC(GetDesktopWindow(), dc);
+ DeleteDC(dc2);
+ fontlist.addItem(f);
+ return f;
+ }
+ delete f;
+ f = NULL;
+ }
+ }
+#else
+#warning port me
+#endif
+
+ if (f == NULL) {
+ // ok, NOW I'm getting pissed
+ wchar_t fp[WA_MAX_PATH] = {0};
+ Wasabi::Std::getFontPath(WA_MAX_PATH, fp);
+#ifdef _WIN32
+ Wasabi::Std::messageBox(StringPrintfW(L"Fatal error trying to load truetype fonts.\n\nYou need arial.ttf at the very least, but it does not appear to be in %s", fp), L"Fatal Error", MB_ICONERROR);
+#else
+#warning port me
+#endif
+ }
+
+ //if (f == NULL) DebugString("font.cpp ====== FALLBACK FOR FONT %s CANNOT BE FOUND IN OUR LISTS.\n",f->getFontId());
+
+ return f;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Intelligently delete the font
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void Font::deleteFont(svc_font *f)
+{
+ if (f)
+ {
+ if (f->isBitmap())
+ {
+ delete static_cast<BitmapFont *>(f); // we delete our own bitmap fonts.
+ }
+ else
+ {
+ SvcEnum::release(f);
+ }
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Intelligently make a new truetype font from the service interfaces
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+svc_font *Font::newTrueTypeFont()
+{
+/*#ifdef WASABI_COMPILE_CONFIG
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *options = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+#endif*/
+
+ svc_font *retval = NULL;
+ const wchar_t *name = NULL;
+
+#ifdef WASABI_COMPILE_CONFIG
+ //const wchar_t *attr = L"Font Renderer";
+ // First, try to find a font service that matches the attribute.
+// if (options) {
+// char buf[256]; // WHEEE for stack arrays
+// if (options->getData(attr, buf, sizeof buf)) {
+ if (WASABI_API_SKIN->skin_getVersion() >= 1.3) // hardcode win32 renderer for v1.3+ skins
+ retval = FontSvcEnum(L"Win32 TextOut").getFirst();
+ else
+ retval = FontSvcEnum(cfg_options_fontrenderer.getValue()).getFirst();
+
+#else
+#ifndef WASABI_FONT_RENDERER
+#error You need to define WASABI_FONT_RENDERER (ie: #define WASABI_FONT_RENDERER "Freetype")
+#endif
+ retval = FontSvcEnum(WASABI_FONT_RENDERER).getFirst();
+#endif
+#ifdef WASABI_COMPILE_CONFIG
+// }
+// }
+
+ // If we can't find one, fallback and just take the first.
+ if (!retval)
+ {
+ retval = FontSvcEnum().getFirst();
+ if (retval != NULL)
+ name = retval->getFontSvcName();
+ }
+
+ // If we had to fallback, remember the fallback service in the attribute.
+ if (name/* && options*/)
+ {
+ //options->setData(attr, name);
+ cfg_options_fontrenderer.setValue(name);
+ }
+#endif
+
+ return retval;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Test whether to forbid bitmap fonts.
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int Font::useTrueTypeOverride(const wchar_t *txt)
+
+{
+ if (cfg_options_no7bitsttfoverride.getValueAsInt())
+ {
+ const wchar_t *p = (const wchar_t *)txt;
+ while (p && *p)
+ {
+ // TODO: benski> some characters above 127 can be handled by the bitmap fonts - it might be worth checking those explicitly
+ if (*p & 0xFF80)
+ break;
+ p++;
+ }
+ if (!*p) return 0;
+ }
+#ifdef WASABI_COMPILE_CONFIG
+/* // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ return !_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), "Use bitmap fonts (no international support)", 1);*/
+ return !cfg_options_allowbitmapfonts.getValueAsInt();
+#else
+ return WASABI_FONT_TTFOVERRIDE;
+#endif
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Get the font to be used to override bitmap fonts.
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+const wchar_t *Font::getTrueTypeOverride()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ return cfg_options_ttfoverridefont.getValue();
+#else
+ return L"Arial";
+#warning TODO
+#endif
+}
+
+int Font::getTrueTypeOverrideScale()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ return cfg_options_ttfoverridescale.getValueAsInt();
+#else
+ return 1;
+#warning TODO
+#endif
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Returns the font mapping for this font & skin, if font mapper is on and if there is a mapping, otherwise returns null
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+const wchar_t *Font::getFontMapping(const wchar_t *id, int *size)
+{
+ if (cfg_options_usefontmapper.getValueAsInt())
+ {
+ wchar_t t[256]=L"";
+ StringW tmp;
+ tmp.printf(L"Skin:%s/Font Mapping/%s",WASABI_API_SKIN->getSkinName(), id);
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 256, L"");
+
+ tmp.printf(L"Skin:%s/Font Mapping/%s_scale",WASABI_API_SKIN->getSkinName(), id);
+ int v = WASABI_API_CONFIG->getIntPrivate(tmp, -1);
+ if (!*t)
+ {
+ tmp.printf(L"Font Mapping/%s", id);
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 256, L"");
+ tmp.printf(L"Font Mapping/%s_scale", id);
+ v = WASABI_API_CONFIG->getIntPrivate(tmp, -1);
+ }
+ mapping = t;
+ if (mapping.isempty()) return NULL;
+ if (size != NULL)
+ {
+ if (v != -1)
+ {
+ double f = (double)v / 100.0;
+ *size = (int)((double)*size * f);
+ }
+ }
+ return mapping;
+ }
+ return NULL;
+}
+
+StringW Font::mapping; \ No newline at end of file
diff --git a/Src/Wasabi/api/font/font.h b/Src/Wasabi/api/font/font.h
new file mode 100644
index 00000000..8e1f15f2
--- /dev/null
+++ b/Src/Wasabi/api/font/font.h
@@ -0,0 +1,55 @@
+#ifndef __FONT_H
+#define __FONT_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+class ifc_canvas;
+class svc_font;
+class svc_fontMaker;
+
+class FontDef {
+ public:
+ StringW filename;
+ StringW path;
+ StringW id;
+ int allowmapping;
+ int isbitmap;
+ int scriptid;
+};
+
+class Font {
+ public:
+ static void init();
+
+ static svc_font *installTrueTypeFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int scriptid, int allowmapping, int isreload); // call this to install a new font
+ static void installBitmapFont(const wchar_t *filename, const wchar_t *path, const wchar_t *id, int charwidth, int charheight, int hspacing, int vspacing, int scriptid, int allowmapping);
+ static void uninstallAll(int isttfreload=0);
+ static void uninstallByScriptId(int scriptid);
+
+ static svc_font *requestSkinFont(const wchar_t *id, int *size=NULL, int *gotdefault=NULL); // call this to get a Font pointer to a font id, pass your size if you have one, so that the mapper can do its job.
+ static void dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt);
+ static int dispatchGetInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h);
+
+ static int useTrueTypeOverride(const wchar_t *txt);
+ static const wchar_t *getTrueTypeOverride();
+ static int getTrueTypeOverrideScale();
+ static int getNumFonts() { return fontlist.getNumItems(); }
+
+ static FontDef *enumFontDef(int n) { return fontdefs.enumItem(n); }
+ static int getNumFontDefs() { return fontdefs.getNumItems(); }
+
+ static const wchar_t *getFontMapping(const wchar_t *id, int *size);
+
+ private:
+ static void deleteFont(svc_font *font);
+ static svc_font *newTrueTypeFont();
+
+ static PtrList<svc_font> fontlist;
+ static PtrList<FontDef> fontdefs;
+ StringW font_id;
+ int scriptid;
+ static StringW mapping;
+};
+
+#endif
diff --git a/Src/Wasabi/api/font/fontapi.cpp b/Src/Wasabi/api/font/fontapi.cpp
new file mode 100644
index 00000000..c004c65c
--- /dev/null
+++ b/Src/Wasabi/api/font/fontapi.cpp
@@ -0,0 +1,32 @@
+#include <precomp.h>
+#include "fontapi.h"
+#include <api/font/font.h>
+
+api_font *fontApi = NULL;
+
+FontApi::FontApi()
+{
+ Font::init();
+}
+
+FontApi::~FontApi()
+{
+ Font::uninstallAll();
+}
+
+void FontApi::font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt)
+{
+ Font::dispatchTextOut(c, style, x, y, w, h, txt);
+}
+
+int FontApi::font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h)
+{
+ return Font::dispatchGetInfo(c, font, infoid, txt, w, h);
+}
+
+#define CBCLASS FontApi
+START_DISPATCH;
+ VCB(API_FONT_FONT_TEXTOUT, font_textOut);
+ CB(API_FONT_FONT_GETINFO, font_getInfo);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/font/fontapi.h b/Src/Wasabi/api/font/fontapi.h
new file mode 100644
index 00000000..3a169ac3
--- /dev/null
+++ b/Src/Wasabi/api/font/fontapi.h
@@ -0,0 +1,20 @@
+#ifndef __FONTAPI_H
+#define __FONTAPI_H
+
+#include <api/font/api_font.h>
+
+class FontApi : public api_font
+{
+public:
+ FontApi();
+ ~FontApi();
+ void font_textOut(ifc_canvas *c, int style, int x, int y, int w, int h, const wchar_t *txt);
+ int font_getInfo(ifc_canvas *c, const wchar_t *font, int infoid, const wchar_t *txt, int *w, int *h);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+extern api_font *fontApi;
+
+#endif
diff --git a/Src/Wasabi/api/font/linux/truetypefont_linux.cpp b/Src/Wasabi/api/font/linux/truetypefont_linux.cpp
new file mode 100644
index 00000000..188d09b6
--- /dev/null
+++ b/Src/Wasabi/api/font/linux/truetypefont_linux.cpp
@@ -0,0 +1,472 @@
+// ============================================================================================================================================================
+// Font abstract class + statics to install TT fonts and Bitmap fonts
+// ============================================================================================================================================================
+
+// what other linux headers need be made?
+
+#include "truetypefont_linux.h"
+
+#include <tataki/canvas/ifc_canvas.h>
+#include "../../bitmap.h"
+
+// ============================================================================================================================================================
+// TrueTypeFont_Linux implementation.
+// ============================================================================================================================================================
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+TrueTypeFont_Linux::TrueTypeFont_Linux() {
+ font = NULL;
+ antialias_canvas = NULL;
+ DColdstate = NULL;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+TrueTypeFont_Linux::~TrueTypeFont_Linux() {
+ ASSERT(fontstack.isempty());
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Linux::isBitmap() {
+ return 0;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::addFontResource(FILE *in){
+ ASSERT(in != NULL);
+ OutputDebugString( "portme -- TrueTypeFont_Linux::addFontResource\n" );
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::setFontFace(const char *face) {
+ face_name = face;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+const char *TrueTypeFont_Linux::getFaceName() {
+ return face_name;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::prepareCanvas(ifc_canvas *c, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor) {
+ String fontname = StringPrintf( "-*-%s-%s-%s-*--%d-*-*-*-*-*-*-*",
+ (const char *)face_name,
+ bold?"bold":"medium",
+ italic?"i":"r", size * 3/4 );
+ font = XLoadQueryFont( Linux::getDisplay(), (const char *)fontname );
+ if ( font == NULL ) {
+ fontname = StringPrintf( "-*-arial-%s-%s-*--%d-*-*-*-*-*-*-*",
+ bold?"bold":"medium",
+ italic?"i":"r", size * 3/4 );
+ font = XLoadQueryFont( Linux::getDisplay(), (const char *)fontname );
+
+ if ( font == NULL ) {
+ fontname = StringPrintf( "-*-courier-%s-%s-*--%d-*-*-*-*-*-*-*",
+ bold?"bold":"medium",
+ italic?"i":"r", size * 3/4 );
+ font = XLoadQueryFont( Linux::getDisplay(), (const char *)fontname );
+ }
+ }
+ ASSERTPR( font != NULL, fontname );
+ XSetFont( Linux::getDisplay(), c->getHDC()->gc, font->fid );
+ XSetForeground( Linux::getDisplay(), c->getHDC()->gc, color );
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::restoreCanvas(ifc_canvas *c) {
+ if ( font != NULL ) {
+ XFreeFont( Linux::getDisplay(), font );
+ font = NULL;
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+ifc_canvas *TrueTypeFont_Linux::prepareAntialias(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int w, int h) {
+ ASSERT(antialias_canvas == NULL);
+ BaseCloneCanvas canvas(c);
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, color, bkcolor);
+ al_w = MAX(2,canvas.getTextWidth(txt) * 2 + xoffset*2);
+ al_h = MAX(2,canvas.getTextHeight()*2 + yoffset*2);
+ restoreCanvas(&canvas);
+ if (w != -1) {
+ al_w = w * 2;
+ al_dw = w;
+ } else al_dw = w;
+ if (h != -1) {
+ al_h = h * 2;
+ al_dh = h;
+ } else al_dh = h;
+ al_mask=RGB(0,0,0);
+ if (color == al_mask) al_mask=RGB(255,255,255);
+ antialias_canvas = new BltCanvas(al_w, al_h);
+ antialias_canvas->fillBits(0);
+ prepareCanvas(antialias_canvas, size*2, bold, opaque, underline, italic, color, bkcolor);
+ if (al_mask != 0) antialias_canvas->fillBits(al_mask);
+ al_x = x; al_y = y; al_xo = xoffset; al_yo = yoffset;
+ return antialias_canvas;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::completeAntialias(ifc_canvas *c) {
+ BaseCloneCanvas canvas(c);
+ antialias_canvas->maskColor(al_mask, RGB(0,0,0));
+ BltCanvas *ac = new BltCanvas(al_w/2, al_h/2);
+ antialias_canvas->antiAliasTo(ac, al_w/2, al_h/2, 2);
+ SkinBitmap *b = ac->getSkinBitmap();
+ RECT src={0,0,al_w/2,al_h/2};
+ RECT dst={al_x+al_xo,al_y+al_yo,al_x+al_xo+al_dw,al_y+al_yo+al_dh};
+ b->blitToRect(&canvas, &src, &dst);
+ delete ac;
+ restoreCanvas(antialias_canvas);
+ delete antialias_canvas;
+ antialias_canvas = NULL;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::textOut(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
+ if (antialiased) {
+ ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, -1, -1);
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, 0, 0, txt, STRLEN(txt) );
+
+ completeAntialias(c);
+ } else {
+ prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
+
+ int dir, ascent, descent;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, x+xoffset, y+yoffset+ascent, txt, STRLEN(txt) );
+
+
+ restoreCanvas(c);
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::textOut(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
+ if (antialiased) {
+ ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, h);
+ RECT al_r={0,0,w*2,h*2};
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, al_r.left, al_r.top, txt, STRLEN(txt) );
+
+ completeAntialias(c);
+ } else {
+ RECT r;
+ r.left = x+xoffset;
+ r.top = y+yoffset;
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+ prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
+
+ int dir, ascent, descent;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+ int xstart = r.left;
+
+ if ( align == DT_RIGHT ) {
+ int width = XTextWidth( font, txt, STRLEN( txt ) );
+ xstart = r.right - width;
+
+ } else if ( align == DT_CENTER ) {
+ int width = XTextWidth( font, txt, STRLEN( txt ) );
+ xstart = (r.right + r.left - width) / 2;
+ }
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, xstart, r.top + ascent, txt, STRLEN(txt) );
+
+ restoreCanvas(c);
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
+ if (antialiased) {
+ ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, h);
+ RECT al_r={0,0,w*2,h*2};
+
+ OutputDebugString( "portme -- TrueTypeFont_Linux::textoutEllipsed (antialiased)\n" );
+
+ completeAntialias(c);
+ } else {
+ RECT r;
+ r.left = x+xoffset;
+ r.top = y+yoffset;
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+ prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
+
+ if ( txt == NULL )
+ return;
+
+ int dir, ascent, descent;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+
+ char *tmp = (char *)MALLOC( STRLEN( txt ) + 3 );
+ STRCPY( tmp, txt );
+
+ if ( XTextWidth( font, tmp, STRLEN( tmp ) ) > r.right - r.left ) {
+ int len = STRLEN( tmp );
+ char *p = tmp + len;
+ int width = r.right - r.left - XTextWidth( font, "...", 3 );
+ while( XTextWidth( font, tmp, len ) > width ) {
+ *p-- = '\0';
+ len--;
+ }
+ STRCPY( p, "..." );
+ }
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, r.left, r.top + ascent, tmp, STRLEN(tmp) );
+
+ FREE( tmp );
+
+ restoreCanvas(c);
+ }
+}
+
+const char *find_break( int (*width_func)(void *, const char *, int ),
+ void *f, const char *str, int width ) {
+ const char *softret, *lastsoft, *hardret;
+
+ if ( width_func( f, str, STRLEN( str ) ) <= width )
+ return str + STRLEN( str );
+
+ for( hardret = str; *hardret; hardret ++ )
+ if ( *hardret == '\r' || *hardret == '\n' )
+ break;
+
+ if ( hardret && width_func( f, str, hardret - str ) <= width ) {
+ return hardret;
+ }
+ for( softret = str; *softret && !isspace( *softret ); softret++ )
+ ;
+
+ if ( width_func( f, str, softret - str ) <= width ) {
+ do {
+ lastsoft = softret;
+
+ for( softret = lastsoft+1; *softret && !isspace( *softret ); softret++ )
+ ;
+
+ } while ( *lastsoft && width_func( f, str, softret - str ) <= width );
+
+ softret = lastsoft;
+ } else {
+ for( softret = str; *softret; softret++ )
+ if ( width_func( f, str, softret - str ) > width )
+ break;
+
+ softret--;
+ }
+
+ return softret;
+}
+
+int xlib_width( void *data, const char *str, int len ) {
+ return XTextWidth( (XFontStruct *)data, str, len );
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
+ if (antialiased) {
+ ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, h);
+ RECT al_r={0,0,w*2,h*2};
+
+ OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrapped (antialiased)\n" );
+
+ completeAntialias(c);
+ } else {
+ RECT r;
+ r.left = x+xoffset;
+ r.top = y+yoffset;
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+ prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
+
+
+ int dir, ascent, descent;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+ HDC hdc = c->getHDC();
+
+ int yoff = r.top + ascent;
+ const char *cur = txt, *next;
+ int length = STRLEN( txt );
+ for (int yoff = r.top + ascent; yoff < r.bottom - descent; yoff += ascent + descent) {
+ next = find_break(xlib_width, font, cur, r.right - r.left);
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, r.left, yoff, cur, next - cur );
+ for ( cur = next; *cur && isspace( *cur ); cur++ )
+ ;
+ if ( cur >= txt + length )
+ break;
+ }
+
+
+ restoreCanvas(c);
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
+ prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
+ RECT r;
+ char *ptr, *d;
+ const char *s;
+ ptr = (char *)MALLOC(STRLEN(txt)+1+4);
+ for (s = txt, d = ptr; *s; s++, d++) {
+ if (*s == '/') *d = '\\';
+ else *d = *s;
+ }
+ r.left = x+xoffset;
+ r.top = y+yoffset;
+ r.right = r.left + w;
+ r.bottom = r.top + getTextHeight(c, size, bold, underline, italic, antialiased);
+
+ OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrappedPathed\n" );
+
+ for (d = ptr; *d; d++) {
+ if (*d == '\\') *d = '/';
+ }
+
+ if (antialiased) {
+ restoreCanvas(c);
+
+ ifc_canvas *canvas = prepareAntialias(c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, w, -1);
+ RECT al_r={0,0,w*2,al_h};
+
+ OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrappedPathed (antialised)\n" );
+
+ completeAntialias(c);
+ } else {
+ int dir, ascent, descent;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, r.left, r.top + ascent, txt, STRLEN(txt) );
+ OutputDebugString( "portme -- TrueTypeFont_Linux::textoutWrappedPathed\n" );
+
+ restoreCanvas(c);
+ }
+
+ FREE(ptr);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::textOutCentered(ifc_canvas *c, RECT *r, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased) {
+ ASSERT(r != NULL);
+ ASSERT(txt != NULL);
+ RECT rr=*r;
+ rr.left += xoffset;
+ rr.right += xoffset;
+ rr.top += yoffset;
+ rr.bottom += yoffset;
+
+ if (antialiased) {
+ ifc_canvas *canvas = prepareAntialias(c, r->left, r->top, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, r->right-r->left, r->bottom-r->top);
+ RECT al_r={0,0,(r->right-r->left)*2,(r->bottom-r->top)*2};
+
+ OutputDebugString( "portme -- TrueTypeFont_Linux::textoutCentered (antialiased)\n" );
+
+ completeAntialias(c);
+ } else {
+ prepareCanvas(c, size, bold, opaque, underline, italic, color, bkcolor);
+
+ int dir, ascent, descent, width;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+ width = XTextWidth( font, txt, STRLEN( txt ) );
+
+ HDC hdc = c->getHDC();
+ XDrawString( Linux::getDisplay(), hdc->d, hdc->gc, (rr.right + rr.left - width) / 2, rr.top + ascent, txt, STRLEN(txt) );
+
+ restoreCanvas(c);
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Linux::getTextWidth(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialiased) {
+ int w;
+ getTextExtent(c, text, &w, NULL, size, bold, underline, italic, antialiased);
+ return w;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Linux::getTextHeight(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialiased) {
+ int h;
+ getTextExtent(c, text, NULL, &h, size, bold, underline, italic, antialiased);
+ {
+ // calcul for multiline text
+ const char *p=text;
+ int n=0;
+ while(*p!=0) if(*p++=='\n') n++;
+ if(n) h*=(n+1);
+ }
+ return h;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Linux::getTextExtent(ifc_canvas *c, const char *txt, int *w, int *h, int size, int bold, int underline, int italic, int antialiased) {
+ SIZE rsize={0,0};
+ ASSERT(txt != NULL);
+ if (*txt == 0) {
+ if (w != NULL) *w = 0;
+ if (h != NULL) *h = 0;
+ return;
+ }
+
+ if (antialiased)
+ prepareCanvas(c, size*2, bold, 0, underline, italic, 0, 0);
+ else
+ prepareCanvas(c, size, bold, 0, underline, italic, 0, 0);
+
+ int dir, ascent, descent;
+ XCharStruct overall;
+ XTextExtents( font, txt, STRLEN( txt ), &dir, &ascent, &descent, &overall );
+ rsize.cy = ascent + descent;
+ rsize.cx = XTextWidth( font, txt, STRLEN( txt ) );
+
+ if (w != NULL) *w = rsize.cx;
+ if (h != NULL) *h = rsize.cy;
+
+ if (antialiased) {
+ if (w != NULL) *w /= 2;
+ if (h != NULL) *h /= 2;
+ }
+
+ restoreCanvas(c);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Linux::getTextHeight(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased) {
+ return getTextHeight(c, "My", size, bold, underline, italic, antialiased);
+}
+
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// code from ftp.microsoft.com/Softlib/MSLFILES/FONTINST.EXE
+// retrieves the friendly font name from its filename
+char *TrueTypeFont_Linux::filenameToFontFace(const char *pszFile) {
+ static char lpszLongName[256];
+ unsigned i;
+ char namebuf[255];
+ int fp;
+ unsigned short numNames;
+ long curseek;
+ unsigned cTables;
+ sfnt_OffsetTable OffsetTable;
+ sfnt_DirectoryEntry Table;
+ sfnt_NamingTable NamingTable;
+ sfnt_NameRecord NameRecord;
+
+ OutputDebugString( "portme -- TrueTypeFont_Linux::filenameToFontFace\n" );
+
+ return FALSE;
+}
diff --git a/Src/Wasabi/api/font/linux/truetypefont_linux.h b/Src/Wasabi/api/font/linux/truetypefont_linux.h
new file mode 100644
index 00000000..b98046c5
--- /dev/null
+++ b/Src/Wasabi/api/font/linux/truetypefont_linux.h
@@ -0,0 +1,65 @@
+#ifndef __TRUETYPEFONT_LINUX_H
+#define __TRUETYPEFONT_LINUX_H
+
+#include "../../../studio/services/svc_font.h"
+
+#include "../../string.h"
+#include "../../stack.h"
+#include "../truetypefontdef.h"
+
+class ifc_canvas;
+class BltCanvas;
+
+class TrueTypeFont_Linux : public svc_fontI {
+ public:
+ TrueTypeFont_Linux();
+ virtual ~TrueTypeFont_Linux();
+
+ virtual void textOut(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOut2(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutCentered(ifc_canvas *c, RECT *r, const char *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual int getTextWidth(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialias);
+ virtual int getTextHeight(ifc_canvas *c, const char *text, int size, int bold, int underline, int italic, int antialias);
+ virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias);
+ virtual void getTextExtent(ifc_canvas *c, const char *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias);
+
+ virtual void setFontId(const char *id) { font_id = id; }
+ virtual const char *getFontId() { return font_id; }
+ virtual int getScriptId() { return scriptid; }
+ virtual void setScriptId(int id) { scriptid = id; }
+
+ virtual int isBitmap();
+ virtual void setFontFace(const char *face);
+ virtual int addFontResource(FILE *f);
+ virtual const char *getFaceName();
+
+ virtual const wchar_t *getFontSvcName() { return "Linux"; }
+ static const char *getServiceName() { return "Linux font renderer"; }
+
+ protected:
+ static char *filenameToFontFace(const wchar_t *filename);
+ void prepareCanvas(ifc_canvas *c, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor);
+ void restoreCanvas(ifc_canvas *c);
+
+ protected:
+ String font_id;
+ int scriptid;
+
+ private:
+ ifc_canvas *prepareAntialias(ifc_canvas *c, int x, int y, const char *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int w, int h);
+ void completeAntialias(ifc_canvas *c);
+
+ String face_name;
+ String tmpfilename;
+ int DColdstate;
+ XFontStruct *font;
+ Stack<fontslot*> fontstack;
+ BltCanvas *antialias_canvas;
+ int al_w, al_h, al_x, al_y, al_xo, al_yo, al_dw, al_dh;
+ COLORREF al_mask;
+};
+
+#endif
diff --git a/Src/Wasabi/api/font/skinfont.cpp b/Src/Wasabi/api/font/skinfont.cpp
new file mode 100644
index 00000000..d1987dfa
--- /dev/null
+++ b/Src/Wasabi/api/font/skinfont.cpp
@@ -0,0 +1,43 @@
+#include "precomp.h"
+#include "skinfont.h"
+#include "api.h"
+#include "../bfc/std.h"
+
+SkinFont::SkinFont() {
+}
+
+SkinFont::~SkinFont() {
+ if (!tempFn.isempty()) {
+#ifdef WIN32
+ RemoveFontResource(tempFn);
+#else
+ DebugString( "portme -- SkinFont::~SkinFont\n" );
+#endif
+ UNLINK(tempFn);
+ }
+}
+
+int SkinFont::setXmlOption(const char *paramname, const char *strvalue) {
+ return 0;
+}
+
+void SkinFont::installFont(OSFNSTR filename, OSFNSTR path) {
+ FILE *in,*out;
+ StringPrintf temp("%s%s", path, filename);
+ in = WFOPEN(temp, L"rb");
+ if (!in) return;
+ int len = FGETSIZE(in);
+ MemBlock<char> m(len);
+ FREAD(m.getMemory(), len, 1, in);
+ tempFn = TMPNAM(NULL);
+ out = FOPEN(tempFn, "wb");
+ ASSERT(out);
+ FWRITE(m.getMemory(), len, 1, out);
+ FCLOSE(out);
+ FCLOSE(in);
+#ifdef WIN32
+ AddFontResource(tempFn);
+#else
+ DebugString( "portme -- SkinFont::installFont\n" );
+#endif
+}
diff --git a/Src/Wasabi/api/font/skinfont.h b/Src/Wasabi/api/font/skinfont.h
new file mode 100644
index 00000000..4780c136
--- /dev/null
+++ b/Src/Wasabi/api/font/skinfont.h
@@ -0,0 +1,17 @@
+#ifndef _SKINFONT_H
+#define _SKINFONT_H
+
+#include <api/skin/xmlobject.h>
+
+class SkinFont : public XmlObjectI
+{
+public:
+ SkinFont();
+ ~SkinFont();
+ void installFont(const wchar_t *filename, const wchar_t *path);
+ virtual int setXmlOption(const wchar_t *name, const wchar_t *val);
+private:
+ StringW tempFn;
+};
+
+#endif
diff --git a/Src/Wasabi/api/font/svc_fontI.h b/Src/Wasabi/api/font/svc_fontI.h
new file mode 100644
index 00000000..76a9ad9c
--- /dev/null
+++ b/Src/Wasabi/api/font/svc_fontI.h
@@ -0,0 +1,39 @@
+#ifndef NULLSOFT_WASABI_SVC_FONTI_H
+#define NULLSOFT_WASABI_SVC_FONTI_H
+
+#include <api/service/svcs/svc_font.h>
+//#include <tataki/canvas/canvas.h>
+class ifc_canvas;
+// implementor derives from this one
+class NOVTABLE svc_fontI : public svc_font {
+public:
+
+ virtual void textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)=0; // abstract interface
+ virtual void textOut2(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)=0;
+ virtual void textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)=0;
+ virtual void textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)=0;
+ virtual void textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)=0;
+ virtual void textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)=0;
+ virtual int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias)=0;
+ virtual int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias)=0;
+ virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias)=0;
+ virtual void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias)=0;
+
+ virtual void setFontId(const wchar_t *id)=0;
+ virtual const wchar_t *getFontId()=0;
+ virtual const wchar_t *getFaceName()=0;
+ virtual int isBitmap()=0;
+ virtual int getScriptId()=0;
+ virtual void setScriptId(int id)=0;
+
+ virtual void setFontFace(const wchar_t *face)=0;
+ virtual int addFontResource(OSFILETYPE f, const wchar_t *name)=0;
+ virtual int addFontResource2(void *mem, int datalen, const wchar_t *name)=0;
+
+ virtual const wchar_t * getFontSvcName()=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/font/truetypefontdef.h b/Src/Wasabi/api/font/truetypefontdef.h
new file mode 100644
index 00000000..2b54a045
--- /dev/null
+++ b/Src/Wasabi/api/font/truetypefontdef.h
@@ -0,0 +1,56 @@
+#ifndef __TRUETYPEFONTDEF_H
+#define __TRUETYPEFONTDEF_H
+
+// Macros for TrueType portability
+#define FS_2BYTE(p) ( ((unsigned short)((p)[0]) << 8) | (p)[1])
+#define FS_4BYTE(p) ( FS_2BYTE((p)+2) | ( (FS_2BYTE(p)+0L) << 16) )
+#define SWAPW(a) ((short) FS_2BYTE( (unsigned char FAR*)(&a) ))
+#define SWAPL(a) ((long) FS_4BYTE( (unsigned char FAR*)(&a) ))
+
+typedef short int16;
+typedef unsigned short uint16;
+typedef long int32;
+typedef unsigned long uint32;
+typedef long sfnt_TableTag;
+
+typedef struct {
+ uint16 platformID;
+ uint16 specificID;
+ uint16 languageID;
+ uint16 nameID;
+ uint16 length;
+ uint16 offset;
+} sfnt_NameRecord;
+
+typedef struct {
+ uint16 format;
+ uint16 count;
+ uint16 stringOffset;
+} sfnt_NamingTable;
+
+typedef struct {
+ sfnt_TableTag tag;
+ uint32 checkSum;
+ uint32 offset;
+ uint32 length;
+} sfnt_DirectoryEntry;
+
+typedef struct {
+ int32 version;
+ uint16 numOffsets;
+ uint16 searchRange;
+ uint16 entrySelector;
+ uint16 rangeShift;
+ sfnt_DirectoryEntry table[1];
+} sfnt_OffsetTable;
+#define OFFSETTABLESIZE 12
+
+typedef struct {
+ int dcstate;
+ HFONT font;
+ HFONT prevfont;
+} fontslot;
+
+#define tag_NamingTable 0x656d616e /* 'name' */
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/font/win32/truetypefont_win32.cpp b/Src/Wasabi/api/font/win32/truetypefont_win32.cpp
new file mode 100644
index 00000000..46c41ce7
--- /dev/null
+++ b/Src/Wasabi/api/font/win32/truetypefont_win32.cpp
@@ -0,0 +1,561 @@
+#include "precomp.h"
+// ============================================================================================================================================================
+// Font abstract class + statics to install TT fonts and Bitmap fonts
+// ============================================================================================================================================================
+#define WIN32_LEAN_AND_MEAN
+#include <fcntl.h>
+#include "../nu/ns_wc.h"
+#include "truetypefont_win32.h"
+
+#include <tataki/canvas/bltcanvas.h>
+#include <tataki/bitmap/bitmap.h>
+#include <bfc/file/tmpnamestr.h>
+#include <api/memmgr/api_memmgr.h>
+#if UTF8
+#ifdef WANT_UTF8_WARNINGS
+#pragma CHAT("mig", "all", "UTF8 is enabled in std.cpp -- Things might be screwy till it's all debugged?")
+#endif
+# include <bfc/string/encodedstr.h>
+#endif
+#define VERTICAL_LPADDING 0
+#define VERTICAL_RPADDING 2
+#define VERTICAL_TPADDING 1
+#define VERTICAL_BPADDING 1
+
+/** ============================================================================================================================================================
+ ** TrueTypeFont_Win32 implementation.
+ **
+ ** TODO:
+ ** use GDI transformation to draw in 72 DPI
+ ** fractional point sizes?
+ ** ===========================================================================================================================================================
+ */
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+TrueTypeFont_Win32::TrueTypeFont_Win32()
+{
+ scriptid = 0;
+ font = oldFont = NULL;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+TrueTypeFont_Win32::~TrueTypeFont_Win32()
+{
+ if (!tmpfilename.isempty())
+ {
+ RemoveFontResourceW(tmpfilename);
+ // explict call to this instead of UNLINK allows correct removal of the temp files
+ _wunlink(tmpfilename);
+ }
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Win32::isBitmap()
+{
+ return 0;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Win32::addFontResource(OSFILETYPE in, const wchar_t *name)
+{
+ ASSERT(in != NULL);
+
+ int len = (int)FGETSIZE(in);
+ OSFILETYPE out;
+ char *m = (char *)MALLOC(len);
+ ASSERT(m != NULL);
+ FREAD(m, len, 1, in);
+ TmpNameStrW tempfn;
+ out = WFOPEN(tempfn, L"wb");
+ ASSERT(out != OPEN_FAILED);
+ FWRITE(m, len, 1, out);
+ FCLOSE(out);
+ AddFontResourceW(tempfn);
+ FREE(m);
+ tmpfilename = tempfn;
+ setFontFace(filenameToFontFace(tempfn));
+ return 1;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Win32::addFontResource2(void *data, int datalen, const wchar_t *name)
+{
+ TmpNameStrW tempfn;
+ OSFILETYPE out = WFOPEN(tempfn, L"wb");
+ ASSERT(out != OPEN_FAILED);
+ FWRITE(data, datalen, 1, out);
+ FCLOSE(out);
+ AddFontResourceW(tempfn);
+ tmpfilename = tempfn;
+ setFontFace(filenameToFontFace(tempfn));
+
+ WASABI_API_MEMMGR->sysFree(data);
+
+ return 1;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::setFontFace(const wchar_t *face)
+{
+ face_name = face;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+const wchar_t *TrueTypeFont_Win32::getFaceName()
+{
+ return face_name;
+}
+
+static int IsXp_or_higher()
+{
+ static int checked=0;
+ static int isXp=0;
+ if (!checked)
+ {
+ OSVERSIONINFO osver;
+ osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+ isXp = ( ::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion >= 5 )) ? 1 : 0;
+ checked=1;
+ }
+ return isXp;
+}
+
+#ifndef CLEARTYPE_QUALITY
+#define CLEARTYPE_QUALITY 5
+#endif
+HFONT TrueTypeFont_Win32::MakeFont(int size, int bold, int underline, int italic, int antialiased)
+{
+ // TODO: we got the height to be in 72 DPI, but how can we get the width???
+ int nHeight = MulDiv(size, 72, 96); // this is lame, but we have to do it to match freetype
+
+ int quality;
+ if (antialiased)
+ {
+ if (IsXp_or_higher())
+ quality=CLEARTYPE_QUALITY;
+ else
+ quality=ANTIALIASED_QUALITY;
+ }
+ else
+ quality=NONANTIALIASED_QUALITY;
+
+ return CreateFontW(-nHeight, 0, 0, 0, bold ? FW_BOLD : FW_NORMAL,
+ italic, underline, FALSE, DEFAULT_CHARSET,
+ OUT_TT_ONLY_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ quality,
+ DEFAULT_PITCH | FF_DONTCARE, face_name);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::prepareCanvas(BltCanvas *canvas, int size, int bold, int opaque, int underline, int italic, int antialiased)
+{
+ HDC canvasHDC = canvas->getHDC();
+
+ font = MakeFont(size, bold, underline, italic, antialiased);
+ oldFont = (HFONT)SelectObject(canvasHDC, font);
+
+ SetBkColor(canvasHDC, RGB(0, 0, 0));
+ //SetBkMode(canvasHDC, TRANSPARENT);
+ SetTextColor(canvasHDC, RGB(255, 255, 255));
+}
+
+typedef DWORD ARGB;
+
+#define MIN_TONE 100.0
+//BYTE min = 255, max=0;
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::restoreCanvas(BltCanvas *canvas, ifc_canvas *dest, int w, int h, COLORREF color, COLORREF bkcolor, int antialiased, int _x, int _y)
+{
+#ifndef FE_FONTSMOOTHINGCLEARTYPE
+#define FE_FONTSMOOTHINGCLEARTYPE 0x0002
+#endif
+
+#ifndef SPI_GETFONTSMOOTHINGTYPE
+#define SPI_GETFONTSMOOTHINGTYPE 0x200A
+#endif
+
+ bool clearType = false;
+ UINT fontSmoothing;
+ if (antialiased && SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothing, 0))
+ clearType = fontSmoothing == FE_FONTSMOOTHINGCLEARTYPE;
+
+ ARGB32 *buf = static_cast<ARGB32 *>(canvas->getBits());
+
+ for (int y = 0; y < h; y++)
+ {
+ int linewidth = y * w;
+
+ for (int x = 0; x < w; x++)
+ {
+
+ ARGB32* prgb = &buf[linewidth + x];
+ unsigned char *pixel = (unsigned char *)prgb;
+ if (*prgb == 0)
+ {
+ // Do nothing
+ }
+ else
+ {
+ BYTE alpha = 255;
+ BYTE rAlpha = 255;
+ BYTE gAlpha = 255;
+ BYTE bAlpha = 255;
+
+ if (*prgb != 0xFFFFFF)
+ {
+ if (clearType)
+ {
+ rAlpha = pixel[2];
+ gAlpha = pixel[1];
+ bAlpha = pixel[0];
+ }
+
+ UINT value = pixel[0] + pixel[1] + pixel[2];
+ value = value / 3;
+ alpha = (BYTE)value;
+
+ if (!clearType)
+ {
+ rAlpha = alpha;
+ gAlpha = alpha;
+ bAlpha = alpha;
+ }
+
+ //alpha=pixel[0];
+ //alpha = (((float)pixel[0] - MIN_TONE) / (255.0 - MIN_TONE)) * 255 ;
+
+ //min = (min > value) ? value : min;
+ //max = (max < value) ? value : max;
+ }
+
+ pixel[3] = (BYTE)alpha;
+ pixel[2] = ((GetRValue(color) * rAlpha) + 128) / 255;
+ pixel[1] = ((GetGValue(color) * gAlpha) + 128) / 255;
+ pixel[0] = ((GetBValue(color) * bAlpha) + 128) / 255;
+ }
+ }
+ }
+
+ canvas->blitAlpha(dest, _x + VERTICAL_LPADDING, _y + VERTICAL_TPADDING);
+ //SkinBitmap *bitmap = canvas->getSkinBitmap();
+ //bitmap->blitAlpha(dest, _x + VERTICAL_LPADDING, _y + VERTICAL_TPADDING);
+
+ SelectObject(canvas->getHDC(), oldFont);
+ oldFont = 0;
+ DeleteObject(font);
+ font = 0;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
+{
+ int w, h;
+ c->getDim(&w, &h);
+
+ if (!h || !w) return;
+
+ BltCanvas canvas;
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
+ canvas.DestructiveResize(w, h);
+
+ TextOutW(canvas.getHDC(), x + xoffset, y + yoffset, txt, wcslen(txt));
+
+ restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::textOut2(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
+{
+ if (!h || !w) return;
+
+ BltCanvas canvas;
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
+ canvas.DestructiveResize(/*x +*/ w, /*y +*/ h);
+
+ RECT r = {
+ /*x +*/ xoffset,
+ /*y + */yoffset,
+ /*x + */w,
+ /*y + */h
+ };
+
+ DrawTextW(canvas.getHDC(), txt, -1, &r, align | DT_NOPREFIX | DT_NOCLIP);
+
+ restoreCanvas(&canvas, c, /*x + */w, /*y + */h, color, bkcolor, antialiased, x, y);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
+{
+ if (!h || !w) return;
+
+ BltCanvas canvas;
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
+ canvas.DestructiveResize(/*x + */w, /*y + */h);
+
+ RECT r = {
+ /*x + */xoffset,
+ /*y + */yoffset,
+ /*x + */w,
+ /*y + */ h
+ };
+
+ DrawTextW(canvas.getHDC(), txt, -1, &r, align | DT_NOPREFIX | DT_END_ELLIPSIS | DT_NOCLIP);
+ restoreCanvas(&canvas, c,/* x + */w, /*y + */h, color, bkcolor, antialiased, x, y);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
+{
+ if (!h || !w) return;
+
+ BltCanvas canvas;
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
+ canvas.DestructiveResize(w, h);
+
+ RECT r;
+ r.left = x + xoffset;
+ r.top = y + yoffset;
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+
+ DrawTextW(canvas.getHDC(), txt, -1, &r, align | DT_NOPREFIX | DT_WORDBREAK);
+
+ restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
+{
+ int w_dummy, h;
+ c->getDim(&w_dummy, &h);
+
+ if (!h || !w) return;
+
+ BltCanvas canvas;
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
+ canvas.DestructiveResize(w, h);
+
+ RECT r;
+ wchar_t *ptr, *d;
+ const wchar_t *s;
+ ptr = (wchar_t *)MALLOC(sizeof(wchar_t) * (wcslen(txt) + 1 + 4));
+ for (s = txt, d = ptr; *s; s++, d++)
+ {
+ if (*s == '/') *d = '\\';
+ else *d = *s;
+ }
+ r.left = x + xoffset;
+ r.top = y + yoffset;
+ r.right = r.left + w;
+ r.bottom = r.top + getTextHeight2(c, size, bold, underline, italic, antialiased);
+
+ DrawTextW(canvas.getHDC(), ptr, -1, &r, align | DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_SINGLELINE | DT_MODIFYSTRING | DT_CALCRECT);
+
+ for (d = ptr; *d; d++)
+ {
+ if (*d == '\\') *d = '/';
+ }
+
+ DrawTextW(canvas.getHDC(), ptr, -1, &r, align | DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_SINGLELINE);
+ restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased);
+
+ FREE(ptr);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialiased)
+{
+ yoffset += 1;
+ ASSERT(r != NULL);
+ ASSERT(txt != NULL);
+ RECT rr = *r;
+ rr.left += xoffset;
+ rr.right += xoffset;
+ rr.top += yoffset;
+ rr.bottom += yoffset;
+
+ int w = rr.right - rr.left;
+ int h = rr.bottom - rr.top;
+
+ RECT r2 = {0, 0, w, h};
+
+ BltCanvas canvas;
+ prepareCanvas(&canvas, size, bold, opaque, underline, italic, antialiased);
+ canvas.DestructiveResize(w, h);
+
+ DrawTextW(canvas.getHDC(), txt, -1, &r2, align | DT_CENTER | /*DT_VCENTER | */DT_NOPREFIX | DT_WORDBREAK | DT_SINGLELINE);
+
+ restoreCanvas(&canvas, c, w, h, color, bkcolor, antialiased, rr.left, rr.top);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Win32::getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
+{
+ int w = 0;
+ getTextExtent(c, text, &w, NULL, size, bold, underline, italic, antialiased);
+ return w;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Win32::getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialiased)
+{
+ int h = 0;
+ getTextExtent(c, text, NULL, &h, size, bold, underline, italic, antialiased);
+ {
+ // calcul for multiline text
+ const wchar_t *p = text;
+ int n = 0;
+ while (p && *p != 0) if (*p++ == '\n') n++;
+ if (n) h *= (n + 1);
+ }
+ return h ;
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+void TrueTypeFont_Win32::getTextExtent(ifc_canvas *c, const wchar_t *txt, int *w, int *h, int size, int bold, int underline, int italic, int antialiased)
+{
+ SIZE rsize = {0, 0};
+ ASSERT(txt != NULL);
+ if (*txt == 0)
+ {
+ if (w != NULL) *w = 0;
+ if (h != NULL) *h = 0;
+ return ;
+ }
+
+ HFONT newFont = MakeFont(size, bold, underline, italic, antialiased);
+ HFONT theOldFont = (HFONT)SelectObject(c->getHDC(), newFont);
+ GetTextExtentPoint32W(c->getHDC(), txt, wcslen(txt), &rsize);
+
+ SelectObject(c->getHDC(), theOldFont);
+ DeleteObject(newFont);
+
+ if (w != NULL) *w = rsize.cx + VERTICAL_LPADDING + VERTICAL_RPADDING;
+ if (h != NULL) *h = rsize.cy + VERTICAL_TPADDING + VERTICAL_BPADDING;
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+int TrueTypeFont_Win32::getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialiased)
+{
+ return getTextHeight(c, L"Mg", size, bold, underline, italic, antialiased);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------------------------------
+// code from ftp.microsoft.com/Softlib/MSLFILES/FONTINST.EXE
+// retrieves the friendly font name from its filename
+wchar_t *TrueTypeFont_Win32::filenameToFontFace(const wchar_t *pszFile)
+{
+ static wchar_t lpszLongName[256];
+ unsigned i;
+ char namebuf[255] = {0};
+ int fp;
+ unsigned short numNames;
+ long curseek;
+ unsigned cTables;
+ sfnt_OffsetTable OffsetTable;
+ sfnt_DirectoryEntry Table;
+ sfnt_NamingTable NamingTable;
+ sfnt_NameRecord NameRecord;
+
+
+ lpszLongName[0] = '\0';
+ if ((fp = _wopen(pszFile, O_RDONLY | O_BINARY)) == -1)
+ return NULL;
+
+ /* First off, read the initial directory header on the TTF. We're only
+ * interested in the "numOffsets" variable to tell us how many tables
+ * are present in this file.
+ *
+ * Remember to always convert from Motorola format (Big Endian to
+ * Little Endian).
+ */
+ _read(fp, &OffsetTable, sizeof(OffsetTable) - sizeof
+ (sfnt_DirectoryEntry));
+ cTables = (int) SWAPW(OffsetTable.numOffsets);
+
+ for (i = 0; i < cTables && i < 40; i++)
+ {
+ if ((read(fp, &Table, sizeof(Table))) != sizeof(Table)) return NULL;
+ if (Table.tag == tag_NamingTable) /* defined in sfnt_en.h */ {
+ /* Now that we've found the entry for the name table, seek to that * position in the file and read in the initial header for this * particular table. See "True Type Font Files" for information * on this record layout.
+ */
+ lseek(fp, SWAPL(Table.offset), SEEK_SET);
+ read(fp, &NamingTable, sizeof(NamingTable));
+ numNames = SWAPW(NamingTable.count);
+ while (numNames--)
+ {
+ read(fp, &NameRecord, sizeof(NameRecord));
+ curseek = tell(fp);
+ if (SWAPW(NameRecord.platformID) == 1 &&
+ SWAPW(NameRecord.nameID) == 4)
+ {
+ lseek(fp, SWAPW(NameRecord.offset) +
+ SWAPW(NamingTable.stringOffset) +
+ SWAPL(Table.offset), SEEK_SET);
+ read(fp, &namebuf, MIN(255, (int)SWAPW(NameRecord.length)));
+ namebuf[MIN(255, (int)SWAPW(NameRecord.length))] = '\0';
+ MultiByteToWideCharSZ(1252, 0, namebuf, -1, lpszLongName, 256); // TODO: benski> what codepage is TTF using internally?
+ //CUT: lstrcpy(lpszLongName, namebuf);
+ lseek(fp, curseek, SEEK_SET);
+ }
+ }
+ close(fp);
+ return lpszLongName;
+ }
+ }
+ close(fp);
+
+ return NULL;
+}
+
+
+/*
+TODO:
+in order to do anti-aliased stuff, we need to draw onto a Compatible Bitmap, and then get the DIB bits out
+we might also be able to create a Compatible HBITMAP and then pass it as the constructor parameter to SkinBitmap
+
+sample code:
+void RenderFont(int x, int y, int size, char *str, char *fontname,
+ void *buf, int w, int h)
+ {
+
+ HDC hdc=GetDC(NULL);
+ HDC mdc = CreateCompatibleDC(hdc);
+ HBITMAP bm = CreateCompatibleBitmap(hdc,w,h);
+
+ HFONT hf=CreateFont(size, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
+ ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
+ ANTIALIASED_QUALITY, DEFAULT_PITCH, fontname);
+
+ RECT r;
+ r.top=0;
+ r.left=0;
+ r.right=w;
+ r.bottom=h;
+
+ SelectObject(mdc, bm);
+ FillRect(mdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
+
+ SelectObject(mdc, hf);
+ SetBkMode(mdc, TRANSPARENT);
+ SetTextColor(mdc, 0xFFFFFF);
+ TextOut(mdc, 0, 0, str, strlen(str));
+
+ BITMAPINFO bmi;
+
+ bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader);
+ bmi.bmiHeader.biWidth=256;
+ bmi.bmiHeader.biHeight=256;
+ bmi.bmiHeader.biPlanes=1;
+ bmi.bmiHeader.biBitCount=32;
+ bmi.bmiHeader.biCompression=BI_RGB;
+
+ GetDIBits(mdc,bm,0,256,buf,&bmi,DIB_RGB_COLORS);
+
+ DeleteObject(hf);
+ DeleteObject(bm);
+}
+*/ \ No newline at end of file
diff --git a/Src/Wasabi/api/font/win32/truetypefont_win32.h b/Src/Wasabi/api/font/win32/truetypefont_win32.h
new file mode 100644
index 00000000..e8afff21
--- /dev/null
+++ b/Src/Wasabi/api/font/win32/truetypefont_win32.h
@@ -0,0 +1,61 @@
+#ifndef __TRUETYPEFONT_WN32_H
+#define __TRUETYPEFONT_WN32_H
+
+#include <api/font/svc_fonti.h>
+
+#include <bfc/stack.h>
+#include <api/font/truetypefontdef.h>
+#include <tataki/canvas/bltcanvas.h>
+class ifc_canvas;
+class BltCanvas;
+
+class TrueTypeFont_Win32 : public svc_fontI {
+ public:
+ TrueTypeFont_Win32();
+ virtual ~TrueTypeFont_Win32();
+
+ virtual void textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOut2(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual void textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, COLORREF color, COLORREF bkcolor, int xoffset, int yoffset, int antialias);
+ virtual int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias);
+ virtual int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias);
+ virtual int getTextHeight2(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias);
+ virtual void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias);
+
+ virtual void setFontId(const wchar_t *id) { font_id = id; }
+ virtual const wchar_t *getFontId() { return font_id; }
+ virtual int getScriptId() { return scriptid; }
+ virtual void setScriptId(int id) { scriptid = id; }
+
+ virtual int isBitmap();
+ virtual void setFontFace(const wchar_t *face);
+ virtual int addFontResource(OSFILETYPE f, const wchar_t *name);
+ virtual int addFontResource2( void *data, int datalen, const wchar_t *name );
+ virtual const wchar_t *getFaceName();
+
+ virtual const wchar_t *getFontSvcName() { return L"Win32 TextOut"; }
+ static const char *getServiceName() { return "Win32 Truetype font renderer"; }
+
+ static wchar_t *filenameToFontFace(const wchar_t *filename);
+
+ protected:
+ void prepareCanvas(BltCanvas *canvas, int size, int bold, int opaque, int underline, int italic, int antialiased);
+ void restoreCanvas(BltCanvas *canvas, ifc_canvas *dest, int w, int h, COLORREF color, COLORREF bkcolor, int antialiased, int x=0, int y=0);
+ HFONT MakeFont(int size, int bold, int underline, int italic, int antialiased);
+
+ protected:
+ StringW font_id;
+ int scriptid;
+
+ private:
+ StringW face_name;
+ StringW tmpfilename;
+
+ HFONT font, oldFont;
+
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/imgldr/ImgLoaderEnum.h b/Src/Wasabi/api/imgldr/ImgLoaderEnum.h
new file mode 100644
index 00000000..e71f4c4d
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/ImgLoaderEnum.h
@@ -0,0 +1,24 @@
+#ifndef __WASABI_IMGLOADERENUM_H
+#define __WASABI_IMGLOADERENUM_H
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class ImgLoaderEnum : public SvcEnumT<svc_imageLoader> {
+public:
+ ImgLoaderEnum(uint8_t *data, int datalen) : mem(datalen, data) { }
+ ImgLoaderEnum(const wchar_t *filename) : fname(filename) { }
+
+protected:
+ virtual int testService(svc_imageLoader *svc)
+ {
+ if (!fname.isempty() && !svc->isMine(fname)) return 0;
+ return svc->testData(mem, mem.getSizeInBytes());
+ }
+
+private:
+ StringW fname;
+ MemBlock<uint8_t> mem;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/imgldr/api_imgldr.cpp b/Src/Wasabi/api/imgldr/api_imgldr.cpp
new file mode 100644
index 00000000..20d03bcf
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/api_imgldr.cpp
@@ -0,0 +1,20 @@
+#include <precomp.h>
+#include "api_imgldr.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS imgldr_apiI
+START_DISPATCH;
+ CB(IMGLDR_API_MAKEBMP, imgldr_makeBmp);
+#ifdef _WIN32
+ CB(IMGLDR_API_MAKEBMP2, imgldr_makeBmp2);
+#endif
+ VCB(IMGLDR_API_RELEASEBMP, imgldr_releaseBmp);
+#ifdef WASABI_COMPILE_SKIN
+ CB(IMGLDR_API_REQUESTSKINBITMAP, imgldr_requestSkinBitmap);
+ CB(IMGLDR_API_REQUESTSKINREGION, imgldr_requestSkinRegion);
+ VCB(IMGLDR_API_CACHESKINREGION, imgldr_cacheSkinRegion);
+ VCB(IMGLDR_API_RELEASESKINBITMAP, imgldr_releaseSkinBitmap);
+#endif //WASABI_COMPILE_SKIN
+END_DISPATCH;
diff --git a/Src/Wasabi/api/imgldr/api_imgldr.h b/Src/Wasabi/api/imgldr/api_imgldr.h
new file mode 100644
index 00000000..55e19bec
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/api_imgldr.h
@@ -0,0 +1,98 @@
+#ifndef __API_IMGLOADER_H
+#define __API_IMGLOADER_H
+
+#include <wasabicfg.h>
+#include <bfc/dispatch.h>
+
+class RegionServer;
+class api_region;
+
+class imgldr_api : public Dispatchable
+{
+public:
+ ARGB32 *imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h);
+ ARGB32 *imgldr_makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup = NULL);
+ void imgldr_releaseBmp(ARGB32 *bmpbits);
+ ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached);
+ RegionServer *imgldr_requestSkinRegion(const wchar_t *id);
+ void imgldr_cacheSkinRegion(const wchar_t *id, api_region *r);
+ void imgldr_releaseSkinBitmap(ARGB32 *bmpbits);
+
+ DISPATCH_CODES
+ {
+ IMGLDR_API_MAKEBMP = 0,
+ IMGLDR_API_MAKEBMP2 = 10,
+ IMGLDR_API_RELEASEBMP = 20,
+ IMGLDR_API_REQUESTSKINBITMAP = 30,
+ IMGLDR_API_REQUESTSKINREGION = 40,
+ IMGLDR_API_CACHESKINREGION = 50,
+ IMGLDR_API_RELEASESKINBITMAP = 60,
+ };
+};
+
+inline ARGB32 *imgldr_api::imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h)
+{
+ return _call(IMGLDR_API_MAKEBMP, (ARGB32 *)NULL, filename, has_alpha, w, h);
+}
+
+inline ARGB32 *imgldr_api::imgldr_makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup)
+{
+ return _call(IMGLDR_API_MAKEBMP2, (ARGB32 *)NULL, hInst, id, has_alpha, w, h, colorgroup);
+}
+
+inline void imgldr_api::imgldr_releaseBmp(ARGB32 *bmpbits)
+{
+ _voidcall(IMGLDR_API_RELEASEBMP, bmpbits);
+}
+
+#ifdef WASABI_COMPILE_SKIN
+
+inline ARGB32 *imgldr_api::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached)
+{
+ return _call(IMGLDR_API_REQUESTSKINBITMAP, (ARGB32 *)NULL, file, has_alpha, x, y, subw, subh, w, h, cached);
+}
+
+inline RegionServer *imgldr_api::imgldr_requestSkinRegion(const wchar_t *id)
+{
+ return _call(IMGLDR_API_REQUESTSKINREGION, (RegionServer *)NULL, id);
+}
+
+inline void imgldr_api::imgldr_cacheSkinRegion(const wchar_t *id, api_region *r)
+{
+ _voidcall(IMGLDR_API_CACHESKINREGION, id, r);
+}
+
+inline void imgldr_api::imgldr_releaseSkinBitmap(ARGB32 *bmpbits)
+{
+ _voidcall(IMGLDR_API_RELEASESKINBITMAP, bmpbits);
+}
+
+#endif //WASABI_COMPILE_SKIN
+
+class imgldr_apiI : public imgldr_api
+{
+public:
+ virtual ARGB32 *imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h) = 0;
+#ifdef _WIN32
+ virtual ARGB32 *imgldr_makeBmp2(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup = NULL) = 0;
+#endif
+ virtual void imgldr_releaseBmp(ARGB32 *bmpbits) = 0;
+#ifdef WASABI_COMPILE_SKIN
+ virtual ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) = 0;
+ virtual RegionServer *imgldr_requestSkinRegion(const wchar_t *id) = 0;
+ virtual void imgldr_cacheSkinRegion(const wchar_t *id, api_region *r) = 0;
+ virtual void imgldr_releaseSkinBitmap(ARGB32 *bmpbits) = 0;
+#endif //WASABI_COMPILE_SKIN
+
+protected:
+ RECVS_DISPATCH;
+};
+
+// {703ECC7C-B3D8-4e1e-B8B5-A7563D9D6F30}
+static const GUID imgLdrApiServiceGuid =
+ { 0x703ecc7c, 0xb3d8, 0x4e1e, { 0xb8, 0xb5, 0xa7, 0x56, 0x3d, 0x9d, 0x6f, 0x30 } };
+
+extern imgldr_api *imgLoaderApi;
+
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/imggen/grad.cpp b/Src/Wasabi/api/imgldr/imggen/grad.cpp
new file mode 100644
index 00000000..acec2eab
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/grad.cpp
@@ -0,0 +1,60 @@
+#include "precomp.h"
+
+#include "grad.h"
+
+#include <api/xml/xmlparams.h>
+#include <api/memmgr/api_memmgr.h>
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(GradientGen_Svc);
+DECLARE_SERVICETSINGLE(svc_imageGenerator, GradientImage);
+END_SERVICES(GradientGen_Svc, _GradientGen_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_GradientGen_Svc; }
+#else
+extern "C" { int __link_GradientGen_Svc; }
+#endif
+
+#endif
+
+
+int GradientImage::testDesc(const wchar_t *desc) {
+ return !_wcsicmp(desc, L"$gradient");
+}
+
+ARGB32 *GradientImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params)
+{
+ int _w = params->getItemValueInt(L"w",1);
+ if (_w == 0) _w = 1;
+ int _h = params->getItemValueInt(L"h",1);
+ if (_h == 0) _h = 1;
+ if (_w <= 0 || _h <= 0) return NULL;
+
+#ifdef WASABI_COMPILE_MEMMGR
+ ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32));
+#else
+ ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32));
+#endif
+
+ setX1((float)WTOF(params->getItemValue(L"gradient_x1")));
+ setY1((float)WTOF(params->getItemValue(L"gradient_y1")));
+ setX2((float)WTOF(params->getItemValue(L"gradient_x2")));
+ setY2((float)WTOF(params->getItemValue(L"gradient_y2")));
+
+ setPoints(params->getItemValue(L"points"));
+
+ setMode(params->getItemValue(L"mode"));
+
+ setReverseColors(TRUE); // cuz we're imggen
+
+ setAntialias(params->getItemValueInt(L"antialias"));
+
+ renderGradient(ret, _w, _h);
+
+ *w = _w;
+ *h = _h;
+ *has_alpha = 1; // will be optimized anyway
+
+ return ret;
+}
diff --git a/Src/Wasabi/api/imgldr/imggen/grad.h b/Src/Wasabi/api/imgldr/imggen/grad.h
new file mode 100644
index 00000000..8ee4c886
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/grad.h
@@ -0,0 +1,15 @@
+#ifndef _GRAD_H
+#define _GRAD_H
+
+#include <api/service/svcs/svc_imggen.h>
+#include <bfc/draw/gradient.h>
+
+class GradientImage : public svc_imageGeneratorI, public Gradient
+{
+public:
+ static const char *getServiceName() { return "Gradient image generator"; }
+ virtual int testDesc(const wchar_t *desc);
+ virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params=NULL);
+};
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/imggen/imggen.cpp b/Src/Wasabi/api/imgldr/imggen/imggen.cpp
new file mode 100644
index 00000000..bcf0b6d4
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/imggen.cpp
@@ -0,0 +1,29 @@
+#include "precomp.h"
+#include "imggen.h"
+
+#include "solid.h"
+#include "grad.h"
+#include "osedge.h"
+#include "poly.h"
+#include "shadowwnd.h"
+
+#include "../studio/services/servicei.h"
+
+static WACNAME wac;
+WAComponentClient *the = &wac;
+
+// {9C9CB15E-2904-4df2-B8CE-FFBC6CD230DC}
+static const GUID guid =
+{ 0x9c9cb15e, 0x2904, 0x4df2, { 0xb8, 0xce, 0xff, 0xbc, 0x6c, 0xd2, 0x30, 0xdc } };
+
+WACNAME::WACNAME() {
+ registerService(new waServiceFactoryTSingle<svc_imageGenerator, SolidImage>);
+ registerService(new waServiceFactoryTSingle<svc_imageGenerator, GradientImage>);
+ registerService(new waServiceFactoryTSingle<svc_imageGenerator, OsEdgeImage>);
+ registerService(new waServiceFactoryTSingle<svc_imageGenerator, PolyImage>);
+ registerService(new XuiObjectCreator<XuiShadowWndSvc>);
+}
+
+GUID WACNAME::getGUID() {
+ return guid;
+}
diff --git a/Src/Wasabi/api/imgldr/imggen/imggen.h b/Src/Wasabi/api/imgldr/imggen/imggen.h
new file mode 100644
index 00000000..9af473d5
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/imggen.h
@@ -0,0 +1,14 @@
+#ifndef _IMGGEN_H
+#define _IMGGEN_H
+
+#include "../studio/wac.h"
+
+#define WACNAME WACimggen
+class WACNAME : public WAComponentClient {
+public:
+ WACNAME();
+
+ virtual const char *getName() { return "Standard Image Generators"; };
+ virtual GUID getGUID();
+};
+#endif
diff --git a/Src/Wasabi/api/imgldr/imggen/osedge.cpp b/Src/Wasabi/api/imgldr/imggen/osedge.cpp
new file mode 100644
index 00000000..c699a860
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/osedge.cpp
@@ -0,0 +1,95 @@
+#include "precomp.h"
+
+#include "osedge.h"
+#include <api/xml/xmlparams.h>
+#include <bfc/parse/pathparse.h>
+#include <api/memmgr/api_memmgr.h>
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(OsEdgeGen_Svc);
+DECLARE_SERVICETSINGLE(svc_imageGenerator, OsEdgeImage);
+END_SERVICES(OsEdgeGen_Svc, _OsEdgeGen_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_OsEdgeGen_Svc; }
+#else
+extern "C" { int __link_OsEdgeGen_Svc; }
+#endif
+
+#endif
+
+
+int OsEdgeImage::testDesc(const wchar_t *desc) {
+ return !_wcsicmp(desc, L"$osedge");
+}
+
+ARGB32 *OsEdgeImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params)
+{
+ int _w = params->getItemValueInt(L"w", 1);
+ if (_w == 0) _w = 1;
+ int _h = params->getItemValueInt(L"h", 1);
+ if (_h == 0) _h = 1;
+ if (_w <= 0 || _h <= 0) return NULL;
+
+#ifdef WASABI_COMPILE_MEMMGR
+ ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32));
+#else
+ ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32));
+#endif
+
+ RECT r = Wasabi::Std::makeRect(0, 0, _w, _h);
+
+ BITMAPINFO bmi;
+ ZERO(bmi);
+ bmi.bmiHeader.biSize = sizeof(bmi);
+ bmi.bmiHeader.biWidth = _w;
+ bmi.bmiHeader.biHeight = -_h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ // the rest are 0
+ ARGB32 *bits;
+ HBITMAP hbmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+ HDC hdc = CreateCompatibleDC(NULL);
+ HBITMAP prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
+
+ unsigned long edgev = 0;
+ if (!_wcsicmp(params->getItemValue(L"edge"), L"bump")) edgev = EDGE_BUMP;
+ else if (!_wcsicmp(params->getItemValue(L"edge"), L"etched")) edgev = EDGE_ETCHED;
+ else if (!_wcsicmp(params->getItemValue(L"edge"), L"raised")) edgev = EDGE_RAISED;
+ else if (!_wcsicmp(params->getItemValue(L"edge"), L"sunken")) edgev = EDGE_SUNKEN;
+ if (edgev == 0) edgev = EDGE_RAISED;
+
+ unsigned long sides = 0;
+ PathParserW pp(params->getItemValue(L"sides"), L",");
+ for (int i = 0; i < pp.getNumStrings(); i++) {
+ const wchar_t *p = pp.enumString(i);
+ if (!_wcsicmp(p, L"left")) sides |= BF_LEFT;
+ if (!_wcsicmp(p, L"top")) sides |= BF_TOP;
+ if (!_wcsicmp(p, L"right")) sides |= BF_RIGHT;
+ if (!_wcsicmp(p, L"bottom")) sides |= BF_BOTTOM;
+ if (!_wcsicmp(p, L"all")) sides |= BF_RECT;
+ if (!_wcsicmp(p, L"middle")) sides |= BF_MIDDLE;
+ if (!_wcsicmp(p, L"flat")) sides |= BF_FLAT;
+ if (!_wcsicmp(p, L"soft")) sides |= BF_SOFT;
+ if (!_wcsicmp(p, L"mono")) sides |= BF_MONO;
+ }
+
+// DO EET
+ DrawEdge(hdc, &r, edgev, sides);
+
+ MEMCPY(ret, bits, sizeof(ARGB32) * _w * _h);
+ for (int i = 0; i < _w * _h; i++) { // force alpha
+ ret[i] |= 0xff000000;
+ }
+
+ SelectObject(hdc, prevbmp);
+ DeleteDC(hdc);
+ DeleteObject(hbmp);
+
+ *w = _w;
+ *h = _h;
+ *has_alpha = 1; // will be optimized anyway
+
+ return ret;
+}
diff --git a/Src/Wasabi/api/imgldr/imggen/osedge.h b/Src/Wasabi/api/imgldr/imggen/osedge.h
new file mode 100644
index 00000000..f00771a1
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/osedge.h
@@ -0,0 +1,13 @@
+#ifndef _OSEDGE_H
+#define _OSEDGE_H
+
+#include <api/service/svcs/svc_imggen.h>
+
+class OsEdgeImage : public svc_imageGeneratorI {
+public:
+ static const char *getServiceName() { return "OS Edge image generator"; }
+ virtual int testDesc(const wchar_t *desc);
+ virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params=NULL);
+};
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/imggen/poly.cpp b/Src/Wasabi/api/imgldr/imggen/poly.cpp
new file mode 100644
index 00000000..086664e8
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/poly.cpp
@@ -0,0 +1,59 @@
+#include "precomp.h"
+
+#include "poly.h"
+
+#include <api/xml/xmlparams.h>
+#include <api/memmgr/api_memmgr.h>
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(PolyGen_Svc);
+DECLARE_SERVICETSINGLE(svc_imageGenerator, PolyImage);
+END_SERVICES(PolyGen_Svc, _PolyGen_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_PolyGen_Svc; }
+#else
+extern "C" { int __link_PolyGen_Svc; }
+#endif
+
+#endif
+
+int PolyImage::testDesc(const wchar_t *desc) {
+ return !_wcsicmp(desc, L"$polygon");
+}
+
+void premultiply(ARGB32 *m_pBits, int nwords);
+
+#include <bfc/draw/drawpoly.h>
+
+ARGB32 *PolyImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params)
+{
+ int _w = (params->getItemValueInt(L"w", 1));
+ if (_w == 0) _w = 1;
+ int _h = (params->getItemValueInt(L"h", 1));
+ if (_h == 0) _h = 1;
+ if (_w <= 0 || _h <= 0) return NULL;
+
+ const wchar_t *bgcolorstr = params->getItemValue(L"bgcolor");
+ ARGB32 bgcolor = (bgcolorstr == NULL || *bgcolorstr=='\0') ? 0 : _byteswap_ulong(WASABI_API_SKIN->parse(params->getItemValue(L"bgcolor"), L"color")<<8);
+
+ unsigned int bgalpha = params->getItemValueInt(L"bgalpha", 0);
+ bgcolor |= ((bgalpha & 0xff) << 24);
+
+ premultiply(&bgcolor, 1);
+
+#ifdef WASABI_COMPILE_MEMMGR
+ ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32));
+#else
+ ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32));
+#endif
+
+ MEMFILL<ARGB32>(ret, bgcolor, _w * _h);
+
+ Draw::drawPointList(ret, _w, _h, params->getItemValue(L"points"));
+
+ *w = _w;
+ *h = _h;
+ *has_alpha = 1;
+ return ret;
+}
diff --git a/Src/Wasabi/api/imgldr/imggen/poly.h b/Src/Wasabi/api/imgldr/imggen/poly.h
new file mode 100644
index 00000000..07095056
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/poly.h
@@ -0,0 +1,13 @@
+#ifndef _POLY_H
+#define _POLY_H
+
+#include <api/service/svcs/svc_imggen.h>
+
+class PolyImage : public svc_imageGeneratorI {
+public:
+ static const char *getServiceName() { return "Polygon image generator"; }
+ virtual int testDesc(const wchar_t *desc);
+ virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params=NULL);
+};
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp b/Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp
new file mode 100644
index 00000000..fb61c95c
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp
@@ -0,0 +1,152 @@
+#include "precomp.h"
+
+#include "shadowwnd.h"
+
+#include "../bfc/canvas.h"
+#include "../bfc/region.h"
+
+enum { TARGET };
+
+char XuiShadowWndParams[][]=
+{
+ "TARGET",
+};
+XuiShadowWnd::XuiShadowWnd() {
+ myxuihandle = newXuiHandle();
+ addParam(myxuihandle, XuiShadowWndParams[0], TARGET, XUI_ATTRIBUTE_REQUIRED);
+ group = NULL;
+ bltcanvas = NULL;
+ c_w = c_h = 0;
+ in_paint = 0;
+}
+
+XuiShadowWnd::~XuiShadowWnd() {
+ delete bltcanvas;
+}
+
+int XuiShadowWnd::onInit() {
+ XUISHADOWWND_PARENT::onInit();
+
+DebugString("on iniiit");
+
+ attachToGroup();
+setTimer(10, 50);
+
+ return 1;
+}
+
+void XuiShadowWnd::timerclient_timerCallback(int id) {
+ if (id == 10) {
+ if (group == NULL) attachToGroup();
+ delete bltcanvas;
+ RECT r; group->getClientRect(&r);
+ bltcanvas = new BltCanvas(r.right - r.left, r.bottom - r.top);
+ in_paint++;
+ group->paint(bltcanvas);
+MEMFILL<ARGB32>((unsigned long *)bltcanvas->getBits(), 0xffffffff, (r.right - r.left) * 20);
+ in_paint--;
+ invalidate();
+ } else
+ XUISHADOWWND_PARENT::timerclient_timerCallback(id);
+}
+
+int XuiShadowWnd::onPaint(Canvas *canvas) {
+#if 0
+if (group == NULL) attachToGroup();
+if (group == NULL) { DebugString("groupNull"); }
+if (group == NULL) return 0;
+
+#endif
+DebugString("begin painting");
+
+if (in_paint++) {
+// RECT cr = clientRect();
+// canvas->fillRect(&cr, RGB(255,0,255));
+//MEMFILL<ARGB32>((unsigned long *)canvas->getBits(), 0xffffffff, (cr.right - cr.left) * 20);
+DebugString("filla!");
+} else {
+#if 0
+ RECT cr;
+ group->getClientRect(&cr);
+ SkinBitmap *bm
+bltcanvas->blit(0, 0,
+BltCanvas c(cr.right - cr.left, cr.bottom - cr.top);
+group->paint(&c);
+#if 0
+c.pushPen(0,255,0);
+c.lineDraw(0, 0, cr.right, cr.bottom);
+/c.popPen();
+#endif
+MEMFILL<ARGB32>((unsigned long *)c.getBits(), 0xffffffff, (cr.right - cr.left) * 20);
+c.blit(0, 0, canvas, 0, 0, cr.right - cr.left, cr.bottom - cr.top);
+
+DebugString("get from group!");
+#endif
+ if (bltcanvas != NULL) {
+ SkinBitmap *bm = bltcanvas->getSkinBitmap();
+ bm->stretchToRectAlpha(canvas, &clientRect(), getPaintingAlpha());
+DebugString("bleet!");
+ }
+}
+in_paint--;
+ return 1;
+}
+
+int XuiShadowWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return XUISHADOWWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+ switch (xmlattributeid) {
+ case TARGET:
+ targetname = value;
+DebugString("set target %s", value);
+ if (isPostOnInit()) attachToGroup();
+ break;
+ default: return 0;
+ }
+ return 1;
+}
+
+void XuiShadowWnd::attachToGroup() {
+ if (targetname.isempty()) return;
+ group = findWindow(targetname);
+ if (group == NULL) return;
+ monitorWindow(group);
+DebugString("attached to group rw %d", group);
+
+ delete bltcanvas; bltcanvas = NULL;
+}
+
+void XuiShadowWnd::onAfterPaint(PaintCallbackInfo *info) {
+DebugString("after paint");
+#if 0
+ RECT ncr;
+ group->getNonClientRect(&ncr);
+ c_w = ncr.right - ncr.left;
+ c_h = ncr.bottom - ncr.top;
+
+DebugString("w %d h %d", c_w, c_h);
+
+ delete bltcanvas; bltcanvas = NULL;
+ if (c_w != 0 && c_h != 0) bltcanvas = new BltCanvas(c_w, c_h);
+
+ Canvas *c = info->getCanvas();
+ api_region *r = info->getRegion();
+ // blit what changed
+ RegionI saved;
+ c->getClipRgn(&saved);
+ bltcanvas->selectClipRgn(r);
+ c->blit(0, 0, bltcanvas, 0, 0, c_w, c_h);
+ c->selectClipRgn(&saved);
+
+ invalidate();
+#endif
+}
+
+void XuiShadowWnd::onInvalidation(PaintCallbackInfo *info) {
+// invalidate();
+DebugString("got invalidate");
+}
+
+void XuiShadowWnd::onWindowDeleted(api_window *w) {
+ if (w == group) group = NULL;
+}
diff --git a/Src/Wasabi/api/imgldr/imggen/shadowwnd.h b/Src/Wasabi/api/imgldr/imggen/shadowwnd.h
new file mode 100644
index 00000000..8082dba5
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/shadowwnd.h
@@ -0,0 +1,40 @@
+#ifndef _SHADOW_H
+#define _SHADOW_H
+
+#include "../common/guiobjwnd.h"
+#include "../bfc/paintcb.h"
+
+#define XUISHADOWWND_PARENT GuiObjectWnd
+class XuiShadowWnd : public XUISHADOWWND_PARENT, public PaintCallback {
+public:
+ static const wchar_t *xuiobject_getXmlTag() { return "Shadow"; }
+ static const char *xuiobject_getServiceName() { return "Shadow XuiObject"; }
+
+ XuiShadowWnd();
+ virtual ~XuiShadowWnd();
+
+ virtual int onInit();
+
+ virtual int onPaint(Canvas *canvas);
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void onAfterPaint(PaintCallbackInfo *info);
+ virtual void onInvalidation(PaintCallbackInfo *info);
+protected:
+ virtual void onWindowDeleted(BaseWnd *w);
+ void attachToGroup();
+ virtual void timerclient_timerCallback(int id);
+
+private:
+ int myxuihandle;
+ StringW targetname;
+ api_window *group;
+ BltCanvas *bltcanvas;
+ int c_w, c_h;
+ int in_paint;
+};
+
+class XuiShadowWndSvc : public XuiObjectSvc2<XuiShadowWnd> {};
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/imggen/solid.cpp b/Src/Wasabi/api/imgldr/imggen/solid.cpp
new file mode 100644
index 00000000..7f461eaa
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/solid.cpp
@@ -0,0 +1,67 @@
+#include "precomp.h"
+
+#include "solid.h"
+#include <api/xml/xmlparams.h>
+#include <api/memmgr/api_memmgr.h>
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(SolidGen_Svc);
+DECLARE_SERVICETSINGLE(svc_imageGenerator, SolidImage);
+END_SERVICES(SolidGen_Svc, _SolidGen_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_SolidGen_Svc; }
+#else
+extern "C" { int __link_SolidGen_Svc; }
+#endif
+
+#endif
+
+int SolidImage::testDesc(const wchar_t *desc)
+{
+ return !WCSICMP(desc, L"$solid");
+}
+
+void premultiply(ARGB32 *m_pBits, int nwords)
+{
+ for (; nwords > 0; nwords--, m_pBits++)
+ {
+ unsigned __int8 *pixel = (unsigned __int8 *)m_pBits;
+ unsigned int alpha = pixel[3];
+ if (alpha == 255) continue;
+ pixel[0] = (pixel[0] * alpha) >> 8; // blue
+ pixel[1] = (pixel[1] * alpha) >> 8; // green
+ pixel[2] = (pixel[2] * alpha) >> 8; // red
+ }
+}
+
+ARGB32 *SolidImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params)
+{
+ int _w = params->getItemValueInt(L"w", 1);
+ if (_w == 0) _w = 1;
+ int _h = params->getItemValueInt(L"h", 1);
+ if (_h == 0) _h = 1;
+ if (_w <= 0 || _h <= 0) return NULL;
+ ARGB32 color = _byteswap_ulong(WASABI_API_SKIN->parse(params->getItemValue(L"color"), L"color") << 8);
+
+ unsigned int alpha = params->getItemValueInt(L"alpha", 255);
+ color |= ((alpha & 0xff) << 24);
+
+ premultiply(&color, 1);
+
+#ifdef WASABI_COMPILE_MEMMGR
+ ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32));
+#else
+ ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32));
+#endif
+
+ MEMFILL<ARGB32>(ret, color, _w * _h);
+
+ *w = _w;
+ *h = _h;
+
+ *has_alpha = (alpha == 255) ? 0 : 1;
+
+ return ret;
+}
diff --git a/Src/Wasabi/api/imgldr/imggen/solid.h b/Src/Wasabi/api/imgldr/imggen/solid.h
new file mode 100644
index 00000000..d810bc1c
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imggen/solid.h
@@ -0,0 +1,14 @@
+#ifndef _SOLID_H
+#define _SOLID_H
+
+#include <api/service/svcs/svc_imggen.h>
+
+class SolidImage : public svc_imageGeneratorI
+{
+public:
+ static const char *getServiceName() { return "Solid Color image generator"; }
+ virtual int testDesc(const wchar_t *desc);
+ virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params = NULL);
+};
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/imgldr.cpp b/Src/Wasabi/api/imgldr/imgldr.cpp
new file mode 100644
index 00000000..d7e33b54
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imgldr.cpp
@@ -0,0 +1,554 @@
+#include <precomp.h>
+#include <setjmp.h>
+#include <bfc/bfc_assert.h>
+#include <api.h>
+
+#include <bfc/wasabi_std.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/skin/skinfilter.h> // ApplySkinFilters
+
+#include "imgldr.h"
+#ifdef _WIN32
+#include <api/imgldr/winbmp.h>
+#endif
+#include <api/imgldr/skinbmps.h>
+
+#include <api/skin/skinparse.h>
+#include <api/skin/skinelem.h>
+#include <api/skin/gammamgr.h>
+
+#include <api/service/svcs/svc_skinfilter.h>
+#include <api/service/svcs/svc_imgload.h>
+#include <api/service/svcs/svc_imggen.h>
+#include "ImgLoaderEnum.h"
+#include <api/memmgr/api_memmgr.h>
+#include <bfc/string/PathString.h>
+#include <api/locales/localesmgr.h>
+
+//#define DEBUG_OUTPUT
+
+#define IMAGEHEADERLEN 256
+
+#ifdef _WIN32
+ARGB32 *imageLoader::makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *forcegroup)
+{
+ ARGB32 *bits = makeBmp(StringPrintfW(L"res://%u,%i", hInst, id), NULL, has_alpha, w, h, NULL, TRUE, NULL);
+ if (bits && *w > 0 && *h > 0)
+ {
+ ApplySkinFilters::apply(StringPrintfW(L"resource:%x,%d", hInst, id), forcegroup, bits, *w, *h);
+ }
+ return bits;
+}
+#endif
+
+StringW imageLoader::getWallpaper()
+{
+ StringW ret(L"");
+#ifdef WIN32
+ HKEY hkey;
+ static wchar_t file[MAX_PATH];
+ file[0] = 0;
+ if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), &hkey) == ERROR_SUCCESS)
+ {
+ unsigned long len = MAX_PATH;
+ RegQueryValueExW(hkey, L"Wallpaper", 0, NULL, (unsigned char *)&file, &len);
+ RegCloseKey(hkey);
+ }
+ if (file[0] && GetFileAttributesW(file) != (DWORD) - 1) ret = file;
+#endif
+ return ret;
+}
+extern StringW g_resourcepath;
+
+ARGB32 *imageLoader::makeBmp(const wchar_t *_filename, const wchar_t *path, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params, bool addMem, int *force_nocache)
+{
+ if (!_filename || !*_filename)
+ return 0;
+
+
+ ARGB32 *ret = NULL;
+
+ if (has_alpha != NULL)
+ *has_alpha = 0; //BU
+
+ // test image generator services FIRST
+ ImgGeneratorEnum ige(_filename);
+ svc_imageGenerator *gen;
+ while ((gen = ige.getNext()) != NULL)
+ {
+ ret = gen->genImage(_filename, has_alpha, w, h, params);
+ int cacheable = gen->outputCacheable();
+ ige.release(gen);
+ if (ret != NULL)
+ {
+ ApplySkinFilters::apply(params->getItemValue(L"id"), params->getItemValue(L"gammagroup"), ret, *w, *h);
+ if (addMem) addMemUsage(_filename, (*w) * (*h) * sizeof(int));
+ optimizeHasAlpha(ret, *w * *h, has_alpha);
+ // don't try to cache generated images
+ if (force_nocache) *force_nocache = !cacheable;
+ return ret;
+ }
+ }
+
+ StringW wallpaper;
+ if (!WCSICMP(_filename, L"$wallpaper"))
+ {
+ wallpaper = getWallpaper();
+ _filename = wallpaper.getValue();
+ }
+
+ MemBlock<uint8_t> mem;
+
+ wchar_t olddir[PATH_MAX] = {0};
+ Wasabi::Std::getCurDir(olddir, PATH_MAX);
+ Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath());
+
+ StringW file;
+
+ // benski> try language pack first
+ StringPathCombine skinLocalePath(LocalesManager::getLocaleRoot(), WASABI_API_SKIN->getSkinName());
+ file.swap(StringPathCombine(skinLocalePath, _filename));
+ OSFILETYPE in = WFOPEN(file, WF_READONLY_BINARY);
+
+ if (in == OPEN_FAILED)
+ {
+ // try the language pack's folder itself before falling back to the resource path
+ file.swap(StringPathCombine(LocalesManager::getLocaleRoot(), _filename));
+ in = WFOPEN(file, WF_READONLY_BINARY);
+ }
+
+ if (in == OPEN_FAILED)
+ {
+ if (path)
+ {
+ file.swap(StringPathCombine(path, _filename));
+ in = WFOPEN(file, WF_READONLY_BINARY);
+ }
+ else
+ in = WFOPEN(file=_filename, WF_READONLY_BINARY);
+ }
+
+#ifdef WASABI_COMPILE_SKIN
+ if (in == OPEN_FAILED)
+ {
+ file.swap(StringPathCombine(WASABI_API_SKIN->getSkinPath(), _filename));
+ in = WFOPEN(file, WF_READONLY_BINARY);
+ }
+
+#if 0 // this isn't used in gen_ff, basically makes it look in C:/Program Files/Winamp/Skins/Default/
+ if (in == OPEN_FAILED)
+ {
+ file.swap(StringPathCombine(Skin::getDefaultSkinPath(), _filename));
+ in = WFOPEN(file, WF_READONLY_BINARY);
+ }
+#endif
+
+ // look in the fallback stuff (in Winamp5, this is c:/program files/winamp/plugins/freeform/xml)
+ if (in == OPEN_FAILED)
+ {
+ file.swap(StringPathCombine(g_resourcepath, _filename));
+ in = WFOPEN(file, WF_READONLY_BINARY);
+ }
+#endif
+
+ if (in == OPEN_FAILED && path)
+ {
+ in = WFOPEN(file = _filename, WF_READONLY_BINARY);
+ }
+
+ Wasabi::Std::setCurDir(olddir);
+
+ if (in != OPEN_FAILED)
+ {
+ int filelen = (int)FGETSIZE(in);
+ if (filelen > 0)
+ {
+ mem.setSize(filelen);
+ int len = FREAD(mem, 1, mem.getSizeInBytes(), in);
+ if (len == filelen)
+ {
+ svc_imageLoader *loader = ImgLoaderEnum(mem, len).getNext();
+ if (loader != NULL)
+ {
+ ret = loader->loadImage(mem, mem.getSizeInBytes(), w, h, params);
+ if (ret != NULL)
+ {
+ if (addMem)
+ addMemUsage(file, (*w) * (*h) * sizeof(ARGB32));
+ optimizeHasAlpha(ret, *w * *h, has_alpha);
+ }
+ SvcEnum::release(loader);
+ }
+ }
+ } // filelen > 0
+ FCLOSE(in);
+ } // if file opened
+ if (ret != NULL)
+ {
+ return ret;
+ }
+ else if (in != OPEN_FAILED && mem)
+ {
+ int m = getFileType(mem);
+#ifdef WIN32
+ switch (m)
+ {
+ case FT_BMP:
+ {
+ wchar_t tmpname[WA_MAX_PATH] = L"";
+
+ // FG> if loading bmp from disk, no need to do the copy to disk
+ HBITMAP hbmp = (HBITMAP)LoadImageW(0, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+ if (!hbmp)
+ {
+ // CT> extract/copy the file into temp directory (so we don't have any trouble if the file
+ // is in a ZIP file). this whole copying thing will go away as soon as we'll get rid of
+ // the LoadImage win32 function and use our own bmp loading functions
+
+ GetTempPathW(WA_MAX_PATH, tmpname);
+ wcscat(tmpname, L"wa3tmp");
+ OSFILETYPE fs = WFOPEN(file, WF_READONLY_BINARY);
+ if (fs != OPEN_FAILED)
+ {
+ OSFILETYPE fd = WFOPEN(tmpname, L"wb");
+ int l;
+ do
+ {
+ char buf[1024] = {0};
+ l = FREAD(buf, 1, sizeof(buf), fs);
+ if (l > 0) FWRITE(buf, 1, l, fd);
+ }
+ while (l > 0);
+ FCLOSE(fs);
+ FCLOSE(fd);
+ hbmp = (HBITMAP)LoadImageW(0, tmpname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+ }
+ if (!hbmp)
+ {
+#ifdef WASABI_COMPILE_SKIN_WA2
+ // bitmap not found or broken (like in the netscape skin)
+ // try to find it in the Classic skin (wa2)
+ StringW wa2skinFn = WASABI_API_APP->getSkinsPath();
+ wa2skinFn.AppendPath("Classic");
+ wa2skinFn.AppendPath(_filename);
+ fs = WFOPEN(wa2skinFn), WF_READONLY_BINARY);
+ if (fs != OPEN_FAILED)
+ {
+ OSFILETYPE fd = WFOPEN(tmpname, L"wb");
+ int l;
+ do
+ {
+ char buf[1024] = {0};
+ l = FREAD(buf, 1, sizeof(buf), fs);
+ if (l > 0) FWRITE(buf, 1, l, fd);
+ }
+ while (l > 0);
+ FCLOSE(fs);
+ FCLOSE(fd);
+ hbmp = (HBITMAP)LoadImageW(0, tmpname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+ }
+#endif //WASABI_COMPILE_SKIN_WA2
+ }
+ if (!hbmp)
+ {
+ // no luck :(
+ _wunlink(tmpname);
+ return 0;
+ }
+ }
+
+ BITMAP bm;
+ HDC hMemDC, hMemDC2;
+ HBITMAP hprev, hprev2;
+ HBITMAP hsrcdib;
+ void *srcdib;
+ BITMAPINFO srcbmi = {0, };
+ int r = GetObject(hbmp, sizeof(BITMAP), &bm);
+ ASSERT(r != 0);
+ *w = bm.bmWidth;
+ *h = ABS(bm.bmHeight);
+
+ ARGB32 *newbits;
+ srcbmi.bmiHeader.biSize = sizeof(srcbmi.bmiHeader);
+ srcbmi.bmiHeader.biWidth = *w;
+ srcbmi.bmiHeader.biHeight = -*h;
+ srcbmi.bmiHeader.biPlanes = 1;
+ srcbmi.bmiHeader.biBitCount = 32;
+ srcbmi.bmiHeader.biCompression = BI_RGB;
+
+ hMemDC = CreateCompatibleDC(NULL);
+ hMemDC2 = CreateCompatibleDC(NULL);
+ hsrcdib = CreateDIBSection(hMemDC, &srcbmi, DIB_RGB_COLORS, &srcdib, NULL, 0);
+ ASSERTPR(hsrcdib != 0, "CreateDIBSection() failed #69");
+ hprev2 = (HBITMAP) SelectObject(hMemDC2, hbmp);
+ hprev = (HBITMAP) SelectObject(hMemDC, hsrcdib);
+ BitBlt(hMemDC, 0, 0, *w, *h, hMemDC2, 0, 0, SRCCOPY);
+ newbits = (ARGB32*)MALLOC((*w) * (*h) * sizeof(ARGB32));
+ MEMCPY32(newbits, srcdib, (*w)*(*h) /**sizeof(ARGB32)*/);
+ {
+ // put the alpha channel to 255
+ unsigned char *b = (unsigned char *)newbits;
+ int l = (*w) * (*h);
+ for (int i = 0;i < l;i++)
+ b[(i*4) + 3] = 0xff;
+ }
+ SelectObject(hMemDC, hprev);
+ SelectObject(hMemDC2, hprev2);
+ DeleteObject(hsrcdib);
+ DeleteDC(hMemDC2);
+ DeleteDC(hMemDC);
+
+ DeleteObject(hbmp);
+
+ if (tmpname[0])
+ _wunlink(tmpname); // destroy temp extraction
+
+ if (addMem)
+ addMemUsage(file, (*w)*(*h)*4);
+ return newbits;
+ }
+ }
+#endif
+ }
+ return ret;
+}
+
+int imageLoader::getFileType(unsigned char *pData)
+{
+ // Bmp ?
+#ifdef WIN32
+ WINBITMAPFILEHEADER * pBFH;
+ pBFH = (WINBITMAPFILEHEADER *) pData;
+#ifdef _WINDOWS
+ if (pBFH->bfType == 0x4d42)
+#else
+ if (pBFH->bfType == 0x424d)
+#endif
+ return FT_BMP;
+#endif
+ return FT_UNKNOWN;
+}
+
+#ifdef WASABI_COMPILE_SKIN
+
+ARGB32 *imageLoader::requestSkinBitmap(const wchar_t *id, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached)
+{
+ ifc_xmlreaderparams *params = NULL;
+ const wchar_t *rootpath = NULL;
+
+ const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id);
+
+ if (aliastarget)
+ id = aliastarget;
+
+ const wchar_t *efile = WASABI_API_PALETTE->getSkinBitmapFilename(id, x, y, subw, subh, &rootpath, &params);
+
+ if (x && *x == -1) *x = 0;
+ if (y && *y == -1) *y = 0;
+
+ if (!efile)
+ efile = id;
+
+ if (cached)
+ {
+ StringPathCombine f(rootpath, efile);
+ f.toupper();
+ f.FixSlashes();
+
+ int pos = -1;
+ /*skinCacheEntry *entry = */skinCacheList.findItem(f.getValue(), &pos);
+ if (pos != -1)
+ {
+ //find first one
+ while (pos > 0 && !wcscmp(skinCacheList[pos - 1]->fullpathfilename, f)) pos--;
+ do
+ {
+ skinCacheEntry *entry = skinCacheList[pos];
+ if (GammaMgr::gammaEqual(entry->original_element_id, id) && layerEqual(entry->original_element_id, id))
+ {
+ entry->usageCount++;
+ if (w) *w = entry->width;
+ if (h) *h = entry->height;
+ if (has_alpha) *has_alpha = entry->has_alpha;
+ return entry->bitmapbits;
+ }
+ pos++;
+ if (pos >= skinCacheList.getNumItems()) break;
+ }
+ while (!wcscmp(skinCacheList[pos]->fullpathfilename, f));
+ }
+ }
+
+ int force_nocache = 0;
+ int t_has_alpha = 0;
+ ARGB32 *bits = makeBmp(efile, rootpath, &t_has_alpha, w, h, params, TRUE, &force_nocache);
+ if (has_alpha != NULL) *has_alpha = t_has_alpha;
+
+ if (!bits)
+ return NULL;
+
+ if (force_nocache || !cached) return bits;
+
+ skinCacheEntry *cachedbmp = new skinCacheEntry;
+
+ if (params)
+ {
+ for (size_t i = 0;i != params->getNbItems();i++)
+ cachedbmp->params.addItem(params->getItemName(i), params->getItemValue(i));
+ }
+
+ cachedbmp->usageCount = 1;
+ cachedbmp->bitmapbits = bits;
+ cachedbmp->filename = efile;
+ cachedbmp->has_alpha = !!t_has_alpha;
+ cachedbmp->width = *w;
+ cachedbmp->height = *h;
+ cachedbmp->original_element_id = id;
+
+ //needed for findItem above
+ StringPathCombine b(rootpath, efile);
+ b.toupper();
+ b.FixSlashes();
+ cachedbmp->fullpathfilename.swap(b);
+
+ applySkinFilters(cachedbmp);
+ skinCacheList.addItem(cachedbmp);
+
+ return cachedbmp->bitmapbits;
+}
+/*
+int imageLoader::paramsMatch(ifc_xmlreaderparams *a, ifc_xmlreaderparams *b)
+{
+ if (!a && !b) return 1;
+ if ((!a && b) || (!b && a)) return 0;
+ for (int i = 0;i < a->getNbItems();i++)
+ {
+ const wchar_t *name = a->getItemName(i);
+ if (!_wcsicmp(name, L"w") || !_wcsicmp(name, L"h") || !_wcsicmp(name, L"x") || !_wcsicmp(name, L"y")) continue;
+ if (_wcsicmp(a->getItemValue(i), b->getItemValue(name)))
+ return 0;
+ }
+ return 1;
+}
+*/
+int imageLoader::layerEqual(const wchar_t *id1, const wchar_t *id2)
+{
+ int a = WASABI_API_PALETTE->getLayerFromId(id1);
+ int b = WASABI_API_PALETTE->getLayerFromId(id2);
+ return (a == b);
+}
+
+void imageLoader::releaseSkinBitmap(ARGB32 *bitmapbits)
+{ //FG
+ int i;
+ // TODO: add critical sections
+
+ int ni = skinCacheList.getNumItems();
+ for (i = 0;i < ni;i++)
+ {
+ skinCacheEntry *entry = skinCacheList.enumItem(i);
+ if (entry->bitmapbits == bitmapbits)
+ {
+ entry->usageCount--;
+ if (entry->usageCount == 0)
+ {
+ subMemUsage(entry->width*entry->height*sizeof(int));
+ WASABI_API_MEMMGR->sysFree(entry->bitmapbits);
+ skinCacheList.removeByPos(i);
+ delete entry;
+ if (skinCacheList.getNumItems() == 0) skinCacheList.removeAll();
+ }
+ return ;
+ }
+ }
+ // bitmap was not a cached skin bitmap, simply free it
+ release(bitmapbits);
+}
+
+#endif //WASABI_COMPILE_SKIN
+
+void imageLoader::release(ARGB32 *bitmapbits)
+{
+ WASABI_API_MEMMGR->sysFree(bitmapbits);
+}
+
+void imageLoader::optimizeHasAlpha(ARGB32 *bits, int len, int *has_alpha)
+{
+ if (len <= 0 || has_alpha == NULL) return ;
+ for (*has_alpha = 0; len; len--, bits++)
+ {
+ ARGB32 v = *bits;
+ unsigned int alpha = v >> 24;
+ if (alpha != 255)
+ {
+ *has_alpha = 1;
+ break;
+ }
+ }
+}
+
+#ifdef WASABI_COMPILE_SKIN
+
+void imageLoader::applySkinFilters()
+{ //FG
+ int i;
+
+ Skin::unloadResources();
+ for (i = 0; i < skinCacheList.getNumItems(); i++)
+ {
+ skinCacheEntry *entry = skinCacheList.q(i);
+ applySkinFilters(entry);
+ }
+
+ WASABI_API_PALETTE->newSkinPart();
+ Skin::reloadResources();
+}
+
+void imageLoader::applySkinFilters(skinCacheEntry *entry)
+{
+ ASSERT(entry != NULL);
+
+ int w = entry->width, h = entry->height;
+
+ ApplySkinFilters::apply(entry->original_element_id, NULL, (ARGB32*)entry->bitmapbits, w, h);
+}
+
+ARGB32 imageLoader::filterSkinColor(ARGB32 color, const wchar_t *element_id, const wchar_t *groupname)
+{
+ SkinFilterEnum sfe;
+
+ svc_skinFilter *obj;
+ while (1)
+ {
+ obj = sfe.getNext(FALSE);
+ if (!obj) break;
+ color = obj->filterColor(color, element_id, groupname);
+ sfe.getLastFactory()->releaseInterface(obj);
+ }
+
+ return color;
+}
+
+#endif //WASABI_COMPILE_SKIN
+
+void imageLoader::addMemUsage(const wchar_t *filename, int size)
+{
+ totalMemUsage += size;
+#ifdef DEBUG_OUTPUT
+ DebugStringW("Bitmaps memory usage : %s - %d\n", filename, totalMemUsage);
+#endif
+}
+
+void imageLoader::subMemUsage(int size)
+{
+ totalMemUsage -= size;
+}
+
+#ifdef WASABI_COMPILE_SKIN
+
+//PtrList<skinCacheEntry> imageLoader::skinCacheList;
+PtrListInsertMultiSorted<skinCacheEntry, skinCacheComp> imageLoader::skinCacheList;
+#endif //WASABI_COMPILE_SKIN
+
+int imageLoader::totalMemUsage = 0; \ No newline at end of file
diff --git a/Src/Wasabi/api/imgldr/imgldr.h b/Src/Wasabi/api/imgldr/imgldr.h
new file mode 100644
index 00000000..33a64864
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imgldr.h
@@ -0,0 +1,86 @@
+#ifndef __IMGLDR_H
+#define __IMGLDR_H
+
+//CUT
+#define FT_UNKNOWN 0
+#define FT_BMP 1
+#define FT_JPEG 5
+#define FT_PNG 6
+
+#include <bfc/ptrlist.h>
+#include <tataki/bitmap/bitmap.h>
+#ifdef WASABI_COMPILE_XMLPARSER
+#include <api/xml/xmlreader.h>
+#include <api/xml/xmlparamsi.h>
+#else
+class XmlReaderParamsI;
+#endif
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/skin.h>
+#include <api/skin/skinfilter.h>
+#endif
+
+#include <bfc/string/StringW.h>
+
+typedef struct {
+ ARGB32 *bitmapbits;
+ StringW filename;
+ int usageCount;
+ bool has_alpha;
+ int width;
+ int height;
+ StringW includepath;
+// String rootpath;
+ XmlReaderParamsI params;
+ StringW original_element_id;
+ StringW fullpathfilename;
+} skinCacheEntry;
+
+typedef unsigned long ARGB32;
+
+#ifdef WASABI_COMPILE_SKIN
+
+class skinCacheComp
+{
+public:
+ static int compareItem(void *p1, void *p2) {
+ return wcscmp(((skinCacheEntry *)p1)->fullpathfilename, ((skinCacheEntry *)p2)->fullpathfilename);
+ }
+ static int compareAttrib(const wchar_t *attrib, void *item) {
+ return wcscmp(attrib, ((skinCacheEntry *)item)->fullpathfilename);
+ }
+};
+
+#endif //WASABI_COMPILE_SKIN
+
+class imageLoader
+{
+public:
+ static ARGB32 *makeBmp(const wchar_t *filename, const wchar_t *path, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params, bool addmem, int *force_nocache);
+#ifdef _WIN32
+ static ARGB32 *makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *forcegroup=NULL);
+#endif
+ static int getFileType(uint8_t *pData);
+ static StringW getWallpaper();
+ static void release(ARGB32 *bitmapbits);
+#ifdef WASABI_COMPILE_SKIN
+ static ARGB32 *requestSkinBitmap(const wchar_t *id, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached=1);
+ static void releaseSkinBitmap(ARGB32 *bmpbits);
+ static void applySkinFilters();
+ static void applySkinFilters(skinCacheEntry *entry);
+ static ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname);
+ static int layerEqual(const wchar_t *id1, const wchar_t *id2);
+#endif //WASABI_COMPILE_SKIN
+ static int getMemUsage() { return totalMemUsage; }
+ static int getNumCached() { return skinCacheList.getNumItems(); }
+private:
+#ifdef WASABI_COMPILE_SKIN
+ //static int paramsMatch(ifc_xmlreaderparams *a, ifc_xmlreaderparams *b);
+ static PtrListInsertMultiSorted<skinCacheEntry,skinCacheComp> skinCacheList;
+#endif //WASABI_COMPILE_SKIN
+ static void optimizeHasAlpha(ARGB32 *bits, int len, int *has_alpha);
+ static void addMemUsage(const wchar_t *filename, int size);
+ static void subMemUsage(int size);
+ static int totalMemUsage;
+};
+#endif
diff --git a/Src/Wasabi/api/imgldr/imgldrapi.cpp b/Src/Wasabi/api/imgldr/imgldrapi.cpp
new file mode 100644
index 00000000..45790615
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imgldrapi.cpp
@@ -0,0 +1,81 @@
+#include "precomp.h"
+#include <api.h>
+#include "imgldrapi.h"
+#include <api/imgldr/imgldr.h>
+
+#include <api/skin/skinelem.h>
+imgldr_api *imgLoaderApi = NULL;
+
+ARGB32 *ImgLdrApi::imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h)
+{
+ if (filename == NULL)
+ {
+ DebugString("illegal param : filename == NULL");
+ return NULL;
+ }
+ return imageLoader::makeBmp(filename, NULL, has_alpha, w, h, NULL, TRUE, NULL);
+}
+
+#ifdef _WIN32
+ARGB32 *ImgLdrApi::imgldr_makeBmp2(HINSTANCE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup)
+{
+ return imageLoader::makeBmp(hInst, id, has_alpha,w,h, colorgroup);
+}
+#endif
+
+void ImgLdrApi::imgldr_releaseBmp(ARGB32 *bmpbits)
+{
+ if (bmpbits == NULL) {
+ DebugString("illegal param : bmpbits == NULL");
+ return;
+ }
+ imageLoader::release(bmpbits);
+}
+
+#ifdef WASABI_COMPILE_SKIN
+
+ARGB32 *ImgLdrApi::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached)
+{
+ if (file == NULL)
+ {
+ DebugString("illegal param : file == NULL");
+ return NULL;
+ }
+ return imageLoader::requestSkinBitmap(file, has_alpha, x, y, subw, subh, w, h, cached);
+}
+
+void ImgLdrApi::imgldr_releaseSkinBitmap(ARGB32 *bmpbits)
+{
+ if (bmpbits == NULL)
+ {
+ DebugString("illegal param : bmpbits == NULL");
+ return;
+ }
+ imageLoader::releaseSkinBitmap(bmpbits);
+}
+
+RegionServer *ImgLdrApi::imgldr_requestSkinRegion(const wchar_t *id)
+{
+ if (id == NULL)
+ {
+ DebugString("illegal param : id == NULL");
+ return NULL;
+ }
+ return WASABI_API_PALETTE->requestSkinRegion(id);
+}
+
+void ImgLdrApi::imgldr_cacheSkinRegion(const wchar_t *id, api_region *r)
+{
+ if (id == NULL)
+ {
+ DebugString("illegal param : id == NULL");
+ }
+ if (r == NULL)
+ {
+ DebugString("illegal param : region == NULL");
+ }
+ WASABI_API_PALETTE->cacheSkinRegion(id, r);
+}
+
+#endif
+
diff --git a/Src/Wasabi/api/imgldr/imgldrapi.h b/Src/Wasabi/api/imgldr/imgldrapi.h
new file mode 100644
index 00000000..b94fdfa5
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/imgldrapi.h
@@ -0,0 +1,23 @@
+#ifndef __IMGLDRAPI_H
+#define __IMGLDRAPI_H
+
+#include <api/imgldr/api_imgldr.h>
+
+class ImgLdrApi : public imgldr_apiI
+{
+ public:
+ ARGB32 *imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h);
+#ifdef _WIN32
+ ARGB32 *imgldr_makeBmp2(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup = NULL);
+#endif
+ void imgldr_releaseBmp(ARGB32 *bmpbits);
+#ifdef WASABI_COMPILE_SKIN
+ ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached);
+ RegionServer *imgldr_requestSkinRegion(const wchar_t *id);
+ void imgldr_cacheSkinRegion(const wchar_t *id, api_region *r);
+ void imgldr_releaseSkinBitmap(ARGB32 *bmpbits);
+#endif //WASABI_COMPILE_SKIN
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/imgldr/skinbmps.h b/Src/Wasabi/api/imgldr/skinbmps.h
new file mode 100644
index 00000000..dab8568c
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/skinbmps.h
@@ -0,0 +1,122 @@
+#ifndef _SKINBMPS_H
+#define _SKINBMPS_H
+/*
+typedef enum {
+ SKIN_BITMAP_UNKNOWN,
+
+ // Base texture
+ SKIN_BITMAP_BASE_TEXTURE,
+
+ // Framewnd
+ SKIN_BITMAP_FRAME_VERTICAL_DIVIDER,
+ SKIN_BITMAP_FRAME_HORIZONTAL_DIVIDER,
+
+ // Listwnd/Treewnd
+ SKIN_BITMAP_LIST_BACKGROUND,
+ SKIN_BITMAP_TREE_BACKGROUND,
+
+ // Appctrl
+ SKIN_BITMAP_APPCTRL_LEFTARROW_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_LEFTARROW_PRESSED,
+ SKIN_BITMAP_APPCTRL_RIGHTARROW_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_RIGHTARROW_PRESSED,
+ SKIN_BITMAP_APPCTRL_WINDOWSIZER,
+ SKIN_BITMAP_APPCTRL_PLAYERMODE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_PLAYERMODE_PRESSED,
+ SKIN_BITMAP_APPCTRL_MINIMIZE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_MINIMIZE_PRESSED,
+ SKIN_BITMAP_APPCTRL_MAXIMIZE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_MAXIMIZE_PRESSED,
+ SKIN_BITMAP_APPCTRL_CLOSE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_CLOSE_PRESSED,
+ SKIN_BITMAP_APPCTRL_SYSTEMICON,
+ SKIN_BITMAP_APPCTRL_PLACEHOLDER_LEFT,
+ SKIN_BITMAP_APPCTRL_PLACEHOLDER_MIDDLE,
+ SKIN_BITMAP_APPCTRL_PLACEHOLDER_RIGHT,
+ SKIN_BITMAP_APPCTRL_TITLEBAR,
+
+ // Controls
+ SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_STOP_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_STOP_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_PRESSED,
+
+ // Paintset
+ SKIN_BITMAP_LABEL_UPPERLEFT,
+ SKIN_BITMAP_LABEL_TOP,
+ SKIN_BITMAP_LABEL_UPPERRIGHT,
+ SKIN_BITMAP_LABEL_LEFT,
+ SKIN_BITMAP_LABEL_MIDDLE,
+ SKIN_BITMAP_LABEL_RIGHT,
+ SKIN_BITMAP_LABEL_LOWERLEF,
+ SKIN_BITMAP_LABEL_BOTTOM,
+ SKIN_BITMAP_LABEL_LOWERRIGHT,
+ SKIN_BITMAP_APPBORDER_UPPERLEFT,
+ SKIN_BITMAP_APPBORDER_TOP,
+ SKIN_BITMAP_APPBORDER_UPPERRIGHT,
+ SKIN_BITMAP_APPBORDER_LEFT,
+ SKIN_BITMAP_APPBORDER_RIGHT,
+ SKIN_BITMAP_APPBORDER_LOWERLEFT,
+ SKIN_BITMAP_APPBORDER_BOTTOM,
+ SKIN_BITMAP_APPBORDER_LOWERRIGHT,
+
+ // Seeker
+ SKIN_BITMAP_SEEKBAR_LEFT,
+ SKIN_BITMAP_SEEKBAR_MIDDLE,
+ SKIN_BITMAP_SEEKBAR_RIGHT,
+ SKIN_BITMAP_SEEKBAR_BUTTON_NONPRESSED,
+ SKIN_BITMAP_BUTTON_PRESSED,
+
+ // Status
+ SKIN_BITMAP_STATUSBAR_LEFT,
+ SKIN_BITMAP_STATUSBAR_MIDDLE,
+ SKIN_BITMAP_STATUSBAR_RIGHT,
+
+ // Volbar
+ SKIN_BITMAP_VOLBAR_LEFT,
+ SKIN_BITMAP_VOLBAR_MIDDLE,
+ SKIN_BITMAP_VOLBAR_RIGHT,
+ SKIN_BITMAP_VOLBAR_BUTTON_NONPRESSED,
+ SKIN_BITMAP_VOLBAR_BUTTON_PRESSED,
+
+ // Titlewnd
+ SKIN_BITMAP_COMPONENT_PROP_TOP,
+ SKIN_BITMAP_COMPONENT_PROP,
+ SKIN_BITMAP_COMPONENT_PROP_MIDDLE,
+ SKIN_BITMAP_COMPONENT_PROP_BOTTOM,
+
+ // Videownd
+ SKIN_BITMAP_MOVIE_BACKGROUND,
+
+ // Seditwnd
+ SKIN_BITMAP_AVS_SCRIPT_MARKER,
+ SKIN_BITMAP_AVS_SCRIPT_PLAY_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_PLAY_PRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_PAUSE_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_PAUSE_PRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_STOP_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_STOP_PRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_TIMEARROW,
+ SKIN_BITMAP_AVS_SCRIPT_BACKGROUND,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_TOP,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_MIDDLE,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BOTTOM,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_PRESSED,
+
+// ComponentAPI1 ends here
+ NUM_SKIN_BITMAP_ELEMENT_IDS
+} SkinBitmapElementId;
+
+typedef struct {
+ SkinBitmapElementId id;
+ char *fn;
+ } SkinBitmapTableElement;
+*/
+#endif
diff --git a/Src/Wasabi/api/imgldr/winbmp.h b/Src/Wasabi/api/imgldr/winbmp.h
new file mode 100644
index 00000000..afcc0784
--- /dev/null
+++ b/Src/Wasabi/api/imgldr/winbmp.h
@@ -0,0 +1,47 @@
+#ifndef __WINBMP_H
+#define __WINBMP_H
+
+typedef struct tagWINRGBQUAD
+{
+ BYTE rgbBlue;
+ BYTE rgbGreen;
+ BYTE rgbRed;
+ BYTE rgbReserved;
+} WINRGBQUAD;
+
+typedef struct tagWINBITMAPFILEHEADER
+{
+ WORD bfType;
+ LONG bfSize;
+ WORD bfReserved1;
+ WORD bfReserved2;
+ LONG bfOffBits;
+} WINBITMAPFILEHEADER;
+
+typedef struct tagWINBITMAPINFOHEADER
+{
+ LONG biSize;
+ LONG biWidth;
+ LONG biHeight;
+ WORD biPlanes;
+ WORD biBitCount;
+ LONG biCompression;
+ LONG biSizeImage;
+ LONG biXPelsPerMeter;
+ LONG biYPelsPerMeter;
+ LONG biClrUsed;
+ LONG biClrImportant;
+} WINBITMAPINFOHEADER;
+
+typedef struct tagWINBITMAPINFO
+{
+ WINBITMAPINFOHEADER bmiHeader;
+ WINRGBQUAD bmiColors[1];
+} WINBITMAPINFO;
+
+#define BI_RGB 0L
+#define BI_RLE8 1L
+#define BI_RLE4 2L
+#define BI_BITFIELDS 3L
+
+#endif
diff --git a/Src/Wasabi/api/locales/LocalesInfo.cpp b/Src/Wasabi/api/locales/LocalesInfo.cpp
new file mode 100644
index 00000000..667fb25b
--- /dev/null
+++ b/Src/Wasabi/api/locales/LocalesInfo.cpp
@@ -0,0 +1,41 @@
+#include <precomp.h>
+#include "LocalesInfo.h"
+#include "../xml/obj_xml.h"
+#include <api/xml/XMLAutoInclude.h>
+#include <api/xml/LoadXML.h>
+#include <api/service/waservicefactory.h>
+
+LocalesInfosXmlReader::LocalesInfosXmlReader(const wchar_t *localename) : LocaleItem(localename)
+{
+ parser = 0;
+
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ {
+ XMLAutoInclude include(parser, L"Locales");
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition", this);
+ parser->xmlreader_open();
+
+ StringPathCombine fn(L"Locales", localename);
+ LoadXmlFile(parser, fn);
+ parser->xmlreader_unregisterCallback(this);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+
+ }
+}
+
+
+void LocalesInfosXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ language = params->getItemValue(L"language");
+ author = params->getItemValue(L"author");
+}
diff --git a/Src/Wasabi/api/locales/LocalesInfo.h b/Src/Wasabi/api/locales/LocalesInfo.h
new file mode 100644
index 00000000..5179d94a
--- /dev/null
+++ b/Src/Wasabi/api/locales/LocalesInfo.h
@@ -0,0 +1,30 @@
+#ifndef NULLSOFT_WASABI_LOCALESINFO_H
+#define NULLSOFT_WASABI_LOCALESINFO_H
+
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include <bfc/string/StringW.h>
+class obj_xml;
+class LocaleItem
+{
+public:
+ LocaleItem(const wchar_t *name) : name(name), language(name) { };
+ const wchar_t *getName() { return name; }
+
+ const wchar_t *getLanguage() { return language; }
+ const wchar_t *getAuthor() { return author; }
+protected:
+ StringW name;
+ StringW language;
+ StringW author;
+};
+
+
+class LocalesInfosXmlReader : public LocaleItem, public ifc_xmlreadercallbackI // XmlReaderCallbackI
+{
+public:
+ LocalesInfosXmlReader(const wchar_t *skinname);
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+private:
+ obj_xml *parser;
+};
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_locales.cpp b/Src/Wasabi/api/locales/api_locales.cpp
new file mode 100644
index 00000000..26cf75ab
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_locales.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_locales.cpp
+// Class : api_locales
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_locales.h"
+
+
diff --git a/Src/Wasabi/api/locales/api_locales.h b/Src/Wasabi/api/locales/api_locales.h
new file mode 100644
index 00000000..0ae75c73
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_locales.h
@@ -0,0 +1,80 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_locales.h
+// Class : api_locales
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_LOCALES_H
+#define __API_LOCALES_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE api_locales: public Dispatchable {
+ protected:
+ api_locales() {}
+ ~api_locales() {}
+ public:
+ const wchar_t *locales_getTranslation(const wchar_t *str);
+ void locales_addTranslation(const wchar_t *from, const wchar_t *to);
+ const wchar_t *locales_getBindFromAction(int action);
+ int locales_getNumEntries();
+ const wchar_t *locales_enumEntry(int n);
+ void locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global = 0);
+
+ protected:
+ enum {
+ API_LOCALES_LOCALES_GETTRANSLATION = 10,
+ API_LOCALES_LOCALES_ADDTRANSLATION = 20,
+ API_LOCALES_LOCALES_GETBINDFROMACTION = 30,
+ API_LOCALES_LOCALES_GETNUMENTRIES = 40,
+ API_LOCALES_LOCALES_ENUMENTRY = 50,
+ API_LOCALES_LOCALES_REGISTERACCELERATORSECTION = 60,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline const wchar_t *api_locales::locales_getTranslation(const wchar_t *str) {
+ const wchar_t *__retval = _call(API_LOCALES_LOCALES_GETTRANSLATION, (const wchar_t *)0, str);
+ return __retval;
+}
+
+inline void api_locales::locales_addTranslation(const wchar_t *from, const wchar_t *to)
+{
+ _voidcall(API_LOCALES_LOCALES_ADDTRANSLATION, from, to);
+}
+
+inline const wchar_t *api_locales::locales_getBindFromAction(int action) {
+ const wchar_t *__retval = _call(API_LOCALES_LOCALES_GETBINDFROMACTION, (const wchar_t *)0, action);
+ return __retval;
+}
+
+inline int api_locales::locales_getNumEntries() {
+ int __retval = _call(API_LOCALES_LOCALES_GETNUMENTRIES, (int)0);
+ return __retval;
+}
+
+inline const wchar_t *api_locales::locales_enumEntry(int n)
+{
+ const wchar_t *__retval = _call(API_LOCALES_LOCALES_ENUMENTRY, (const wchar_t *)0, n);
+ return __retval;
+}
+
+inline void api_locales::locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global) {
+ _voidcall(API_LOCALES_LOCALES_REGISTERACCELERATORSECTION, name, wnd, global);
+}
+
+// ----------------------------------------------------------------------------
+
+// {C1251318-A6F5-4cd2-9142-A4CEAA08B846}
+static const GUID localesApiServiceGuid =
+{ 0xc1251318, 0xa6f5, 0x4cd2, { 0x91, 0x42, 0xa4, 0xce, 0xaa, 0x8, 0xb8, 0x46 } };
+
+extern api_locales *localesApi;
+
+#endif // __API_LOCALES_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesi.cpp b/Src/Wasabi/api/locales/api_localesi.cpp
new file mode 100644
index 00000000..67c99164
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesi.cpp
@@ -0,0 +1,47 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "api_localesi.h"
+//?>
+
+#include <api/locales/localesmgr.h>
+#include <api/wnd/keyboard.h>
+
+api_locales *localesApi = NULL;
+
+api_localesI::api_localesI() {
+ LocalesManager::init();
+}
+
+api_localesI::~api_localesI() {
+ LocalesManager::deinit();
+}
+
+const wchar_t *api_localesI::locales_getTranslation(const wchar_t *str)
+{
+ return LocalesManager::getTranslation(str);
+}
+
+void api_localesI::locales_addTranslation(const wchar_t *from, const wchar_t *to) {
+ LocalesManager::addTranslation(from, to);
+}
+
+const wchar_t *api_localesI::locales_getBindFromAction(int action)
+{
+ return LocalesManager::getBindFromAction(action);
+}
+
+/* // TODO: benski> maybe hook up to Winamp 5.5's new lang pack stuff
+int api_localesI::locales_getNumEntries()
+{
+ return LocalesManager::getNumLocales();
+}
+
+const wchar_t *api_localesI::locales_enumEntry(int n)
+{
+ return LocalesManager::enumLoadableLocales(n);
+}*/
+
+void api_localesI::locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global)
+{
+ Keyboard::registerAcceleratorSection(name, wnd, global);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesi.h b/Src/Wasabi/api/locales/api_localesi.h
new file mode 100644
index 00000000..eea3ac62
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesi.h
@@ -0,0 +1,23 @@
+#ifndef __API_LOCALESI_IMPL_H
+#define __API_LOCALESI_IMPL_H
+
+/*<?<autoheader/>*/
+#include "api_locales.h"
+#include "api_localesx.h"
+/*?>*/
+
+class api_localesI : public api_localesX
+{
+public:
+ api_localesI();
+ virtual ~api_localesI();
+
+ DISPATCH(10) const wchar_t *locales_getTranslation(const wchar_t *str); // if not found, returns the str paramer
+ DISPATCH(20) void locales_addTranslation(const wchar_t *from, const wchar_t *to);
+ DISPATCH(30) const wchar_t *locales_getBindFromAction(int action);
+ //DISPATCH(40) int locales_getNumEntries();
+ //DISPATCH(50) const wchar_t *locales_enumEntry(int n);
+ DISPATCH(60) void locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global = 0);
+};
+
+#endif // __API_LOCALESI_IMPL_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesx.cpp b/Src/Wasabi/api/locales/api_localesx.cpp
new file mode 100644
index 00000000..ff4d4d31
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesx.cpp
@@ -0,0 +1,26 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_localesx.cpp
+// Class : api_locales
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "api_localesx.h"
+#include "api_localesi.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_localesX
+START_DISPATCH;
+ CB(API_LOCALES_LOCALES_GETTRANSLATION, locales_getTranslation);
+ VCB(API_LOCALES_LOCALES_ADDTRANSLATION, locales_addTranslation);
+ CB(API_LOCALES_LOCALES_GETBINDFROMACTION, locales_getBindFromAction);
+ //CB(API_LOCALES_LOCALES_GETNUMENTRIES, locales_getNumEntries);
+ //CB(API_LOCALES_LOCALES_ENUMENTRY, locales_enumEntry);
+ VCB(API_LOCALES_LOCALES_REGISTERACCELERATORSECTION, locales_registerAcceleratorSection);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/api_localesx.h b/Src/Wasabi/api/locales/api_localesx.h
new file mode 100644
index 00000000..b8efae8e
--- /dev/null
+++ b/Src/Wasabi/api/locales/api_localesx.h
@@ -0,0 +1,31 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 17 16:03:31 2003]
+//
+// File : api_localesx.h
+// Class : api_locales
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_LOCALESX_H
+#define __API_LOCALESX_H
+
+#include "api_locales.h"
+
+// ----------------------------------------------------------------------------
+
+class api_localesX : public api_locales {
+ protected:
+ api_localesX() {}
+ public:
+ virtual const wchar_t *locales_getTranslation(const wchar_t *str)=0;
+ virtual void locales_addTranslation(const wchar_t *from, const wchar_t *to)=0;
+ virtual const wchar_t *locales_getBindFromAction(int action)=0;
+ //virtual int locales_getNumEntries()=0;
+ //virtual const wchar_t *locales_enumEntry(int n)=0;
+ virtual void locales_registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global = 0)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_LOCALESX_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/localesmgr.cpp b/Src/Wasabi/api/locales/localesmgr.cpp
new file mode 100644
index 00000000..610a0432
--- /dev/null
+++ b/Src/Wasabi/api/locales/localesmgr.cpp
@@ -0,0 +1,462 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "localesmgr.h"
+#include <bfc/parse/pathparse.h>
+#include <api/config/items/cfgitem.h>
+#include <bfc/file/readdir.h>
+#include <api/xml/XMLAutoInclude.h>
+#include "../nu/regexp.h"
+#include "../Agave/language/api_language.h"
+#include <bfc/ptrlist.h>
+
+struct StringEntry
+{
+ uint32_t id;
+ wchar_t *string;
+};
+
+typedef PtrList<StringEntry> StringTable;
+struct StringTableData
+{
+ wchar_t *id;
+ StringTable entries;
+};
+
+typedef PtrList<StringTableData> StringTables;
+
+StringTables stringTables;
+
+void LocalesAcceleratorSectionXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *section = params->getItemValue(L"section");
+ if (!section)
+ LocalesManager::setAcceleratorSection(L"general");
+ else
+ LocalesManager::setAcceleratorSection(section);
+}
+
+void LocalesAcceleratorSectionXmlCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ LocalesManager::setAcceleratorSection(L"");
+}
+
+void StringTableXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *section = params->getItemValue(L"id");
+ if (!section)
+ LocalesManager::SetStringTable(L"nullsoft.wasabi");
+ else
+ LocalesManager::SetStringTable(section);
+}
+
+void StringTableXmlCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ LocalesManager::SetStringTable(L"");
+}
+
+void StringTableEntryXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *b = params->getItemValue(L"id");
+ const wchar_t *a = params->getItemValue(L"string");
+ if (b && a)
+ LocalesManager::AddString(WTOI(b), a);
+}
+
+/* ------------------------------------------------------------ */
+void LocalesAcceleratorXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *b = params->getItemValue(L"bind");
+ const wchar_t *a = params->getItemValue(L"action");
+ if (b && a)
+ LocalesManager::addAccelerator(b, a);
+}
+
+/* ------------------------------------------------------------ */
+void LocalesTranslationXmlCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *f = params->getItemValue(L"from");
+ const wchar_t *t = params->getItemValue(L"to");
+ if (f && t)
+ LocalesManager::addTranslation(f, t);
+}
+
+int LocalesSkinCallback::skincb_onUnloading()
+{
+ LocalesManager::ResetStrings();
+ LocalesManager::resetAll();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onReset()
+{
+ //
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onReload()
+{
+ //LocalesManager::load();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onBeforeLoadingElements()
+{
+ LocalesManager::load();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onGuiLoaded()
+{
+ LocalesManager::LoadStringTables();
+ return 0;
+}
+
+int LocalesSkinCallback::skincb_onLoaded()
+{
+ // TODO: load string table?
+ return 0;
+}
+
+/* ------------------------------------------------------------ */
+void LocalesManager::init()
+{
+ WASABI_API_SYSCB->syscb_registerCallback(&localesSkinCallback);
+ //load();
+}
+
+void LocalesManager::load()
+{
+#ifdef LOCALES_CUSTOM_LOAD
+
+ LOCALES_CUSTOM_LOAD(localePath);
+ // TODO: benski> don't load this here. we should set up a syscallback for skin load (maybe skincb_onBeforeLoadingElements?)
+ // and also we should call deinit() on skin unload (skincb_onReload, skincb_onReset, skincb_onUnloading?)
+ StringPathCombine filetoload(localePath, L"Wasabi.xml");
+ /*
+ PathParserW pp(localeName);
+ localeName = pp.getLastString();
+ int p = localeName.lFindChar('.');
+ if (p > 0) localeName.trunc(p);
+ */
+#else
+ wchar_t tmpbuf[WA_MAX_PATH] = L"english";
+
+ WASABI_API_CONFIG->getStringPrivate(L"LocaleFile", tmpbuf, WA_MAX_PATH, L"english");
+
+ // FG> ok I have no idea why it doesn't work when i read from cfg instead of stringprivate and frankly i don't have time for this
+ // so for now it'll work with both a cfgitem and a stringprivate, i couldn't desync them so it should be ok in the meantime.
+ /* const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ if (item != NULL)
+ item->getData("Language", tmpbuf, WA_MAX_PATH-1);*/
+
+ localeName = tmpbuf;
+ englishLocale = !WCSICMP(localeName, L"english");
+ loadFile(L"english");
+ StringW filetoload = localeName;
+ if (englishLocale)
+ filetoload.trunc(0);
+#endif
+
+ if (!filetoload.isempty())
+ loadFile(filetoload);
+
+#ifdef WASABI_API_WNDMGR
+ if (WASABI_API_WNDMGR)
+ WASABI_API_WNDMGR->wndTrackInvalidateAll();
+#endif
+}
+
+void LocalesManager::deinit()
+{
+ resetAll();
+ WASABI_API_SYSCB->syscb_deregisterCallback(&localesSkinCallback);
+}
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+void LocalesManager::LoadStringTables()
+{
+ StringPathCombine genericStringTable(localePath, L"stringtable.xml");
+ LoadStringTable(genericStringTable);
+
+ StringPathCombine skinStringTable(localePath, WASABI_API_SKIN->getSkinName());
+ skinStringTable.AppendPath(L"stringtable.xml");
+ LoadStringTable(skinStringTable);
+}
+
+void LocalesManager::LoadStringTable(const wchar_t *name)
+{
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ {
+ const wchar_t *file = Wasabi::Std::filename(name);
+ int fnlen = wcslen(file);
+ StringW path = name;
+ path.trunc( -fnlen);
+ XMLAutoInclude include(parser, path);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\fStringTable", &stringTableXmlCallback);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\fStringTable\fStringEntry", &stringTableXmlEntryCallback);
+ parser->xmlreader_open();
+#ifdef LOCALES_CUSTOM_LOAD
+ LoadXmlFile(parser, name);
+#else
+ LoadXmlFile(parser, StringPrintfW(L"Locales/%s.xml", name));
+#endif
+ parser->xmlreader_unregisterCallback(&stringTableXmlCallback);
+ parser->xmlreader_unregisterCallback(&stringTableXmlEntryCallback);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+void LocalesManager::loadFile(const wchar_t *name)
+{
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ {
+ const wchar_t *file = Wasabi::Std::filename(name);
+ int fnlen = wcslen(file);
+ StringW path = name;
+ path.trunc( -fnlen);
+ XMLAutoInclude include(parser, path);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\faccelerators", &accelSectionXmlCallback);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\faccelerators\faccelerator", &accelXmlCallback);
+ parser->xmlreader_registerCallback(L"WinampLocaleDefinition\ftranslations\ftranslation", &transXmlCallback);
+ parser->xmlreader_open();
+#ifdef LOCALES_CUSTOM_LOAD
+ LoadXmlFile(parser, name);
+#else
+ LoadXmlFile(parser, StringPrintfW(L"Locales/%s.xml", name));
+#endif
+ parser->xmlreader_unregisterCallback(&accelSectionXmlCallback);
+ parser->xmlreader_unregisterCallback(&accelXmlCallback);
+ parser->xmlreader_unregisterCallback(&transXmlCallback);
+ }
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+void LocalesManager::addTranslation(const wchar_t *from, const wchar_t *to)
+{
+ LocTrans *t = translationsList.findItem(from);
+ if (t)
+ translationsList.removeItem(t);
+ translationsList.addItem(new LocTrans(from, to));
+}
+
+
+const wchar_t *LocalesManager::lookupString(const wchar_t *from)
+{
+ if (from == NULL)
+ return NULL;
+
+ if (*from == L'@')
+ {
+
+ const wchar_t *findPound = wcschr(from, L'#');
+ if (findPound && (findPound-from) < 128)
+ {
+ wchar_t table[128] = {0};
+ memcpy(table, from+1, sizeof(wchar_t)*(findPound-from-1));
+ table[findPound-from-1]=0;
+ const wchar_t *string = GetString(table, WTOI(findPound+1));
+ if (string)
+ return string;
+ }
+ }
+ return from;
+}
+
+const wchar_t *LocalesManager::getTranslation(const wchar_t *from)
+{
+ if (!from)
+ return NULL;
+
+ LocTrans *t = translationsList.findItem(from);
+ if (t == NULL)
+ {
+ return from;
+ }
+ return t->getTo();
+}
+
+void LocalesManager::addAccelerator(const wchar_t *bind, const wchar_t *action)
+{
+ LocAccel *a = acceleratorsList.findItem(bind);
+ if (a) // Martin> shouldn't we also check here if it is the same section?
+ // Hm, now that i look closer, we search our list for a wchar_t but we store LocAccels in the list - does this work?
+ acceleratorsList.removeItem(a);
+ acceleratorsList.addItem(new LocAccel(curSection, bind, action));
+}
+
+void LocalesManager::addAcceleratorFromSkin(const wchar_t *bind, const wchar_t *action)
+{
+ //TODO> use binary search
+ int l = acceleratorsList.getNumItems();
+ for (int i = 0;i < l;i++)
+ {
+ if (0 == WCSICMP(acceleratorsList[i]->getSection(), curSection) &&
+ 0 == WCSICMP(acceleratorsList[i]->getKey(), bind))
+ return;
+ }
+ acceleratorsList.addItem(new LocAccel(curSection, bind, action));
+}
+
+const wchar_t *LocalesManager::getBindFromAction(int action)
+{
+ //TODO> use binary search
+ int l = acceleratorsList.getNumItems();
+ for (int i = 0;i < l;i++)
+ {
+ if (acceleratorsList[i]->getActionNum() == action && action != ACTION_NONE)
+ return acceleratorsList[i]->getRealKey();
+ }
+ return NULL;
+}
+
+const wchar_t *LocalesManager::translateAccelerator(const wchar_t *section, const wchar_t *key)
+{
+ //TODO> use binary search
+ int l = acceleratorsList.getNumItems();
+ for (int i = 0;i < l;i++)
+ {
+ if (!WCSICMP(acceleratorsList[i]->getSection(), section))
+ if (!WCSICMP(acceleratorsList[i]->getKey(), key))
+ return acceleratorsList[i]->getAction();
+ }
+ return NULL;
+}
+
+#if 0
+void LocalesManager::setNewLocaleFile(const wchar_t *name)
+{
+ //WASABI_API_CONFIG->setStringPrivate(L"LocaleFile", name);
+ resetAll();
+ init();
+}
+#endif
+
+void LocalesManager::resetAll()
+{
+ translationsList.deleteAll();
+ acceleratorsList.deleteAll();
+}
+
+void LocalesManager::SetStringTable(const wchar_t *table)
+{
+ curTable = table;
+}
+
+void LocalesManager::setAcceleratorSection(const wchar_t *section)
+{
+ curSection = section;
+}
+
+const wchar_t *LocalesManager::getLocaleRoot()
+{
+ return localePath;
+}
+
+void LocalesManager::ResetStrings()
+{
+ for (int i=0;i!=stringTables.getNumItems();i++)
+ {
+ FREE(stringTables[i]->id);
+ for (int j=0;j!=stringTables[i]->entries.getNumItems();j++)
+ {
+ FREE(stringTables[i]->entries[j]->string);
+ }
+ }
+ stringTables.removeAll();
+}
+
+const wchar_t *LocalesManager::GetString(const wchar_t *table, uint32_t id)
+{
+ if (!table)
+ return 0;
+
+ if (!_wcsicmp(table, L"gen_ff"))
+ return WASABI_API_LNGSTRINGW(id);
+
+ for (int i=0;i!=stringTables.getNumItems();i++)
+ {
+ if (!wcscmp(table, stringTables[i]->id))
+ {
+ for (int j=0;j!=stringTables[i]->entries.getNumItems();j++)
+ {
+ if (id == stringTables[i]->entries[j]->id)
+ return stringTables[i]->entries[j]->string;
+ }
+ }
+ }
+ return 0;
+}
+
+void LocalesManager::AddString(const wchar_t *table, uint32_t id, const wchar_t *string)
+{
+ for (int i=0;i!=stringTables.getNumItems();i++)
+ {
+ if (!wcscmp(table, stringTables[i]->id))
+ {
+ for (int j=0;j!=stringTables[i]->entries.getNumItems();j++)
+ {
+ if (id == stringTables[i]->entries[j]->id)
+ {
+ FREE(stringTables[i]->entries[j]->string);
+ stringTables[i]->entries[j]->string=WCSDUP(string);
+ return;
+ }
+ }
+ StringEntry *newEntry = new StringEntry;
+ newEntry->id = id;
+ newEntry->string = WCSDUP(string);
+ stringTables[i]->entries.addItem(newEntry);
+ return;
+ }
+ }
+ StringTableData *newTable = new StringTableData;
+ newTable->id = WCSDUP(table);
+
+ StringEntry *newEntry = new StringEntry;
+ newEntry->id = id;
+ newEntry->string = WCSDUP(string);
+ stringTables.addItem(newTable);
+ newTable->entries.addItem(newEntry);
+}
+
+void LocalesManager::AddString(uint32_t id, const wchar_t *string)
+{
+ AddString(curTable, id, string);
+}
+
+LocalesAcceleratorXmlCallback LocalesManager::accelXmlCallback;
+LocalesAcceleratorSectionXmlCallback LocalesManager::accelSectionXmlCallback;
+LocalesTranslationXmlCallback LocalesManager::transXmlCallback;
+PtrListSorted<LocTrans, PLS_LocTrans, QuickSorted<LocTrans, PLS_LocTrans> > LocalesManager::translationsList;
+PtrListSorted<LocAccel, PLS_LocAccel, QuickSorted<LocAccel, PLS_LocAccel> > LocalesManager::acceleratorsList;
+StringW LocalesManager::localePath;
+//int LocalesManager::localeListLoaded = 0, LocalesManager::curLocaleNum = -1, LocalesManager::englishLocale;
+//PtrList<LocaleItem> LocalesManager::loadableLocalesList;
+StringW LocalesManager::curSection;
+LocalesSkinCallback LocalesManager::localesSkinCallback;
+StringW LocalesManager::curTable;
+StringTableXmlCallback LocalesManager::stringTableXmlCallback;
+StringTableEntryXmlCallback LocalesManager::stringTableXmlEntryCallback; \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/localesmgr.h b/Src/Wasabi/api/locales/localesmgr.h
new file mode 100644
index 00000000..b9495143
--- /dev/null
+++ b/Src/Wasabi/api/locales/localesmgr.h
@@ -0,0 +1,173 @@
+#ifndef _LOCALESMGR_H
+#define _LOCALESMGR_H
+
+#include "../xml/obj_xml.h"
+#include <bfc/ptrlist.h>
+#include <bfc/string/bfcstring.h>
+#include <api/skin/skinparse.h>
+
+#include "LocalesInfo.h"
+
+class LocTrans
+{
+public:
+ LocTrans(const wchar_t *pfrom, const wchar_t *pto) : from(pfrom), to(pto)
+ {
+ //from.toupper();
+ }
+ const wchar_t *getFrom() { return from; }
+ const wchar_t *getTo() { return to; }
+private:
+ StringW from;
+ StringW to;
+};
+
+class PLS_LocTrans
+{
+public:
+ // comparator for sorting
+ static int compareItem(LocTrans *p1, LocTrans* p2) {
+ return wcscmp(p1->getFrom(), p2->getFrom());
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, LocTrans *item) {
+ return wcscmp(attrib, item->getFrom());
+ }
+};
+
+class LocAccel
+{
+public:
+ LocAccel(const wchar_t *psec, const wchar_t *pkey, const wchar_t *paction)
+ : section(psec), key(pkey), realkey(pkey), action(paction)
+ {
+ key.tolower();
+ actionnum = SkinParser::getAction(paction);
+ }
+ const wchar_t *getKey() { return key; }
+ const wchar_t *getRealKey() { return realkey; }
+ const wchar_t *getAction() { return action; }
+ int getActionNum() { return actionnum; }
+ const wchar_t *getSection() { return section; }
+private:
+ StringW section;
+ StringW key;
+ StringW realkey;
+ StringW action;
+ int actionnum;
+};
+
+class PLS_LocAccel
+{
+public:
+ // comparator for sorting
+ static int compareItem(LocAccel *p1, LocAccel *p2)
+ {
+ return wcscmp(p1->getKey(), p2->getKey());
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, LocAccel *item)
+ {
+ return wcscmp(attrib, item->getKey());
+ }
+};
+
+class LocalesAcceleratorSectionXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+};
+
+class LocalesAcceleratorXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+};
+
+class LocalesTranslationXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+};
+
+class StringTableXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+};
+
+class StringTableEntryXmlCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+};
+
+class LocalesSkinCallback : public SkinCallbackI
+{
+public:
+ int skincb_onUnloading();
+ int skincb_onReset();
+ int skincb_onReload();
+ int skincb_onBeforeLoadingElements();
+ int skincb_onGuiLoaded();
+ int skincb_onLoaded();
+
+};
+
+class LocalesManager
+{
+public:
+ static void init();
+ static void load();
+ static void deinit();
+
+ static void loadFile(const wchar_t *name);
+
+ static void addTranslation(const wchar_t *from, const wchar_t *to);
+ static const wchar_t *getTranslation(const wchar_t *from); // will return the from parameter if not found
+ static const wchar_t *lookupString(const wchar_t *from); // will return the from parameter if not found
+
+ static void setAcceleratorSection(const wchar_t *section);
+ static void addAccelerator(const wchar_t *bind, const wchar_t *action);
+ static void addAcceleratorFromSkin(const wchar_t *bind, const wchar_t *action);
+ static const wchar_t *getBindFromAction(int action);
+ static const wchar_t *translateAccelerator(const wchar_t *section, const wchar_t *key);
+
+ //static const wchar_t *enumLoadableLocales(int num);
+ //static int getNumLocales();
+ //static void setNewLocaleFile(const wchar_t *name);
+ //static void setNewLocaleNum(int num);
+ //static int isCurrentLocaleNum(int num) { return num == curLocaleNum; }
+
+ static void resetAll();
+
+ static const wchar_t *getLocaleRoot();
+
+ static void LoadStringTables();
+ static void LoadStringTable(const wchar_t *filename);
+ static void SetStringTable(const wchar_t *table);
+ static void ResetStrings();
+ static const wchar_t *GetString(const wchar_t *table, uint32_t id);
+ static void AddString(const wchar_t *table, uint32_t id, const wchar_t *string);
+ static void AddString(uint32_t id, const wchar_t *string);
+private:
+ static LocalesAcceleratorXmlCallback accelXmlCallback;
+ static LocalesAcceleratorSectionXmlCallback accelSectionXmlCallback;
+ static LocalesTranslationXmlCallback transXmlCallback;
+
+ static PtrListSorted<LocTrans, PLS_LocTrans, QuickSorted<LocTrans, PLS_LocTrans> > translationsList;
+
+ static PtrListSorted<LocAccel, PLS_LocAccel, QuickSorted<LocAccel, PLS_LocAccel> > acceleratorsList;
+
+ static StringW localePath;
+
+ //static PtrList<LocaleItem> loadableLocalesList;
+
+ //static int localeListLoaded, curLocaleNum, englishLocale;
+ static StringW curSection;
+
+ static StringW curTable;
+
+ static LocalesSkinCallback localesSkinCallback;
+ static StringTableXmlCallback stringTableXmlCallback;
+ static StringTableEntryXmlCallback stringTableXmlEntryCallback;
+};
+
+#endif//_LOCALESMGR_H \ No newline at end of file
diff --git a/Src/Wasabi/api/locales/xlatstr.h b/Src/Wasabi/api/locales/xlatstr.h
new file mode 100644
index 00000000..aca8dac1
--- /dev/null
+++ b/Src/Wasabi/api/locales/xlatstr.h
@@ -0,0 +1,68 @@
+#ifndef _XLATSTR_H
+#define _XLATSTR_H
+
+#include <api/locales/localesmgr.h>
+
+/**
+ Provides string translation for the string
+ used as the constructor parameter.
+
+ The constructor will automatically lookup
+ the translated value of the string it receives
+ in the currently loaded locale.
+
+ @short Translates a string using the currently loaded locale.
+ @author Nullsoft
+ @ver 1.0
+ @see ComponentAPI::locales_getTranslation()
+*/
+
+class _ {
+ public:
+ /**
+ Automatically looks up the translated value of the string
+ it receives as a parameter in the currently loaded
+ locale. The same string is returned if there's no
+ translation.
+
+ @param str String to be translated.
+ @ret Translation found, Translated string; Translation not found, Input string;
+ */
+
+#if defined(WASABI_COMPILE_LOCALES)
+ _(const wchar_t *str) { s=LocalesManager::getTranslation(str); }
+#else
+ _(const wchar_t *str) { s=str; }
+#endif
+ operator const wchar_t *() const { return s; }
+
+ private:
+ const wchar_t *s;
+};
+
+
+class __ {
+ public:
+ /**
+ Automatically looks up the translated value of the string
+ it receives as a parameter in the currently loaded
+ locale. The same string is returned if there's no
+ translation.
+
+ @param str String to be translated.
+ @ret Translation found, Translated string; Translation not found, Input string;
+ */
+
+#if defined(WASABI_COMPILE_LOCALES)
+ __(const wchar_t *str) { s=LocalesManager::lookupString(str); }
+#else
+ __(const wchar_t *str) { s=str; }
+#endif
+ operator const wchar_t *() const { return s; }
+
+ private:
+ const wchar_t *s;
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/memmgr/api_memmgr.cpp b/Src/Wasabi/api/memmgr/api_memmgr.cpp
new file mode 100644
index 00000000..e1001185
--- /dev/null
+++ b/Src/Wasabi/api/memmgr/api_memmgr.cpp
@@ -0,0 +1,13 @@
+#include <precomp.h>
+#include "api_memmgr.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_memmgrI
+START_DISPATCH;
+ CB(API_MEMMGR_SYSMALLOC, sysMalloc);
+ VCB(API_MEMMGR_SYSFREE, sysFree);
+ CB(API_MEMMGR_SYSREALLOC, sysRealloc);
+ VCB(API_MEMMGR_SYSMEMCHANGED, sysMemChanged);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/memmgr/api_memmgr.h b/Src/Wasabi/api/memmgr/api_memmgr.h
new file mode 100644
index 00000000..301d8baa
--- /dev/null
+++ b/Src/Wasabi/api/memmgr/api_memmgr.h
@@ -0,0 +1,78 @@
+#ifndef __API_MEMMGR_H
+#define __API_MEMMGR_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include <new>
+class NOVTABLE api_memmgr : public Dispatchable
+{
+protected:
+ api_memmgr() {}
+ ~api_memmgr() {}
+
+public:
+ void *sysMalloc(size_t size);
+ void sysFree(void *ptr);
+ void *sysRealloc(void *ptr, size_t newsize);
+ void sysMemChanged(void *ptr);
+
+ DISPATCH_CODES
+ {
+ API_MEMMGR_SYSMALLOC = 0,
+ API_MEMMGR_SYSFREE = 10,
+ API_MEMMGR_SYSREALLOC = 20,
+ API_MEMMGR_SYSMEMCHANGED = 30,
+ };
+
+ // Some helper templates to new and delete objects with the memory manager
+ // you need to be cautious with Delete() and inheritance, particularly if you're dealing with a base class
+ // as the pointer to the derived class might not equal to the pointer to the base class, particularly with multiple inheritance
+ // e.g. class C : public A, public B {}; C c; assert((A*)&c == (B*)&c); will likely fail
+
+ template <class Class>
+ void New(Class **obj)
+ {
+ size_t toAlloc = sizeof(Class);
+ void *mem = sysMalloc(toAlloc);
+ *obj = new (mem) Class;
+ }
+
+ template <class Class>
+ void Delete(Class *obj)
+ {
+ if (obj)
+ {
+ obj->~Class();
+ sysFree(obj);
+ }
+ }
+};
+
+inline void *api_memmgr::sysMalloc(size_t size)
+{
+ return _call(API_MEMMGR_SYSMALLOC, (void *)NULL, size);
+}
+
+inline void api_memmgr::sysFree(void *ptr)
+{
+ _voidcall(API_MEMMGR_SYSFREE, ptr);
+}
+
+inline void *api_memmgr::sysRealloc(void *ptr, size_t newsize)
+{
+ return _call(API_MEMMGR_SYSREALLOC, (void *)NULL, ptr, newsize);
+}
+
+inline void api_memmgr::sysMemChanged(void *ptr)
+{
+ _voidcall(API_MEMMGR_SYSMEMCHANGED, ptr);
+}
+
+
+// {000CF46E-4DF6-4a43-BBE7-40E7A3EA02ED}
+static const GUID memMgrApiServiceGuid =
+{ 0xcf46e, 0x4df6, 0x4a43, { 0xbb, 0xe7, 0x40, 0xe7, 0xa3, 0xea, 0x2, 0xed } };
+
+extern api_memmgr *memmgrApi;
+
+#endif
diff --git a/Src/Wasabi/api/metrics/metricscb.h b/Src/Wasabi/api/metrics/metricscb.h
new file mode 100644
index 00000000..ca99a384
--- /dev/null
+++ b/Src/Wasabi/api/metrics/metricscb.h
@@ -0,0 +1,37 @@
+#ifndef _METRICSCB_H
+#define _METRICSCB_H
+
+#include <bfc/dispatch.h>
+
+// metrics codes
+namespace Metric {
+ enum {
+ TEXTDELTA=10,
+ };
+};
+
+class MetricsCallback : public Dispatchable {
+public:
+ int setMetric(int metricid, int param1=0, int param2=0);
+
+ // class Dispatchable codes
+ enum {
+ SETMETRIC=100,
+ };
+};
+
+inline int MetricsCallback::setMetric(int metricid, int param1, int param2) {
+ return _call(SETMETRIC, 0, metricid, param1, param2);
+}
+
+class MetricsCallbackI : public MetricsCallback {
+public:
+ virtual int metricscb_setTextDelta(int delta) { return 0; }
+
+protected:
+ int mcb_setMetric(int metricid, int param1, int param2);
+
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/api_maki.cpp b/Src/Wasabi/api/script/api_maki.cpp
new file mode 100644
index 00000000..a7ef8511
--- /dev/null
+++ b/Src/Wasabi/api/script/api_maki.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 01 02:49:40 1999]
+//
+// File : api_maki.cpp
+// Class : api_maki
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_maki.h"
+
+
diff --git a/Src/Wasabi/api/script/api_maki.h b/Src/Wasabi/api/script/api_maki.h
new file mode 100644
index 00000000..28eb7670
--- /dev/null
+++ b/Src/Wasabi/api/script/api_maki.h
@@ -0,0 +1,392 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 01 02:49:40 1999]
+//
+// File : api_maki.h
+// Class : api_maki
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_MAKI_H
+#define __API_MAKI_H
+
+#include <bfc/dispatch.h>
+
+class ScriptObject;
+class ScriptObjectController;
+
+#include <api/script/scriptvar.h>
+#include <api/script/vcputypes.h>
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE api_maki: public Dispatchable {
+ protected:
+ api_maki() {}
+ ~api_maki() {}
+ public:
+ void maki_pushObject(void *o);
+ void maki_pushInt(int i);
+ void maki_pushBoolean(int b);
+ void maki_pushFloat(float f);
+ void maki_pushDouble(double d);
+ void maki_pushString(const wchar_t *s);
+ void maki_pushVoid();
+ void maki_pushAny(scriptVar v);
+ void *maki_popObject();
+ int maki_popInt();
+ bool maki_popBoolean();
+ float maki_popFloat();
+ double maki_popDouble();
+ const wchar_t *maki_popString();
+ scriptVar maki_popAny();
+ void maki_popDiscard();
+ const wchar_t *maki_getFunction(int dlfid, int *nparams, ScriptObjectController **p);
+ int maki_addDlfRef(ScriptObjectController *o, const wchar_t *function_name, void *host);
+ void maki_addDlfClassRef(ScriptObjectController *o, void *host);
+ void maki_remDlfRef(void *host);
+ scriptVar maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params);
+ scriptVar maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid = -1);
+ int maki_getScriptInt(scriptVar v);
+ bool maki_getScriptBoolean(scriptVar v);
+ float maki_getScriptFloat(scriptVar v);
+ double maki_getScriptDouble(scriptVar v);
+ const wchar_t *maki_getScriptString(scriptVar v);
+ ScriptObject *maki_getScriptObject(scriptVar v);
+ scriptVar maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount);
+ ScriptObject *maki_instantiate(GUID classguid);
+ void maki_destroy(ScriptObject *o);
+ void *maki_encapsulate(GUID classguid, ScriptObject *o);
+ void maki_deencapsulate(GUID classguid, void *o);
+ ScriptObjectController *maki_getController(GUID scriptclass);
+ int maki_createOrphan(int type);
+ void maki_killOrphan(int id);
+ void maki_setObjectAtom(const wchar_t *atomname, ScriptObject *object);
+ ScriptObject *maki_getObjectAtom(const wchar_t *atomname);
+ #ifdef WASABI_COMPILE_WND
+ ScriptObject *maki_findObject(const wchar_t *name);
+ #endif
+ void vcpu_addScriptObject(ScriptObject *o);
+ void vcpu_removeScriptObject(ScriptObject *o);
+ int vcpu_getCacheCount();
+ int vcpu_isValidScriptId(int id);
+ int vcpu_mapVarId(int varid, int scriptid);
+ int vcpu_getUserAncestorId(int varid, int scriptid);
+ int vcpu_getNumEvents();
+ int vcpu_getEvent(int event, int *dlf, int *script, int *var);
+ int vcpu_getComplete();
+ void vcpu_setComplete();
+ void vcpu_resetComplete();
+ const wchar_t *vcpu_getClassName(int vcpuid, int localclassid);
+
+ protected:
+ enum {
+ API_MAKI_MAKI_PUSHOBJECT = 10,
+ API_MAKI_MAKI_PUSHINT = 20,
+ API_MAKI_MAKI_PUSHBOOLEAN = 30,
+ API_MAKI_MAKI_PUSHFLOAT = 40,
+ API_MAKI_MAKI_PUSHDOUBLE = 50,
+ API_MAKI_MAKI_PUSHSTRING = 60,
+ API_MAKI_MAKI_PUSHVOID = 70,
+ API_MAKI_MAKI_PUSHANY = 80,
+ API_MAKI_MAKI_POPOBJECT = 90,
+ API_MAKI_MAKI_POPINT = 100,
+ API_MAKI_MAKI_POPBOOLEAN = 110,
+ API_MAKI_MAKI_POPFLOAT = 120,
+ API_MAKI_MAKI_POPDOUBLE = 130,
+ API_MAKI_MAKI_POPSTRING = 140,
+ API_MAKI_MAKI_POPANY = 150,
+ API_MAKI_MAKI_POPDISCARD = 160,
+ API_MAKI_MAKI_GETFUNCTION = 170,
+ API_MAKI_MAKI_ADDDLFREF = 180,
+ API_MAKI_MAKI_ADDDLFCLASSREF = 190,
+ API_MAKI_MAKI_REMDLFREF = 200,
+ API_MAKI_MAKI_CALLFUNCTION = 210,
+ API_MAKI_MAKI_TRIGGEREVENT = 220,
+ API_MAKI_MAKI_GETSCRIPTINT = 230,
+ API_MAKI_MAKI_GETSCRIPTBOOLEAN = 240,
+ API_MAKI_MAKI_GETSCRIPTFLOAT = 250,
+ API_MAKI_MAKI_GETSCRIPTDOUBLE = 260,
+ API_MAKI_MAKI_GETSCRIPTSTRING = 270,
+ API_MAKI_MAKI_GETSCRIPTOBJECT = 280,
+ API_MAKI_MAKI_UPDATEDLF = 290,
+ API_MAKI_MAKI_INSTANTIATE = 300,
+ API_MAKI_MAKI_DESTROY = 310,
+ API_MAKI_MAKI_ENCAPSULATE = 320,
+ API_MAKI_MAKI_DEENCAPSULATE = 330,
+ API_MAKI_MAKI_GETCONTROLLER = 340,
+ API_MAKI_MAKI_CREATEORPHAN = 350,
+ API_MAKI_MAKI_KILLORPHAN = 360,
+ API_MAKI_MAKI_SETOBJECTATOM = 370,
+ API_MAKI_MAKI_GETOBJECTATOM = 380,
+ #ifdef WASABI_COMPILE_WND
+ API_MAKI_MAKI_FINDOBJECT = 390,
+ #endif
+ API_MAKI_VCPU_ADDSCRIPTOBJECT = 400,
+ API_MAKI_VCPU_REMOVESCRIPTOBJECT = 410,
+ API_MAKI_VCPU_GETCACHECOUNT = 420,
+ API_MAKI_VCPU_ISVALIDSCRIPTID = 430,
+ API_MAKI_VCPU_MAPVARID = 440,
+ API_MAKI_VCPU_GETUSERANCESTORID = 450,
+ API_MAKI_VCPU_GETNUMEVENTS = 460,
+ API_MAKI_VCPU_GETEVENT = 470,
+ API_MAKI_VCPU_GETCOMPLETE = 480,
+ API_MAKI_VCPU_SETCOMPLETE = 481,
+ API_MAKI_VCPU_RESETCOMPLETE = 482,
+ API_MAKI_VCPU_GETCLASSNAME = 490,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline void api_maki::maki_pushObject(void *o) {
+ _voidcall(API_MAKI_MAKI_PUSHOBJECT, o);
+}
+
+inline void api_maki::maki_pushInt(int i) {
+ _voidcall(API_MAKI_MAKI_PUSHINT, i);
+}
+
+inline void api_maki::maki_pushBoolean(int b) {
+ _voidcall(API_MAKI_MAKI_PUSHBOOLEAN, b);
+}
+
+inline void api_maki::maki_pushFloat(float f) {
+ _voidcall(API_MAKI_MAKI_PUSHFLOAT, f);
+}
+
+inline void api_maki::maki_pushDouble(double d) {
+ _voidcall(API_MAKI_MAKI_PUSHDOUBLE, d);
+}
+
+inline void api_maki::maki_pushString(const wchar_t *s) {
+ _voidcall(API_MAKI_MAKI_PUSHSTRING, s);
+}
+
+inline void api_maki::maki_pushVoid() {
+ _voidcall(API_MAKI_MAKI_PUSHVOID);
+}
+
+inline void api_maki::maki_pushAny(scriptVar v) {
+ _voidcall(API_MAKI_MAKI_PUSHANY, v);
+}
+
+inline void *api_maki::maki_popObject() {
+ void *__retval = _call(API_MAKI_MAKI_POPOBJECT, (void *)NULL);
+ return __retval;
+}
+
+inline int api_maki::maki_popInt() {
+ int __retval = _call(API_MAKI_MAKI_POPINT, (int)0);
+ return __retval;
+}
+
+inline bool api_maki::maki_popBoolean() {
+ bool __retval = _call(API_MAKI_MAKI_POPBOOLEAN, (bool)0);
+ return __retval;
+}
+
+inline float api_maki::maki_popFloat() {
+ float __retval = _call(API_MAKI_MAKI_POPFLOAT, (float)0);
+ return __retval;
+}
+
+inline double api_maki::maki_popDouble() {
+ double __retval = _call(API_MAKI_MAKI_POPDOUBLE, (double)0);
+ return __retval;
+}
+
+inline const wchar_t *api_maki::maki_popString() {
+ return _call(API_MAKI_MAKI_POPSTRING, (const wchar_t *)0);
+
+}
+
+inline scriptVar api_maki::maki_popAny()
+{
+ scriptVar r; r.type = SCRIPT_VOID; r.data.idata = 0;
+ scriptVar __retval = _call(API_MAKI_MAKI_POPANY, (scriptVar)r);
+ return __retval;
+}
+
+inline void api_maki::maki_popDiscard() {
+ _voidcall(API_MAKI_MAKI_POPDISCARD);
+}
+
+inline const wchar_t *api_maki::maki_getFunction(int dlfid, int *nparams, ScriptObjectController **p) {
+ return _call(API_MAKI_MAKI_GETFUNCTION, (const wchar_t *)0, dlfid, nparams, p);
+
+}
+
+inline int api_maki::maki_addDlfRef(ScriptObjectController *o, const wchar_t *function_name, void *host) {
+ int __retval = _call(API_MAKI_MAKI_ADDDLFREF, (int)0, o, function_name, host);
+ return __retval;
+}
+
+inline void api_maki::maki_addDlfClassRef(ScriptObjectController *o, void *host) {
+ _voidcall(API_MAKI_MAKI_ADDDLFCLASSREF, o, host);
+}
+
+inline void api_maki::maki_remDlfRef(void *host) {
+ _voidcall(API_MAKI_MAKI_REMDLFREF, host);
+}
+
+inline scriptVar api_maki::maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params) {
+ scriptVar r; r.type = SCRIPT_VOID; r.data.idata = 0;
+ scriptVar __retval = _call(API_MAKI_MAKI_CALLFUNCTION, (scriptVar)r, o, dlfid, params);
+ return __retval;
+}
+
+inline scriptVar api_maki::maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid) {
+ scriptVar r; r.type = SCRIPT_VOID; r.data.idata = 0;
+ scriptVar __retval = _call(API_MAKI_MAKI_TRIGGEREVENT, (scriptVar)r, o, dlfid, np, scriptid);
+ return __retval;
+}
+
+inline int api_maki::maki_getScriptInt(scriptVar v) {
+ int __retval = _call(API_MAKI_MAKI_GETSCRIPTINT, (int)0, v);
+ return __retval;
+}
+
+inline bool api_maki::maki_getScriptBoolean(scriptVar v) {
+ bool __retval = _call(API_MAKI_MAKI_GETSCRIPTBOOLEAN, (bool)0, v);
+ return __retval;
+}
+
+inline float api_maki::maki_getScriptFloat(scriptVar v) {
+ float __retval = _call(API_MAKI_MAKI_GETSCRIPTFLOAT, (float)0, v);
+ return __retval;
+}
+
+inline double api_maki::maki_getScriptDouble(scriptVar v) {
+ double __retval = _call(API_MAKI_MAKI_GETSCRIPTDOUBLE, (double)0, v);
+ return __retval;
+}
+
+inline const wchar_t *api_maki::maki_getScriptString(scriptVar v) {
+ const wchar_t *__retval = _call(API_MAKI_MAKI_GETSCRIPTSTRING, (const wchar_t *)0, v);
+ return __retval;
+}
+
+inline ScriptObject *api_maki::maki_getScriptObject(scriptVar v) {
+ ScriptObject *__retval = _call(API_MAKI_MAKI_GETSCRIPTOBJECT, (ScriptObject *)NULL, v);
+ return __retval;
+}
+
+inline scriptVar api_maki::maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount) {
+ scriptVar r; r.type = SCRIPT_VOID; r.data.idata = 0;
+ scriptVar __retval = _call(API_MAKI_MAKI_UPDATEDLF, (scriptVar)r, cmd, dlfid, linkcount);
+ return __retval;
+}
+
+inline ScriptObject *api_maki::maki_instantiate(GUID classguid) {
+ ScriptObject *__retval = _call(API_MAKI_MAKI_INSTANTIATE, (ScriptObject *)NULL, classguid);
+ return __retval;
+}
+
+inline void api_maki::maki_destroy(ScriptObject *o) {
+ _voidcall(API_MAKI_MAKI_DESTROY, o);
+}
+
+inline void *api_maki::maki_encapsulate(GUID classguid, ScriptObject *o) {
+ void *__retval = _call(API_MAKI_MAKI_ENCAPSULATE, (void *)NULL, classguid, o);
+ return __retval;
+}
+
+inline void api_maki::maki_deencapsulate(GUID classguid, void *o) {
+ _voidcall(API_MAKI_MAKI_DEENCAPSULATE, classguid, o);
+}
+
+inline ScriptObjectController *api_maki::maki_getController(GUID scriptclass) {
+ ScriptObjectController *__retval = _call(API_MAKI_MAKI_GETCONTROLLER, (ScriptObjectController *)NULL, scriptclass);
+ return __retval;
+}
+
+inline int api_maki::maki_createOrphan(int type) {
+ int __retval = _call(API_MAKI_MAKI_CREATEORPHAN, (int)0, type);
+ return __retval;
+}
+
+inline void api_maki::maki_killOrphan(int id) {
+ _voidcall(API_MAKI_MAKI_KILLORPHAN, id);
+}
+
+inline void api_maki::maki_setObjectAtom(const wchar_t *atomname, ScriptObject *object) {
+ _voidcall(API_MAKI_MAKI_SETOBJECTATOM, atomname, object);
+}
+
+inline ScriptObject *api_maki::maki_getObjectAtom(const wchar_t *atomname) {
+ ScriptObject *__retval = _call(API_MAKI_MAKI_GETOBJECTATOM, (ScriptObject *)NULL, atomname);
+ return __retval;
+}
+
+#ifdef WASABI_COMPILE_WND
+inline ScriptObject *api_maki::maki_findObject(const wchar_t *name) {
+ ScriptObject *__retval = _call(API_MAKI_MAKI_FINDOBJECT, (ScriptObject *)NULL, name);
+ return __retval;
+}
+
+#endif
+inline void api_maki::vcpu_addScriptObject(ScriptObject *o) {
+ _voidcall(API_MAKI_VCPU_ADDSCRIPTOBJECT, o);
+}
+
+inline void api_maki::vcpu_removeScriptObject(ScriptObject *o) {
+ _voidcall(API_MAKI_VCPU_REMOVESCRIPTOBJECT, o);
+}
+
+inline int api_maki::vcpu_getCacheCount() {
+ int __retval = _call(API_MAKI_VCPU_GETCACHECOUNT, (int)0);
+ return __retval;
+}
+
+inline int api_maki::vcpu_isValidScriptId(int id) {
+ int __retval = _call(API_MAKI_VCPU_ISVALIDSCRIPTID, (int)0, id);
+ return __retval;
+}
+
+inline int api_maki::vcpu_mapVarId(int varid, int scriptid) {
+ int __retval = _call(API_MAKI_VCPU_MAPVARID, (int)0, varid, scriptid);
+ return __retval;
+}
+
+inline int api_maki::vcpu_getUserAncestorId(int varid, int scriptid) {
+ int __retval = _call(API_MAKI_VCPU_GETUSERANCESTORID, (int)0, varid, scriptid);
+ return __retval;
+}
+
+inline int api_maki::vcpu_getNumEvents() {
+ int __retval = _call(API_MAKI_VCPU_GETNUMEVENTS, (int)0);
+ return __retval;
+}
+
+inline int api_maki::vcpu_getEvent(int event, int *dlf, int *script, int *var) {
+ int __retval = _call(API_MAKI_VCPU_GETEVENT, (int)0, event, dlf, script, var);
+ return __retval;
+}
+
+inline int api_maki::vcpu_getComplete() {
+ int __retval = _call(API_MAKI_VCPU_GETCOMPLETE, (int)0);
+ return __retval;
+}
+
+inline void api_maki::vcpu_setComplete() {
+ _voidcall(API_MAKI_VCPU_SETCOMPLETE);
+}
+
+inline void api_maki::vcpu_resetComplete() {
+ _voidcall(API_MAKI_VCPU_RESETCOMPLETE);
+}
+
+inline const wchar_t *api_maki::vcpu_getClassName(int vcpuid, int localclassid) {
+ return _call(API_MAKI_VCPU_GETCLASSNAME, (const wchar_t *)0, vcpuid, localclassid);
+
+}
+
+// ----------------------------------------------------------------------------
+
+// {87D2391B-C928-4a49-8E0B-D47C049E0711}
+static const GUID makiApiServiceGuid =
+{ 0x87d2391b, 0xc928, 0x4a49, { 0x8e, 0xb, 0xd4, 0x7c, 0x4, 0x9e, 0x7, 0x11 } };
+
+extern api_maki *makiApi;
+
+#endif // __API_MAKI_H
diff --git a/Src/Wasabi/api/script/api_makidebug.cpp b/Src/Wasabi/api/script/api_makidebug.cpp
new file mode 100644
index 00000000..f356f1f1
--- /dev/null
+++ b/Src/Wasabi/api/script/api_makidebug.cpp
@@ -0,0 +1,20 @@
+#include "precomp.h"
+#include "api_makidebug.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_makiDebuggerI
+START_DISPATCH;
+ VCB(API_MAKIDEBUGGER_DEBUGGER_TRACE, debugger_trace);
+ CB(API_MAKIDEBUGGER_DEBUGGER_ISACTIVE, debugger_isActive);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVIP, debugger_getVIP);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVSD, debugger_getVSD);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVCC, debugger_getVCC);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVSP, debugger_getVSP);
+ CB(API_MAKIDEBUGGER_DEBUGGER_FILTEREVENT, debugger_filterEvent);
+ VCB(API_MAKIDEBUGGER_DEBUGGER_EVENTCOMPLETE, debugger_eventComplete);
+ CB(API_MAKIDEBUGGER_DEBUGGER_CREATEJITD, debugger_createJITD);
+ CB(API_MAKIDEBUGGER_DEBUGGER_READSTACK, debugger_readStack);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETCODEBLOCK, debugger_getCodeBlock);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/script/api_makidebug.h b/Src/Wasabi/api/script/api_makidebug.h
new file mode 100644
index 00000000..c55d130e
--- /dev/null
+++ b/Src/Wasabi/api/script/api_makidebug.h
@@ -0,0 +1,134 @@
+#ifndef __API_MAKIDEBUG_H
+#define __API_MAKIDEBUG_H
+
+/*---------------------------------------------------------
+api_makiDebugger
+ void debugger_trace();
+ int debugger_isActive();
+ int debugger_getVIP();
+ int debugger_getVSD();
+ int debugger_getVCC();
+ int debugger_getVSP();
+ int debugger_filterEvent(int vcpuid, int eventid);
+ void debugger_eventComplete();
+ MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1);
+ int debugger_readStack(int n);
+ int debugger_getCodeBlock(int vcpuid);
+---------------------------------------------------------*/
+
+#include <wasabicfg.h>
+
+#ifndef WASABI_COMPILE_SCRIPT
+#error "This module requires the script api"
+#endif
+
+#ifndef WASABI_COMPILE_MAKIDEBUG
+#error "This module requires the script debugger api"
+#endif
+
+#include <bfc/dispatch.h>
+#include <api/script/scriptvar.h>
+
+class MakiJITD;
+
+class NOVTABLE api_makiDebugger : public Dispatchable {
+ public:
+ void debugger_trace();
+ int debugger_isActive();
+ int debugger_getVIP();
+ int debugger_getVSD();
+ int debugger_getVCC();
+ int debugger_getVSP();
+ int debugger_filterEvent(int vcpuid, int eventid);
+ void debugger_eventComplete();
+ MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1);
+ scriptVar debugger_readStack(int n);
+ const char *debugger_getCodeBlock(int vcpuid);
+
+ enum {
+ API_MAKIDEBUGGER_DEBUGGER_TRACE = 0,
+ API_MAKIDEBUGGER_DEBUGGER_ISACTIVE = 10,
+ API_MAKIDEBUGGER_DEBUGGER_GETVIP = 20,
+ API_MAKIDEBUGGER_DEBUGGER_GETVSD = 30,
+ API_MAKIDEBUGGER_DEBUGGER_GETVCC = 40,
+ API_MAKIDEBUGGER_DEBUGGER_GETVSP = 50,
+ API_MAKIDEBUGGER_DEBUGGER_FILTEREVENT = 60,
+ API_MAKIDEBUGGER_DEBUGGER_EVENTCOMPLETE = 70,
+ API_MAKIDEBUGGER_DEBUGGER_CREATEJITD = 80,
+ API_MAKIDEBUGGER_DEBUGGER_READSTACK = 90,
+ API_MAKIDEBUGGER_DEBUGGER_GETCODEBLOCK = 100,
+ };
+};
+
+inline void api_makiDebugger::debugger_trace() {
+ _voidcall(API_MAKIDEBUGGER_DEBUGGER_TRACE);
+}
+
+inline int api_makiDebugger::debugger_isActive() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_ISACTIVE, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVIP() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVIP, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVSD() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVSD, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVCC() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVCC, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVSP() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVSP, (int)0);
+}
+
+inline int api_makiDebugger::debugger_filterEvent(int vcpuid, int eventid) {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_FILTEREVENT, (int)0, vcpuid, eventid);
+}
+
+inline void api_makiDebugger::debugger_eventComplete() {
+ _voidcall(API_MAKIDEBUGGER_DEBUGGER_EVENTCOMPLETE);
+}
+
+inline MakiJITD *api_makiDebugger::debugger_createJITD(int vcpuid, int bringitup) {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_CREATEJITD, (MakiJITD *)NULL, vcpuid, bringitup);
+}
+
+inline const char *api_makiDebugger::debugger_getCodeBlock(int vcpuid) {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETCODEBLOCK, (const char *)NULL, vcpuid);
+}
+
+inline scriptVar api_makiDebugger::debugger_readStack(int n) {
+ scriptVar v={0,0};
+ return _call(API_MAKIDEBUGGER_DEBUGGER_READSTACK, v, n);
+}
+
+class api_makiDebuggerI : public api_makiDebugger {
+ public:
+ virtual void debugger_trace()=0;
+ virtual int debugger_isActive()=0;
+ virtual int debugger_getVIP()=0;
+ virtual int debugger_getVSD()=0;
+ virtual int debugger_getVCC()=0;
+ virtual int debugger_getVSP()=0;
+ virtual int debugger_filterEvent(int vcpuid, int eventid)=0;
+ virtual void debugger_eventComplete()=0;
+ virtual MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1)=0;
+ virtual scriptVar debugger_readStack(int n)=0;
+ virtual const char *debugger_getCodeBlock(int vcpuid)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {858E4B64-AF1E-4b64-8D27-EFFAD9F82BB4}
+static const GUID makiDebugApiServiceGuid =
+{ 0x858e4b64, 0xaf1e, 0x4b64, { 0x8d, 0x27, 0xef, 0xfa, 0xd9, 0xf8, 0x2b, 0xb4 } };
+
+extern api_makiDebugger *debugApi;
+
+#endif
+
+
diff --git a/Src/Wasabi/api/script/api_makii.cpp b/Src/Wasabi/api/script/api_makii.cpp
new file mode 100644
index 00000000..37f885e7
--- /dev/null
+++ b/Src/Wasabi/api/script/api_makii.cpp
@@ -0,0 +1,264 @@
+#include <precomp.h>
+#include "api_makii.h"
+
+#include <api/script/vcpu.h>
+#include <api/script/objecttable.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+
+api_maki *makiApi = NULL;
+
+api_makiI::api_makiI() {
+ VCPU::scriptManager = new ScriptObjectManager();
+}
+
+api_makiI::~api_makiI() {
+ delete VCPU::scriptManager;
+ VCPU::scriptManager = NULL;
+ VCPU::shutdown();
+ ObjectTable::unloadExternalClasses();
+}
+
+void api_makiI::init() {
+ ObjectTable::loadExternalClasses();
+}
+
+void api_makiI::maki_pushObject(void *o) {
+ VCPU::pushObject(o);
+}
+
+void api_makiI::maki_pushInt(int i) {
+ VCPU::pushInt(i);
+}
+
+void api_makiI::maki_pushBoolean(int b) {
+ VCPU::pushBoolean(b);
+}
+
+void api_makiI::maki_pushFloat(float f) {
+ VCPU::pushFloat(f);
+}
+
+void api_makiI::maki_pushDouble(double d) {
+ VCPU::pushDouble(d);
+}
+
+void api_makiI::maki_pushString(const wchar_t *s) {
+ VCPU::pushString(s);
+}
+
+void api_makiI::maki_pushVoid() {
+ VCPU::pushVoid();
+}
+
+void api_makiI::maki_pushAny(scriptVar v) {
+ VCPU::push(v);
+}
+
+void *api_makiI::maki_popObject() {
+ return VCPU::popObject();
+}
+
+int api_makiI::maki_popInt() {
+ return VCPU::popInt();
+}
+
+bool api_makiI::maki_popBoolean() {
+ return VCPU::popBoolean();
+}
+
+float api_makiI::maki_popFloat() {
+ return VCPU::popFloat();
+}
+
+double api_makiI::maki_popDouble() {
+ return VCPU::popDouble();
+}
+
+const wchar_t *api_makiI::maki_popString() {
+ return VCPU::popString();
+}
+
+scriptVar api_makiI::maki_popAny() {
+ return VCPU::pop().v;
+}
+
+void api_makiI::maki_popDiscard() {
+ VCPU::popDiscard();
+}
+
+const wchar_t *api_makiI::maki_getFunction(int dlfid, int *nparams, ScriptObjectController **p) {
+ return ObjectTable::getFunction(dlfid, nparams, p);
+}
+
+int api_makiI::maki_addDlfRef(ScriptObjectController *o, const wchar_t *function_name, void *host) {
+ return ObjectTable::dlfAddRef(o, function_name, host);
+}
+
+void api_makiI::maki_addDlfClassRef(ScriptObjectController *o, void *host) {
+ ObjectTable::dlfAddClassRef(o, host);
+}
+
+void api_makiI::maki_remDlfRef(void *host) {
+ ObjectTable::dlfRemRef(host);
+}
+
+scriptVar api_makiI::maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params) {
+ return ObjectTable::callFunction(o, dlfid, params);
+}
+
+scriptVar api_makiI::maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid) {
+ scriptVar v = MAKE_SCRIPT_OBJECT(o);
+ return VCPU::executeEvent(v, dlfid, np, scriptid);
+}
+
+int api_makiI::maki_getScriptInt(scriptVar v) {
+ return SOM::makeInt(&v);
+}
+
+bool api_makiI::maki_getScriptBoolean(scriptVar v) {
+ return SOM::makeBoolean(&v);
+}
+
+float api_makiI::maki_getScriptFloat(scriptVar v) {
+ return SOM::makeFloat(&v);
+}
+
+double api_makiI::maki_getScriptDouble(scriptVar v) {
+ return SOM::makeDouble(&v);
+}
+
+const wchar_t *api_makiI::maki_getScriptString(scriptVar v)
+{
+ ASSERT(v.type == SCRIPT_STRING);
+ return v.data.sdata;
+}
+
+ScriptObject *api_makiI::maki_getScriptObject(scriptVar v) {
+ ASSERT(!SOM::isNumeric(&v) && v.type != SCRIPT_STRING);
+ return v.data.odata;
+}
+
+scriptVar api_makiI::maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount) {
+ switch (cmd->cmd) {
+ case MAKI_CMD_ADDREF:
+ (*linkcount)++;
+ break;
+ case MAKI_CMD_REMREF:
+ (*linkcount)--;
+ ASSERT(*linkcount >= 0);
+ if (*linkcount == 0)
+ *dlfid = -1;
+ break;
+ case MAKI_CMD_SETDLF:
+ ASSERT(*dlfid == -1);
+ *dlfid = cmd->id;
+ break;
+ case MAKI_CMD_GETDLF:
+ cmd->id = *dlfid;
+ break;
+ case MAKI_CMD_RESETDLF:
+ *dlfid = -1;
+ break;
+ }
+ RETURN_SCRIPT_VOID
+}
+
+ScriptObject *api_makiI::maki_instantiate(GUID classguid) {
+ int classid = ObjectTable::getClassFromGuid(classguid);
+ if (classid == -1) return NULL;
+ return ObjectTable::instantiate(classid);
+}
+
+void api_makiI::maki_destroy(ScriptObject *o) {
+ ObjectTable::destroy(o);
+}
+
+void *api_makiI::maki_encapsulate(GUID classguid, ScriptObject *o) {
+ int classid = ObjectTable::getClassFromGuid(classguid);
+ if (classid == -1) return NULL;
+ return ObjectTable::encapsulate(classid, o);
+}
+
+void api_makiI::maki_deencapsulate(GUID classguid, void *o) {
+ int classid = ObjectTable::getClassFromGuid(classguid);
+ if (classid == -1) return;
+ ObjectTable::deencapsulate(classid, o);
+}
+
+ScriptObjectController *api_makiI::maki_getController(GUID scriptclass) {
+ return ObjectTable::getController(scriptclass);
+}
+
+int api_makiI::maki_createOrphan(int type) {
+ return VCPU::createOrphan(type);
+}
+
+void api_makiI::maki_killOrphan(int id) {
+ VCPU::killOrphan(id);
+}
+
+void api_makiI::maki_setObjectAtom(const wchar_t *atomname, ScriptObject *object) {
+ VCPU::setAtom(atomname, object);
+}
+
+ScriptObject *api_makiI::maki_getObjectAtom(const wchar_t *atomname) {
+ return VCPU::getAtom(atomname);
+}
+
+#ifdef WASABI_COMPILE_WND
+ScriptObject *api_makiI::maki_findObject(const wchar_t *name)
+{
+ return ScriptObjectManager::findObject(name);
+}
+#endif
+
+void api_makiI::vcpu_addScriptObject(ScriptObject *o) {
+ SystemObject::addScriptObject(o);
+}
+
+void api_makiI::vcpu_removeScriptObject(ScriptObject *o) {
+ SystemObject::removeScriptObject(o);
+}
+
+int api_makiI::vcpu_getCacheCount() {
+ return Script::getCacheCount();
+}
+
+int api_makiI::vcpu_isValidScriptId(int id) {
+ return Script::isValidScriptId(id);
+}
+
+int api_makiI::vcpu_mapVarId(int varid, int scriptid) {
+ return Script::varIdToGlobal(varid, scriptid);
+}
+
+int api_makiI::vcpu_getUserAncestorId(int varid, int scriptid) {
+ return Script::getUserAncestor(varid, scriptid);
+}
+
+int api_makiI::vcpu_getNumEvents() {
+ return Script::getNumEventsLinked();
+}
+
+int api_makiI::vcpu_getEvent(int event, int *dlf, int *script, int *var) {
+ return Script::getLinkedEventParams(event, dlf, script, var);
+}
+
+int api_makiI::vcpu_getComplete() {
+ return VCPU::getComplete();
+}
+
+void api_makiI::vcpu_setComplete() {
+ VCPU::setComplete();
+}
+
+void api_makiI::vcpu_resetComplete() {
+ VCPU::resetComplete();
+}
+
+const wchar_t *api_makiI::vcpu_getClassName(int vcpuid, int localclassid) {
+ return VCPU::getClassName(vcpuid, localclassid);
+}
+
diff --git a/Src/Wasabi/api/script/api_makii.h b/Src/Wasabi/api/script/api_makii.h
new file mode 100644
index 00000000..51fc1320
--- /dev/null
+++ b/Src/Wasabi/api/script/api_makii.h
@@ -0,0 +1,93 @@
+#ifndef _API_MAKII_H
+#define _API_MAKII_H
+
+/*[interface.header.h]
+#include "common/script/scriptvar.h"
+#include "common/script/vcputypes.h"
+#include "common/script/objcontroller.h"
+*/
+
+#include "api_maki.h"
+#include "api_makix.h"
+
+class ScriptObject;
+class ScriptObjectController;
+
+class api_makiI : public api_makiX {
+ public:
+ api_makiI();
+ virtual ~api_makiI();
+ DISPATCH(10) virtual void maki_pushObject(void *o);
+ DISPATCH(20) virtual void maki_pushInt(int i);
+ DISPATCH(30) virtual void maki_pushBoolean(int b);
+ DISPATCH(40) virtual void maki_pushFloat(float f);
+ DISPATCH(50) virtual void maki_pushDouble(double d);
+ DISPATCH(60) virtual void maki_pushString(const wchar_t *s);
+ DISPATCH(70) virtual void maki_pushVoid();
+ DISPATCH(80) virtual void maki_pushAny(scriptVar v);
+ DISPATCH(90) virtual void *maki_popObject();
+ DISPATCH(100) virtual int maki_popInt();
+ DISPATCH(110) virtual bool maki_popBoolean();
+ DISPATCH(120) virtual float maki_popFloat();
+ DISPATCH(130) virtual double maki_popDouble();
+ DISPATCH(140) virtual const wchar_t *maki_popString();
+ DISPATCH(150) virtual scriptVar maki_popAny();
+ DISPATCH(160) virtual void maki_popDiscard();
+ DISPATCH(170) virtual const wchar_t *maki_getFunction(int dlfid, int *nparams, ScriptObjectController **p);
+ DISPATCH(180) virtual int maki_addDlfRef(ScriptObjectController *o, const wchar_t *function_name, void *host);
+ DISPATCH(190) virtual void maki_addDlfClassRef(ScriptObjectController *o, void *host);
+ DISPATCH(200) virtual void maki_remDlfRef(void *host);
+ DISPATCH(210) virtual scriptVar maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params);
+ DISPATCH(220) virtual scriptVar maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid = -1);
+ DISPATCH(230) virtual int maki_getScriptInt(scriptVar v);
+ DISPATCH(240) virtual bool maki_getScriptBoolean(scriptVar v);
+ DISPATCH(250) virtual float maki_getScriptFloat(scriptVar v);
+ DISPATCH(260) virtual double maki_getScriptDouble(scriptVar v);
+ DISPATCH(270) virtual const wchar_t *maki_getScriptString(scriptVar v);
+ DISPATCH(280) virtual ScriptObject *maki_getScriptObject(scriptVar v);
+ DISPATCH(290) virtual scriptVar maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount);
+ DISPATCH(300) virtual ScriptObject *maki_instantiate(GUID classguid);
+ DISPATCH(310) virtual void maki_destroy(ScriptObject *o);
+ DISPATCH(320) virtual void *maki_encapsulate(GUID classguid, ScriptObject *o);
+ DISPATCH(330) virtual void maki_deencapsulate(GUID classguid, void *o);
+ DISPATCH(340) virtual ScriptObjectController *maki_getController(GUID scriptclass);
+ DISPATCH(350) virtual int maki_createOrphan(int type);
+ DISPATCH(360) virtual void maki_killOrphan(int id);
+ DISPATCH(370) virtual void maki_setObjectAtom(const wchar_t *atomname, ScriptObject *object);
+ DISPATCH(380) virtual ScriptObject *maki_getObjectAtom(const wchar_t *atomname);
+/*[interface.maki_findObject.cpp]#ifdef WASABI_COMPILE_WND*/
+/*[interface.maki_findObject.h]#ifdef WASABI_COMPILE_WND*/
+/*[dispatchable.maki_findObject.enum]#ifdef WASABI_COMPILE_WND*/
+/*[dispatchable.maki_findObject.bridge]#ifdef WASABI_COMPILE_WND*/
+#ifdef WASABI_COMPILE_WND
+ DISPATCH(390) virtual ScriptObject *maki_findObject(const wchar_t *name);
+#endif
+/*[interface.vcpu_addScriptObject.cpp]#endif*/
+/*[interface.vcpu_addScriptObject.h]#endif*/
+/*[dispatchable.vcpu_addScriptObject.enum]#endif*/
+/*[dispatchable.vcpu_addScriptObject.bridge]#endif*/
+ DISPATCH(400) virtual void vcpu_addScriptObject(ScriptObject *o);
+ DISPATCH(410) virtual void vcpu_removeScriptObject(ScriptObject *o);
+ DISPATCH(420) virtual int vcpu_getCacheCount();
+ DISPATCH(430) virtual int vcpu_isValidScriptId(int id);
+ DISPATCH(440) virtual int vcpu_mapVarId(int varid, int scriptid);
+ DISPATCH(450) virtual int vcpu_getUserAncestorId(int varid, int scriptid);
+ DISPATCH(460) virtual int vcpu_getNumEvents();
+ DISPATCH(470) virtual int vcpu_getEvent(int event, int *dlf, int *script, int *var);
+ DISPATCH(480) virtual int vcpu_getComplete();
+ DISPATCH(481) virtual void vcpu_setComplete();
+ DISPATCH(482) virtual void vcpu_resetComplete();
+ DISPATCH(490) virtual const wchar_t *vcpu_getClassName(int vcpuid, int localclassid);
+
+ NODISPATCH void init();
+};
+
+/*[interface.footer.h]
+// {F2398F09-63B0-4442-86C9-F8BC473F6DA7}
+static const GUID makiApiServiceGuid =
+{ 0xf2398f09, 0x63b0, 0x4442, { 0x86, 0xc9, 0xf8, 0xbc, 0x47, 0x3f, 0x6d, 0xa7 } };
+
+extern api_maki *makiApi;
+*/
+
+#endif
diff --git a/Src/Wasabi/api/script/api_makix.cpp b/Src/Wasabi/api/script/api_makix.cpp
new file mode 100644
index 00000000..8d4efdd5
--- /dev/null
+++ b/Src/Wasabi/api/script/api_makix.cpp
@@ -0,0 +1,72 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 01 02:49:41 1999]
+//
+// File : api_makix.cpp
+// Class : api_maki
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "api_makix.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_makiX
+START_DISPATCH;
+ VCB(API_MAKI_MAKI_PUSHOBJECT, maki_pushObject);
+ VCB(API_MAKI_MAKI_PUSHINT, maki_pushInt);
+ VCB(API_MAKI_MAKI_PUSHBOOLEAN, maki_pushBoolean);
+ VCB(API_MAKI_MAKI_PUSHFLOAT, maki_pushFloat);
+ VCB(API_MAKI_MAKI_PUSHDOUBLE, maki_pushDouble);
+ VCB(API_MAKI_MAKI_PUSHSTRING, maki_pushString);
+ VCB(API_MAKI_MAKI_PUSHVOID, maki_pushVoid);
+ VCB(API_MAKI_MAKI_PUSHANY, maki_pushAny);
+ CB(API_MAKI_MAKI_POPOBJECT, maki_popObject);
+ CB(API_MAKI_MAKI_POPINT, maki_popInt);
+ CB(API_MAKI_MAKI_POPBOOLEAN, maki_popBoolean);
+ CB(API_MAKI_MAKI_POPFLOAT, maki_popFloat);
+ CB(API_MAKI_MAKI_POPDOUBLE, maki_popDouble);
+ CB(API_MAKI_MAKI_POPSTRING, maki_popString);
+ CB(API_MAKI_MAKI_POPANY, maki_popAny);
+ VCB(API_MAKI_MAKI_POPDISCARD, maki_popDiscard);
+ CB(API_MAKI_MAKI_GETFUNCTION, maki_getFunction);
+ CB(API_MAKI_MAKI_ADDDLFREF, maki_addDlfRef);
+ VCB(API_MAKI_MAKI_ADDDLFCLASSREF, maki_addDlfClassRef);
+ VCB(API_MAKI_MAKI_REMDLFREF, maki_remDlfRef);
+ CB(API_MAKI_MAKI_CALLFUNCTION, maki_callFunction);
+ CB(API_MAKI_MAKI_TRIGGEREVENT, maki_triggerEvent);
+ CB(API_MAKI_MAKI_GETSCRIPTINT, maki_getScriptInt);
+ CB(API_MAKI_MAKI_GETSCRIPTBOOLEAN, maki_getScriptBoolean);
+ CB(API_MAKI_MAKI_GETSCRIPTFLOAT, maki_getScriptFloat);
+ CB(API_MAKI_MAKI_GETSCRIPTDOUBLE, maki_getScriptDouble);
+ CB(API_MAKI_MAKI_GETSCRIPTSTRING, maki_getScriptString);
+ CB(API_MAKI_MAKI_GETSCRIPTOBJECT, maki_getScriptObject);
+ CB(API_MAKI_MAKI_UPDATEDLF, maki_updateDlf);
+ CB(API_MAKI_MAKI_INSTANTIATE, maki_instantiate);
+ VCB(API_MAKI_MAKI_DESTROY, maki_destroy);
+ CB(API_MAKI_MAKI_ENCAPSULATE, maki_encapsulate);
+ VCB(API_MAKI_MAKI_DEENCAPSULATE, maki_deencapsulate);
+ CB(API_MAKI_MAKI_GETCONTROLLER, maki_getController);
+ CB(API_MAKI_MAKI_CREATEORPHAN, maki_createOrphan);
+ VCB(API_MAKI_MAKI_KILLORPHAN, maki_killOrphan);
+ VCB(API_MAKI_MAKI_SETOBJECTATOM, maki_setObjectAtom);
+ CB(API_MAKI_MAKI_GETOBJECTATOM, maki_getObjectAtom);
+ #ifdef WASABI_COMPILE_WND
+ CB(API_MAKI_MAKI_FINDOBJECT, maki_findObject);
+ #endif
+ VCB(API_MAKI_VCPU_ADDSCRIPTOBJECT, vcpu_addScriptObject);
+ VCB(API_MAKI_VCPU_REMOVESCRIPTOBJECT, vcpu_removeScriptObject);
+ CB(API_MAKI_VCPU_GETCACHECOUNT, vcpu_getCacheCount);
+ CB(API_MAKI_VCPU_ISVALIDSCRIPTID, vcpu_isValidScriptId);
+ CB(API_MAKI_VCPU_MAPVARID, vcpu_mapVarId);
+ CB(API_MAKI_VCPU_GETUSERANCESTORID, vcpu_getUserAncestorId);
+ CB(API_MAKI_VCPU_GETNUMEVENTS, vcpu_getNumEvents);
+ CB(API_MAKI_VCPU_GETEVENT, vcpu_getEvent);
+ CB(API_MAKI_VCPU_GETCOMPLETE, vcpu_getComplete);
+ VCB(API_MAKI_VCPU_SETCOMPLETE, vcpu_setComplete);
+ VCB(API_MAKI_VCPU_RESETCOMPLETE, vcpu_resetComplete);
+ CB(API_MAKI_VCPU_GETCLASSNAME, vcpu_getClassName);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/script/api_makix.h b/Src/Wasabi/api/script/api_makix.h
new file mode 100644
index 00000000..60cf532e
--- /dev/null
+++ b/Src/Wasabi/api/script/api_makix.h
@@ -0,0 +1,81 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri Oct 01 02:49:40 1999]
+//
+// File : api_makix.h
+// Class : api_maki
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_MAKIX_H
+#define __API_MAKIX_H
+
+#include "api_maki.h"
+
+class ScriptObject;
+class ScriptObjectController;
+
+// ----------------------------------------------------------------------------
+
+class api_makiX : public api_maki {
+ protected:
+ api_makiX() {}
+ public:
+ virtual void maki_pushObject(void *o)=0;
+ virtual void maki_pushInt(int i)=0;
+ virtual void maki_pushBoolean(int b)=0;
+ virtual void maki_pushFloat(float f)=0;
+ virtual void maki_pushDouble(double d)=0;
+ virtual void maki_pushString(const wchar_t *s)=0;
+ virtual void maki_pushVoid()=0;
+ virtual void maki_pushAny(scriptVar v)=0;
+ virtual void *maki_popObject()=0;
+ virtual int maki_popInt()=0;
+ virtual bool maki_popBoolean()=false;
+ virtual float maki_popFloat()=0;
+ virtual double maki_popDouble()=0;
+ virtual const wchar_t *maki_popString()=0;
+ virtual scriptVar maki_popAny()=0;
+ virtual void maki_popDiscard()=0;
+ virtual const wchar_t *maki_getFunction(int dlfid, int *nparams, ScriptObjectController **p)=0;
+ virtual int maki_addDlfRef(ScriptObjectController *o, const wchar_t *function_name, void *host)=0;
+ virtual void maki_addDlfClassRef(ScriptObjectController *o, void *host)=0;
+ virtual void maki_remDlfRef(void *host)=0;
+ virtual scriptVar maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params)=0;
+ virtual scriptVar maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid = -1)=0;
+ virtual int maki_getScriptInt(scriptVar v)=0;
+ virtual bool maki_getScriptBoolean(scriptVar v)=false;
+ virtual float maki_getScriptFloat(scriptVar v)=0;
+ virtual double maki_getScriptDouble(scriptVar v)=0;
+ virtual const wchar_t *maki_getScriptString(scriptVar v)=0;
+ virtual ScriptObject *maki_getScriptObject(scriptVar v)=0;
+ virtual scriptVar maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount)=0;
+ virtual ScriptObject *maki_instantiate(GUID classguid)=0;
+ virtual void maki_destroy(ScriptObject *o)=0;
+ virtual void *maki_encapsulate(GUID classguid, ScriptObject *o)=0;
+ virtual void maki_deencapsulate(GUID classguid, void *o)=0;
+ virtual ScriptObjectController *maki_getController(GUID scriptclass)=0;
+ virtual int maki_createOrphan(int type)=0;
+ virtual void maki_killOrphan(int id)=0;
+ virtual void maki_setObjectAtom(const wchar_t *atomname, ScriptObject *object)=0;
+ virtual ScriptObject *maki_getObjectAtom(const wchar_t *atomname)=0;
+ #ifdef WASABI_COMPILE_WND
+ virtual ScriptObject *maki_findObject(const wchar_t *name)=0;
+ #endif
+ virtual void vcpu_addScriptObject(ScriptObject *o)=0;
+ virtual void vcpu_removeScriptObject(ScriptObject *o)=0;
+ virtual int vcpu_getCacheCount()=0;
+ virtual int vcpu_isValidScriptId(int id)=0;
+ virtual int vcpu_mapVarId(int varid, int scriptid)=0;
+ virtual int vcpu_getUserAncestorId(int varid, int scriptid)=0;
+ virtual int vcpu_getNumEvents()=0;
+ virtual int vcpu_getEvent(int event, int *dlf, int *script, int *var)=0;
+ virtual int vcpu_getComplete()=0;
+ virtual void vcpu_setComplete()=0;
+ virtual void vcpu_resetComplete()=0;
+ virtual const wchar_t *vcpu_getClassName(int vcpuid, int localclassid)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_MAKIX_H
diff --git a/Src/Wasabi/api/script/debugger/api_makidebug.cpp b/Src/Wasabi/api/script/debugger/api_makidebug.cpp
new file mode 100644
index 00000000..af819fd9
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/api_makidebug.cpp
@@ -0,0 +1,20 @@
+#include <precomp.h>
+#include "api_makidebug.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_makiDebuggerI
+START_DISPATCH;
+ VCB(API_MAKIDEBUGGER_DEBUGGER_TRACE, debugger_trace);
+ CB(API_MAKIDEBUGGER_DEBUGGER_ISACTIVE, debugger_isActive);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVIP, debugger_getVIP);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVSD, debugger_getVSD);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVCC, debugger_getVCC);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETVSP, debugger_getVSP);
+ CB(API_MAKIDEBUGGER_DEBUGGER_FILTEREVENT, debugger_filterEvent);
+ VCB(API_MAKIDEBUGGER_DEBUGGER_EVENTCOMPLETE, debugger_eventComplete);
+ CB(API_MAKIDEBUGGER_DEBUGGER_CREATEJITD, debugger_createJITD);
+ CB(API_MAKIDEBUGGER_DEBUGGER_READSTACK, debugger_readStack);
+ CB(API_MAKIDEBUGGER_DEBUGGER_GETCODEBLOCK, debugger_getCodeBlock);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/script/debugger/api_makidebug.h b/Src/Wasabi/api/script/debugger/api_makidebug.h
new file mode 100644
index 00000000..c55d130e
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/api_makidebug.h
@@ -0,0 +1,134 @@
+#ifndef __API_MAKIDEBUG_H
+#define __API_MAKIDEBUG_H
+
+/*---------------------------------------------------------
+api_makiDebugger
+ void debugger_trace();
+ int debugger_isActive();
+ int debugger_getVIP();
+ int debugger_getVSD();
+ int debugger_getVCC();
+ int debugger_getVSP();
+ int debugger_filterEvent(int vcpuid, int eventid);
+ void debugger_eventComplete();
+ MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1);
+ int debugger_readStack(int n);
+ int debugger_getCodeBlock(int vcpuid);
+---------------------------------------------------------*/
+
+#include <wasabicfg.h>
+
+#ifndef WASABI_COMPILE_SCRIPT
+#error "This module requires the script api"
+#endif
+
+#ifndef WASABI_COMPILE_MAKIDEBUG
+#error "This module requires the script debugger api"
+#endif
+
+#include <bfc/dispatch.h>
+#include <api/script/scriptvar.h>
+
+class MakiJITD;
+
+class NOVTABLE api_makiDebugger : public Dispatchable {
+ public:
+ void debugger_trace();
+ int debugger_isActive();
+ int debugger_getVIP();
+ int debugger_getVSD();
+ int debugger_getVCC();
+ int debugger_getVSP();
+ int debugger_filterEvent(int vcpuid, int eventid);
+ void debugger_eventComplete();
+ MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1);
+ scriptVar debugger_readStack(int n);
+ const char *debugger_getCodeBlock(int vcpuid);
+
+ enum {
+ API_MAKIDEBUGGER_DEBUGGER_TRACE = 0,
+ API_MAKIDEBUGGER_DEBUGGER_ISACTIVE = 10,
+ API_MAKIDEBUGGER_DEBUGGER_GETVIP = 20,
+ API_MAKIDEBUGGER_DEBUGGER_GETVSD = 30,
+ API_MAKIDEBUGGER_DEBUGGER_GETVCC = 40,
+ API_MAKIDEBUGGER_DEBUGGER_GETVSP = 50,
+ API_MAKIDEBUGGER_DEBUGGER_FILTEREVENT = 60,
+ API_MAKIDEBUGGER_DEBUGGER_EVENTCOMPLETE = 70,
+ API_MAKIDEBUGGER_DEBUGGER_CREATEJITD = 80,
+ API_MAKIDEBUGGER_DEBUGGER_READSTACK = 90,
+ API_MAKIDEBUGGER_DEBUGGER_GETCODEBLOCK = 100,
+ };
+};
+
+inline void api_makiDebugger::debugger_trace() {
+ _voidcall(API_MAKIDEBUGGER_DEBUGGER_TRACE);
+}
+
+inline int api_makiDebugger::debugger_isActive() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_ISACTIVE, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVIP() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVIP, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVSD() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVSD, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVCC() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVCC, (int)0);
+}
+
+inline int api_makiDebugger::debugger_getVSP() {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETVSP, (int)0);
+}
+
+inline int api_makiDebugger::debugger_filterEvent(int vcpuid, int eventid) {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_FILTEREVENT, (int)0, vcpuid, eventid);
+}
+
+inline void api_makiDebugger::debugger_eventComplete() {
+ _voidcall(API_MAKIDEBUGGER_DEBUGGER_EVENTCOMPLETE);
+}
+
+inline MakiJITD *api_makiDebugger::debugger_createJITD(int vcpuid, int bringitup) {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_CREATEJITD, (MakiJITD *)NULL, vcpuid, bringitup);
+}
+
+inline const char *api_makiDebugger::debugger_getCodeBlock(int vcpuid) {
+ return _call(API_MAKIDEBUGGER_DEBUGGER_GETCODEBLOCK, (const char *)NULL, vcpuid);
+}
+
+inline scriptVar api_makiDebugger::debugger_readStack(int n) {
+ scriptVar v={0,0};
+ return _call(API_MAKIDEBUGGER_DEBUGGER_READSTACK, v, n);
+}
+
+class api_makiDebuggerI : public api_makiDebugger {
+ public:
+ virtual void debugger_trace()=0;
+ virtual int debugger_isActive()=0;
+ virtual int debugger_getVIP()=0;
+ virtual int debugger_getVSD()=0;
+ virtual int debugger_getVCC()=0;
+ virtual int debugger_getVSP()=0;
+ virtual int debugger_filterEvent(int vcpuid, int eventid)=0;
+ virtual void debugger_eventComplete()=0;
+ virtual MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1)=0;
+ virtual scriptVar debugger_readStack(int n)=0;
+ virtual const char *debugger_getCodeBlock(int vcpuid)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {858E4B64-AF1E-4b64-8D27-EFFAD9F82BB4}
+static const GUID makiDebugApiServiceGuid =
+{ 0x858e4b64, 0xaf1e, 0x4b64, { 0x8d, 0x27, 0xef, 0xfa, 0xd9, 0xf8, 0x2b, 0xb4 } };
+
+extern api_makiDebugger *debugApi;
+
+#endif
+
+
diff --git a/Src/Wasabi/api/script/debugger/debugapi.cpp b/Src/Wasabi/api/script/debugger/debugapi.cpp
new file mode 100644
index 00000000..31ffc9d9
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/debugapi.cpp
@@ -0,0 +1,62 @@
+#include <precomp.h>
+#include <api/script/debugger/debugapi.h>
+#include <api/script/debugger/jitd.h>
+#include <api/script/vcpu.h>
+
+api_makiDebugger *debugApi = NULL;
+
+MakiDebuggerApi::MakiDebuggerApi()
+{
+}
+
+MakiDebuggerApi::~MakiDebuggerApi() {
+
+}
+
+void MakiDebuggerApi::debugger_trace() {
+ debugger.trace();
+}
+
+int MakiDebuggerApi::debugger_isActive() {
+ return debugger.isActive();
+}
+
+int MakiDebuggerApi::debugger_getVIP() {
+ return VCPU::VIP;
+}
+
+int MakiDebuggerApi::debugger_getVSD() {
+ return VCPU::VSD;
+}
+
+int MakiDebuggerApi::debugger_getVCC() {
+ return VCPU::VCC;
+}
+
+int MakiDebuggerApi::debugger_getVSP() {
+ return VCPU::VSP;
+}
+
+int MakiDebuggerApi::debugger_filterEvent(int vcpuid, int eventid) {
+ return debugger.filterEvent(vcpuid, eventid);
+}
+
+void MakiDebuggerApi::debugger_eventComplete() {
+ debugger.eventComplete();
+}
+
+MakiJITD *MakiDebuggerApi::debugger_createJITD(int vcpuid, int bringitup) {
+ MakiJITD *jitd = debugger.createJITD(vcpuid);
+ if (bringitup)
+ jitd->setGlobalBreakpoint(1);
+ return jitd;
+}
+
+scriptVar MakiDebuggerApi::debugger_readStack(int n) {
+ VCPUscriptVar v = VCPU::peekAt(n);
+ return v.v;
+}
+
+const char *MakiDebuggerApi::debugger_getCodeBlock(int vcpuid) {
+ return VCPU::getCodeBlock(vcpuid);
+}
diff --git a/Src/Wasabi/api/script/debugger/debugapi.h b/Src/Wasabi/api/script/debugger/debugapi.h
new file mode 100644
index 00000000..2b44fa4f
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/debugapi.h
@@ -0,0 +1,28 @@
+#ifndef __MAKIDEBUGAPI_H
+#define __MAKIDEBUGAPI_H
+
+#include <api/script/debugger/api_makidebug.h>
+#include <api/script/debugger/vcpudebug.h>
+
+class MakiDebuggerApi : public api_makiDebuggerI {
+ public:
+ MakiDebuggerApi();
+ virtual ~MakiDebuggerApi();
+
+ virtual void debugger_trace();
+ virtual int debugger_isActive();
+ virtual int debugger_getVIP();
+ virtual int debugger_getVSD();
+ virtual int debugger_getVCC();
+ virtual int debugger_getVSP();
+ virtual int debugger_filterEvent(int vcpuid, int eventid);
+ virtual void debugger_eventComplete();
+ virtual MakiJITD *debugger_createJITD(int vcpuid, int bringitup=1);
+ virtual scriptVar debugger_readStack(int n);
+ virtual const char *debugger_getCodeBlock(int vcpuid);
+
+ private:
+ VCPUDebugger debugger;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/debugger/debuggerui.cpp b/Src/Wasabi/api/script/debugger/debuggerui.cpp
new file mode 100644
index 00000000..692fdeee
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/debuggerui.cpp
@@ -0,0 +1,11 @@
+#include <precomp.h>
+#include "debuggerui.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS DebuggerUII
+START_DISPATCH;
+ CB(DEBUGGERUI_MESSAGELOOP, messageLoop);
+ VCB(DEBUGGERUI_SETJITD, setJITD);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/script/debugger/debuggerui.h b/Src/Wasabi/api/script/debugger/debuggerui.h
new file mode 100644
index 00000000..6138b417
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/debuggerui.h
@@ -0,0 +1,42 @@
+#ifndef __DEBUGGERUI_H
+#define __DEBUGGERUI_H
+
+#include <bfc/dispatch.h>
+
+class MakiJITD;
+
+/*-------------------------------------------
+DebuggerUI
+ int messageLoop();
+ void setJITD(MakiJITD *jitd);
+-------------------------------------------*/
+
+class DebuggerUI : public Dispatchable {
+ public:
+ int messageLoop();
+ void setJITD(MakiJITD *jitd);
+
+ enum {
+ DEBUGGERUI_MESSAGELOOP = 0,
+ DEBUGGERUI_SETJITD = 10,
+ };
+};
+
+inline int DebuggerUI::messageLoop() {
+ return _call(DEBUGGERUI_MESSAGELOOP, (int)0);
+}
+
+inline void DebuggerUI::setJITD(MakiJITD *jitd) {
+ _voidcall(DEBUGGERUI_SETJITD, jitd);
+}
+
+class DebuggerUII : public DebuggerUI {
+ public:
+ virtual int messageLoop()=0;
+ virtual void setJITD(MakiJITD *jitd)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/debugsymbols.cpp b/Src/Wasabi/api/script/debugger/debugsymbols.cpp
new file mode 100644
index 00000000..e3b85980
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/debugsymbols.cpp
@@ -0,0 +1,75 @@
+#include <precomp.h>
+#include "debugsymbols.h"
+#include <api/script/debugger/disasm.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/debugger/sourcecodeline.h>
+#include <api/script/vcpu.h>
+
+DebugSymbols::DebugSymbols(int _vcpuid) : disasm(_vcpuid)
+{
+ gotsymbols = 0;
+ SystemObject *so = SOM::getSystemObjectByScriptId(_vcpuid);
+ if (so != NULL)
+ binaryfilename = so->getFilename();
+
+ VCPUcodeBlock *cb = VCPU::getCodeBlockEntry(_vcpuid);
+ if (cb->debugsize != 0) {
+ gotsymbols = 1;
+ char *p = cb->debugsymbols;
+ int n = *(int *)p; p += 4;
+ while (n--) {
+ int s = *(int *)p; p += 4;
+ wchar_t *m = WMALLOC(s+1);
+ MEMCPY(m, p, s*sizeof(wchar_t));
+ m[s] = 0;
+ StringW *temp = new StringW;
+ temp->own(m);
+ //files.addItem(new String(m));
+ files.addItem(temp);
+ //FREE(m);
+ p+=s;
+ }
+ n = *(int *)p; p += 4;
+ while (n--) {
+ SourceCodeLineI *l = new SourceCodeLineI();
+ l->setPointer(*(int *)p); p += 4;
+ l->setSourceFile(files[*(int *)p]->getValue()); p += 4;
+ l->setSourceFileLine(*(int *)p); p += 4;
+ SourceCodeLineI *last = lines.getLast();
+ if (last != NULL) last->setLength(l->getPointer()-last->getPointer());
+ lines.addItem(l);
+ }
+ SourceCodeLineI *last = lines.getLast();
+ if (last != NULL) last->setLength(cb->size - last->getPointer());
+ }
+}
+
+DebugSymbols::~DebugSymbols()
+{
+ files.deleteAll();
+ lines.deleteAll();
+}
+
+int DebugSymbols::getNumLines() {
+ if (!gotsymbols) return disasm.getNumLines();
+ return lines.getNumItems();
+}
+
+int DebugSymbols::findLine(int pointer) {
+ if (!gotsymbols) return disasm.findLine(pointer);
+ int i;
+ for (i=0;i<lines.getNumItems();i++) {
+ SourceCodeLine *l = lines.enumItem(i);
+ int ip = l->getPointer();
+ int il = l->getLength();
+ if (pointer >= ip && pointer < ip+il) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+SourceCodeLine *DebugSymbols::enumLine(int n) {
+ if (!gotsymbols) return disasm.enumLine(n);
+ return lines.enumItem(n);
+}
diff --git a/Src/Wasabi/api/script/debugger/debugsymbols.h b/Src/Wasabi/api/script/debugger/debugsymbols.h
new file mode 100644
index 00000000..26c23a9c
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/debugsymbols.h
@@ -0,0 +1,38 @@
+#ifndef __DEBUGSYMBOLS_H
+#define __DEBUGSYMBOLS_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+#include "disasm.h"
+
+class SourceCodeLine;
+class SourceCodeLineI;
+class MakiDisassembler;
+
+class DebugSymbols {
+
+ public:
+
+ DebugSymbols(int vcpuid);
+ virtual ~DebugSymbols();
+
+ virtual int getNumLines();
+ virtual int findLine(int pointer);
+ virtual SourceCodeLine *enumLine(int n);
+
+ private:
+
+ PtrList<SourceCodeLineI> lines;
+ MakiDisassembler disasm;
+ StringW binaryfilename;
+ int gotsymbols;
+ PtrList<StringW> files;
+ //PtrList<MakiVariable> vars;
+};
+
+
+
+
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/disasm.cpp b/Src/Wasabi/api/script/debugger/disasm.cpp
new file mode 100644
index 00000000..7b3c17ee
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/disasm.cpp
@@ -0,0 +1,193 @@
+#include <precomp.h>
+#include <api/script/debugger/disasm.h>
+#include <api/script/opcodes.h>
+#include <api/script/vcpu.h>
+#include <api/script/debugger/sourcecodeline.h>
+// ---------------------------------------------------------------------
+
+typedef struct {
+ const wchar_t *opname;
+ unsigned __int8 opval;
+ int type;
+} opentry;
+
+opentry _optable[] = {
+ {L"nop", OPCODE_NOP, OPCODE_TYPE_VOID},
+ {L"push", OPCODE_PUSH, OPCODE_TYPE_VAR},
+ {L"popi", OPCODE_POPI, OPCODE_TYPE_VOID},
+ {L"pop", OPCODE_POP, OPCODE_TYPE_VAR},
+ {L"set ", OPCODE_SET, OPCODE_TYPE_VOID},
+ {L"retf", OPCODE_RETF, OPCODE_TYPE_VOID},
+ {L"call", OPCODE_CALLC, OPCODE_TYPE_PTR},
+ {L"call", OPCODE_CALLM, OPCODE_TYPE_DLF},
+ {L"call", OPCODE_CALLM2, OPCODE_TYPE_NDLF},
+ {L"umv", OPCODE_UMV, OPCODE_TYPE_DISCARD},
+ {L"cmpeq", OPCODE_CMPEQ, OPCODE_TYPE_VOID},
+ {L"cmpne", OPCODE_CMPNE, OPCODE_TYPE_VOID},
+ {L"cmpa", OPCODE_CMPA, OPCODE_TYPE_VOID},
+ {L"cmpae", OPCODE_CMPAE, OPCODE_TYPE_VOID},
+ {L"cmpb", OPCODE_CMPB, OPCODE_TYPE_VOID},
+ {L"cmpbe", OPCODE_CMPBE, OPCODE_TYPE_VOID},
+ {L"jiz", OPCODE_JIZ, OPCODE_TYPE_PTR},
+ {L"jnz", OPCODE_JNZ, OPCODE_TYPE_PTR},
+ {L"jmp", OPCODE_JMP, OPCODE_TYPE_PTR},
+ {L"incs", OPCODE_INCS, OPCODE_TYPE_VOID},
+ {L"decs", OPCODE_DECS, OPCODE_TYPE_VOID},
+ {L"incp", OPCODE_INCP, OPCODE_TYPE_VOID},
+ {L"decp", OPCODE_DECP, OPCODE_TYPE_VOID},
+ {L"add", OPCODE_ADD, OPCODE_TYPE_VOID},
+ {L"sub", OPCODE_SUB, OPCODE_TYPE_VOID},
+ {L"mul", OPCODE_MUL, OPCODE_TYPE_VOID},
+ {L"div", OPCODE_DIV, OPCODE_TYPE_VOID},
+ {L"mod", OPCODE_MOD, OPCODE_TYPE_VOID},
+ {L"neg", OPCODE_NEG, OPCODE_TYPE_VOID},
+ {L"shl", OPCODE_SHL, OPCODE_TYPE_VOID},
+ {L"shr", OPCODE_SHR, OPCODE_TYPE_VOID},
+ {L"bnot", OPCODE_BNOT, OPCODE_TYPE_VOID},
+ {L"bxor", OPCODE_XOR, OPCODE_TYPE_VOID},
+ {L"band", OPCODE_AND, OPCODE_TYPE_VOID},
+ {L"bor", OPCODE_OR, OPCODE_TYPE_VOID},
+ {L"not", OPCODE_NOT, OPCODE_TYPE_VOID},
+ {L"and", OPCODE_LAND, OPCODE_TYPE_VOID},
+ {L"or", OPCODE_LOR, OPCODE_TYPE_VOID},
+ {L"del", OPCODE_DELETE, OPCODE_TYPE_VOID},
+ {L"new", OPCODE_NEW, OPCODE_TYPE_CLASSID},
+ {L"cmpl", OPCODE_CMPLT, OPCODE_TYPE_VOID},
+};
+
+int MakiDisassembler::optable[256];
+int MakiDisassembler::optableready = 0;
+
+
+MakiDisassembler::MakiDisassembler(int _vcpuid) {
+ if (!optableready) {
+ MEMSET(optable, 0, sizeof(optable));
+ for (int i=0;i<sizeof(_optable)/sizeof(opentry);i++) {
+ opentry e = _optable[i];
+ optable[e.opval] = i;
+ }
+ optableready = 1;
+ }
+ vcpuid = _vcpuid;
+ disassemble();
+}
+
+MakiDisassembler::~MakiDisassembler() {
+ lines.deleteAll();
+}
+
+int MakiDisassembler::getVCPUId() {
+ return vcpuid;
+}
+
+int MakiDisassembler::getNumLines() {
+ return lines.getNumItems();
+}
+
+SourceCodeLine *MakiDisassembler::enumLine(int n) {
+ return lines.enumItem(n);
+}
+
+int MakiDisassembler::findLine(int pointer) {
+ int i;
+ for (i=0;i<lines.getNumItems();i++) {
+ SourceCodeLine *l = lines.enumItem(i);
+ int ip = l->getPointer();
+ int il = l->getLength();
+ if (pointer >= ip && pointer < ip+il) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+void MakiDisassembler::disassemble() {
+ int size;
+ const char *codeblock = VCPU::getCodeBlock(vcpuid, &size);
+ if (codeblock != NULL) {
+
+ const char *p = codeblock;
+
+ unsigned char opcode = OPCODE_NOP;
+
+ while (p < codeblock+size) {
+ const char *start_of_instruction = p;
+ opcode = *p;
+ p+=sizeof(opcode);
+
+ StringW inst;
+ int a = optable[opcode];
+ int id;
+ int size = 0;
+ inst = _optable[a].opname;
+ switch (_optable[a].type) {
+ case OPCODE_TYPE_VOID:
+ size = 1;
+ break;
+ case OPCODE_TYPE_VAR:
+ id = *(int *)p; p+=sizeof(int);
+ inst += StringPrintfW(L" var %08X", id);
+ size = 5;
+ break;
+ case OPCODE_TYPE_PTR:
+ id = *(int *)p; p+=sizeof(int);
+ inst += StringPrintfW(L" %08X", id+(p-codeblock));
+ size = 5;
+ break;
+ case OPCODE_TYPE_DLF: {
+ id = *(int *)p; p+=sizeof(int);
+ int np = *(int *)p;
+ if ((np & 0xFFFF0000) == 0xFFFF0000) {
+ p+=sizeof(int);
+ np &= 0xFFFF;
+ } else
+ np = -1;
+ int i = VCPU::dlfBase(vcpuid)+id;
+ if (i != -1) {
+ VCPUdlfEntry *e = VCPU::DLFentryTable.enumItem(i);
+ if (e != NULL) {
+ if (np != -1) inst += StringPrintfW(L"(%d)", np);
+ inst += L" ";
+ inst += e->functionName;
+ }
+ }
+ size = 5 + ((np == -1) ? 0 : 4);
+ break;
+ }
+ case OPCODE_TYPE_NDLF: {
+ id = *(int *)p; p+=sizeof(int);
+ int np = *p; p++;
+ int i = VCPU::dlfBase(vcpuid)+id;
+ if (i != -1) {
+ VCPUdlfEntry *e = VCPU::DLFentryTable.enumItem(i);
+ if (e != NULL) {
+ inst += StringPrintfW(L"(%d) ", np);
+ inst += e->functionName;
+ }
+ }
+ size = 6;
+ break;
+ }
+ case OPCODE_TYPE_CLASSID: {
+ id = *(int *)p; p+=sizeof(int);
+ const wchar_t *cn = WASABI_API_MAKI->vcpu_getClassName(vcpuid, id);
+ inst += L" ";
+ inst += cn;
+ size = 5;
+ break;
+ }
+ case OPCODE_TYPE_DISCARD:
+ id = *(int *)p; p+=sizeof(int);
+ size = 5;
+ break;
+ }
+ SourceCodeLineI *scl = new SourceCodeLineI();
+ scl->setLine(inst),
+ scl->setPointer(start_of_instruction-codeblock);
+ scl->setLength(size);
+ lines.addItem(scl);
+ }
+ }
+}
+
diff --git a/Src/Wasabi/api/script/debugger/disasm.h b/Src/Wasabi/api/script/debugger/disasm.h
new file mode 100644
index 00000000..2d8d3c71
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/disasm.h
@@ -0,0 +1,38 @@
+#ifndef __MakiDisassembler_H
+#define __MakiDisassembler_H
+
+#include <bfc/ptrlist.h>
+
+class SourceCodeLine;
+class SourceCodeLineI;
+
+enum {
+ OPCODE_TYPE_VOID = 0,
+ OPCODE_TYPE_VAR,
+ OPCODE_TYPE_PTR,
+ OPCODE_TYPE_DLF,
+ OPCODE_TYPE_NDLF,
+ OPCODE_TYPE_CLASSID,
+ OPCODE_TYPE_DISCARD,
+};
+
+class MakiDisassembler {
+ public:
+ MakiDisassembler(int vcpuid);
+ virtual ~MakiDisassembler();
+
+ int getVCPUId();
+ int getNumLines();
+ SourceCodeLine *enumLine(int n);
+ int findLine(int pointer);
+
+ private:
+ void disassemble();
+ PtrList<SourceCodeLineI> lines;
+ int vcpuid;
+ static int optable[256];
+ static int optableready;
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/jitd.cpp b/Src/Wasabi/api/script/debugger/jitd.cpp
new file mode 100644
index 00000000..62bfa731
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/jitd.cpp
@@ -0,0 +1,176 @@
+#include <precomp.h>
+#include "jitd.h"
+#include "jitdbreak.h"
+#include <api/service/svcs/svc_debuggerui.h>
+#include <api/service/svc_enum.h>
+#include <api/script/debugger/vcpudebug.h>
+#include <api/script/debugger/debuggerui.h>
+#include <api/script/debugger/sdebuggerui.h>
+#include <api/script/debugger/debugsymbols.h>
+
+MakiJITD::MakiJITD(VCPUDebugger *_debugger, int _vcpuid) {
+ vip = vsp = vsd = vcc = -1;
+ globalbreakpoint = 1; // fucko!!
+ onhold = 0;
+ debugger = _debugger;
+ vcpuid = _vcpuid;
+ uisvc = NULL;
+ ui = NULL;
+ simpleui = NULL;
+ codeblock = _debugger->getCodeBlock(vcpuid);
+ sysbp = new JITDBreakpoint(this, 0);
+ breakpoints.addItem(sysbp);
+ sysbp->setEnabled(0);
+ symbols = new DebugSymbols(_vcpuid);
+}
+
+MakiJITD::~MakiJITD() {
+ breakpoints.deleteAll();
+ if (uisvc != NULL) {
+ uisvc->destroyUI(ui);
+ WASABI_API_SVC->service_release(uisvc);
+ }
+ delete simpleui;
+ delete symbols;
+}
+
+int MakiJITD::getVIP() {
+ return vip;
+}
+
+int MakiJITD::getVCC() {
+ return vcc;
+}
+
+int MakiJITD::getVSD() {
+ return vsd;
+}
+
+int MakiJITD::getVSP() {
+ return vsp;
+}
+
+int MakiJITD::isGlobalBreakpointSet() {
+ return globalbreakpoint;
+}
+
+void MakiJITD::setGlobalBreakpoint(int s) {
+ globalbreakpoint = s;
+}
+
+int MakiJITD::getNumBreakpoints() {
+ return breakpoints.getNumItems();
+}
+
+JITDBreakpoint *MakiJITD::enumBreakpoint(int n) {
+ return breakpoints.enumItem(n);
+}
+
+JITDBreakpoint *MakiJITD::findBreakpoint(int pointer) {
+ int i;
+ for (i=0;i<breakpoints.getNumItems();i++) {
+ JITDBreakpoint *bp = breakpoints.enumItem(i);
+ if (bp->isEnabled() && bp->getPointer() == pointer)
+ return bp;
+ }
+ return NULL;
+}
+
+void MakiJITD::addBreakpoint(int pointer) {
+ breakpoints.addItem(new JITDBreakpoint(this, pointer));
+}
+
+void MakiJITD::removeBreakpoint(JITDBreakpoint *breakpoint) {
+ breakpoints.removeItem(breakpoint);
+ delete breakpoint;
+}
+
+void MakiJITD::clearAllBreakpoints() {
+ breakpoints.deleteAll();
+}
+
+int MakiJITD::getVCPUId() {
+ return vcpuid;
+}
+
+void MakiJITD::trace() {
+ vip = debugger->getVIP();
+ vsp = debugger->getVSP();
+ vsd = debugger->getVSD();
+ vcc = debugger->getVCC();
+
+ if (globalbreakpoint || findBreakpoint(vip)) {
+ enterUi();
+ }
+}
+
+int MakiJITD::isActive() {
+ return 1;
+}
+
+void MakiJITD::enterUi() {
+ createUi();
+ sysbp->setEnabled(0);
+ globalbreakpoint = 0;
+ onhold = 1;
+ int next_command = ui->messageLoop();
+ onhold = 0;
+ switch (next_command) {
+ case JITD_RETURN_STEPINTO:
+ globalbreakpoint = 1;
+ break;
+ case JITD_RETURN_STEPOUT:
+ // for now, continue
+ break;
+ case JITD_RETURN_TERMINATE:
+ // for now, continue
+ break;
+ case JITD_RETURN_CONTINUE:
+ // do nothing
+ default:
+ break;
+ }
+}
+
+void MakiJITD::createUi() {
+ if (ui != NULL) return;
+ waServiceFactory *f = WASABI_API_SVC->service_getServiceByGuid(SERVICE_DEBUGGERUI);
+ if (f != NULL) {
+ uisvc = castService<svc_debuggerUI>(f);
+ if (uisvc != NULL) {
+ ui = uisvc->createUI();
+ ui->setJITD(this);
+ }
+ } else {
+ simpleui = new SimpleDebuggerUI();
+ ui = simpleui;
+ ui->setJITD(this);
+ }
+}
+
+int MakiJITD::isOnHold() {
+ return onhold;
+}
+
+const char *MakiJITD::getCodeBlock() {
+ return codeblock;
+}
+
+void MakiJITD::setSysBreakpoint(int pointer) {
+ sysbp->setPointer(pointer);
+ sysbp->setEnabled(1);
+}
+
+int MakiJITD::getNumLines() {
+ return symbols->getNumLines();
+}
+
+SourceCodeLine *MakiJITD::enumLine(int n) {
+ return symbols->enumLine(n);
+}
+
+int MakiJITD::findLine(int pointer) {
+ return symbols->findLine(pointer);
+}
+
+
diff --git a/Src/Wasabi/api/script/debugger/jitd.h b/Src/Wasabi/api/script/debugger/jitd.h
new file mode 100644
index 00000000..6cb41f72
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/jitd.h
@@ -0,0 +1,71 @@
+#ifndef __MAKIJITD_H
+#define __MAKIJITD_H
+
+#include <bfc/ptrlist.h>
+
+class JITDBreakpoint;
+class VCPUDebugger;
+class svc_debuggerUI;
+class SimpleDebuggerUI;
+class DebuggerUI;
+class DebugSymbols;
+class SourceCodeLine;
+
+enum {
+ JITD_RETURN_STEPINTO = 0,
+ JITD_RETURN_STEPOVER = 1,
+ JITD_RETURN_STEPOUT = 2,
+ JITD_RETURN_TERMINATE = 3,
+ JITD_RETURN_CONTINUE = 4,
+};
+
+class MakiJITD { // dispatch me!
+ public:
+ MakiJITD(VCPUDebugger *debugger, int vcpuid);
+ virtual ~MakiJITD();
+
+ int getNumBreakpoints();
+ JITDBreakpoint *enumBreakpoint(int n);
+ JITDBreakpoint *findBreakpoint(int pointer);
+ void addBreakpoint(int pointer);
+ void removeBreakpoint(JITDBreakpoint *breakpoint);
+ void clearAllBreakpoints();
+ int isGlobalBreakpointSet();
+ void setGlobalBreakpoint(int s);
+ void setSysBreakpoint(int pointer); // deactivates automatically next time the debugger is activated
+ int getVCPUId();
+ void trace();
+ int isActive();
+ int isOnHold(); // 1 if running in the jitd's message loop
+
+ int getVIP();
+ int getVSD();
+ int getVCC();
+ int getVSP();
+
+ const char *getCodeBlock();
+
+ virtual int findLine(int pointer);
+ virtual int getNumLines();
+ virtual SourceCodeLine *enumLine(int n);
+
+ private:
+ void createUi();
+ void enterUi();
+
+ int vcpuid;
+ int vip, vsd, vcc, vsp;
+ int globalbreakpoint;
+
+ PtrList<JITDBreakpoint> breakpoints;
+ VCPUDebugger *debugger;
+ svc_debuggerUI *uisvc;
+ DebuggerUI *ui;
+ SimpleDebuggerUI *simpleui;
+ int onhold;
+ const char *codeblock;
+ JITDBreakpoint *sysbp;
+ DebugSymbols *symbols;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/jitdbreak.cpp b/Src/Wasabi/api/script/debugger/jitdbreak.cpp
new file mode 100644
index 00000000..4d12d3fe
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/jitdbreak.cpp
@@ -0,0 +1,27 @@
+#include "precomp.h"
+#include "jitdbreak.h"
+
+JITDBreakpoint::JITDBreakpoint(MakiJITD *_jitd, int _pointer) {
+ jitd = _jitd;
+ pointer = _pointer;
+ enabled = 1;
+}
+
+JITDBreakpoint::~JITDBreakpoint() {
+}
+
+int JITDBreakpoint::getPointer() {
+ return pointer;
+}
+
+void JITDBreakpoint::setEnabled(int e) {
+ enabled = e;
+}
+
+int JITDBreakpoint::isEnabled() {
+ return enabled;
+}
+
+void JITDBreakpoint::setPointer(int _pointer) {
+ pointer = _pointer;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/jitdbreak.h b/Src/Wasabi/api/script/debugger/jitdbreak.h
new file mode 100644
index 00000000..960e83b6
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/jitdbreak.h
@@ -0,0 +1,22 @@
+#ifndef __JITDBREAKPOINT_H
+#define __JITDBREAKPOINT_H
+
+class MakiJITD;
+
+class JITDBreakpoint {
+ public:
+ JITDBreakpoint(MakiJITD *jitd, int pointer);
+ virtual ~JITDBreakpoint();
+
+ virtual int getPointer();
+ virtual void setPointer(int pointer);
+ virtual void setEnabled(int e);
+ virtual int isEnabled();
+
+ private:
+ MakiJITD *jitd;
+ int pointer;
+ int enabled;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/debugger/sdebuggerui.cpp b/Src/Wasabi/api/script/debugger/sdebuggerui.cpp
new file mode 100644
index 00000000..c8349b05
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/sdebuggerui.cpp
@@ -0,0 +1,437 @@
+#include <precomp.h>
+#include "sdebuggerui.h"
+#include <api/script/debugger/jitd.h>
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/wndclass/editwnd.h>
+#include <api/script/objcontroller.h>
+#include <bfc/string/stringdict.h>
+#include <bfc/parse/paramparser.h>
+#include <api/wnd/notifmsg.h>
+#include <api/script/objecttable.h>
+#include <api/script/debugger/sourcecodeline.h>
+#include "../nu/AutoWide.h"
+
+#define LEFTCOLUMN 100
+#define RIGHTCOLUMN 200
+#define INPUTHEIGHT 21
+#define NCONSOLELINES 4
+#define LINEHEIGHT 14
+#define REGWIDTH 100
+
+SimpleDebuggerUI::SimpleDebuggerUI()
+{
+ leave = 0;
+ jitd = NULL;
+ edit = NULL;
+ memset(cmdbuf, 0, sizeof(cmdbuf));
+ retcode = JITD_RETURN_CONTINUE;
+}
+
+SimpleDebuggerUI::~SimpleDebuggerUI()
+{}
+
+void SimpleDebuggerUI::setJITD(MakiJITD *_jitd)
+{
+ jitd = _jitd;
+}
+
+int SimpleDebuggerUI::messageLoop()
+{
+ leave = 0;
+ retcode = JITD_RETURN_STEPINTO;
+
+ if (!isInited())
+ {
+ setVirtual(0);
+ setStartHidden(1);
+ setParent(WASABI_API_WND->main_getRootWnd());
+ init(WASABI_API_WND->main_getRootWnd(), 1);
+
+ edit = new EditWnd;
+ edit->setParent(this);
+ edit->setBackgroundColor(RGB(0, 0, 0));
+ edit->setTextColor(RGB(0, 255, 0));
+ edit->setWantFocus(0);
+
+ *cmdbuf = 0;
+ edit->setBuffer(cmdbuf, 256);
+ edit->init(this);
+
+ RECT r;
+ POINT pt = {0, 0};
+ Wasabi::Std::getViewport(&r, &pt);
+ resize(r.right - 656, r.top + 16, 640, 480);
+ bringToFront();
+ }
+
+ for (int s = 0;s < jitd->getVSP();s++)
+ {
+ scriptVar v = WASABI_API_MAKIDEBUG->debugger_readStack(s);
+ StringW str;
+ switch (v.type)
+ {
+ case SCRIPT_VOID:
+ str = L"NULL";
+ break;
+ case SCRIPT_INT:
+ str = StringPrintfW(L"%d", GET_SCRIPT_INT(v));
+ break;
+ case SCRIPT_BOOLEAN:
+ str = StringPrintfW(L"%s", GET_SCRIPT_BOOLEAN(v) ? L"true" : L"false");
+ break;
+ case SCRIPT_FLOAT:
+ str = StringPrintfW(L"%f", GET_SCRIPT_FLOAT(v));
+ break;
+ case SCRIPT_DOUBLE:
+ str = StringPrintfW(L"%f", (float)GET_SCRIPT_DOUBLE(v));
+ break;
+ case SCRIPT_STRING:
+ str = GET_SCRIPT_STRING(v);
+ break;
+ default:
+ {
+ if (v.type == SCRIPT_OBJECT)
+ str = L"Object";
+ else
+ str = ObjectTable::getClassName(v.type);
+#ifdef WASABI_COMPILE_SKIN
+ ScriptObject *o = GET_SCRIPT_OBJECT(v);
+ if (o != NULL)
+ {
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go != NULL)
+ {
+ str += L";";
+ str.cat(go->guiobject_getId());
+ }
+ }
+#endif
+ break;
+ }
+ }
+ strstack.addItem(new StringW(str));
+ }
+
+ setVisible(1);
+
+ //WASABI_API_WND->pushModalWnd(this);
+
+#ifdef WIN32
+ MSG msg;
+ //DWORD leavetime = GetTickCount()+5;
+ while (!leave/* && !(GetTickCount() >leavetime)*/)
+ {
+ if (PeekMessage(&msg, /*(HWND)NULL*/ getOsWindowHandle(), 0, 0, PM_NOREMOVE))
+ {
+ GetMessage(&msg, /*(HWND) NULL*/getOsWindowHandle(), 0, 0) &&
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+#endif
+
+ //WASABI_API_WND->popModalWnd(this);
+
+ setVisible(0);
+ strstack.deleteAll();
+
+ return retcode;
+}
+
+int SimpleDebuggerUI::onPaint(Canvas *c)
+{
+ SimpleDebuggerUI_PARENT::onPaint(c);
+ Wasabi::FontInfo fontInfo;
+ RECT r;
+ getClientRect(&r);
+ c->fillRect(&r, RGB(0, 0, 0));
+ c->drawRect(&r, 1, RGB(0, 255, 0));
+
+ fontInfo.color = RGB(0, 255, 0);
+ fontInfo.pointSize = 14;
+ fontInfo.face = L"Courier New";
+ c->pushPen(PENSTYLE_SOLID, 1, RGB(0, 255, 0));
+ c->textOut(r.right - REGWIDTH + 7, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2) + 8, StringPrintfW(L"VSD:%08X", jitd->getVSD()), &fontInfo);
+ c->textOut(r.right - REGWIDTH + 7, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2) + 8 + (LINEHEIGHT + 1), StringPrintfW(L"VIP:%08X", jitd->getVIP()), &fontInfo);
+ c->textOut(r.right - REGWIDTH + 7, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2) + 8 + (LINEHEIGHT + 1)*2, StringPrintfW(L"VSP:%08X", jitd->getVSP()), &fontInfo);
+ c->textOut(r.right - REGWIDTH + 7, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2) + 8 + (LINEHEIGHT + 1)*3, StringPrintfW(L"VCC:%08X", jitd->getVCC()), &fontInfo);
+ c->lineDraw(r.left, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2), r.right, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2));
+ c->lineDraw(r.left, r.bottom - (INPUTHEIGHT + 2), r.right - REGWIDTH, r.bottom - (INPUTHEIGHT + 2));
+ c->lineDraw(r.right - REGWIDTH, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2), r.right - REGWIDTH, r.bottom);
+ c->lineDraw(r.right - RIGHTCOLUMN, 0, r.right - RIGHTCOLUMN, r.bottom - (INPUTHEIGHT + (NCONSOLELINES*LINEHEIGHT) + 2));
+ disassemble(c);
+ for (int s = 0;s < strstack.getNumItems();s++)
+ {
+ c->textOutEllipsed(r.right - RIGHTCOLUMN + 4, s*LINEHEIGHT + 4, RIGHTCOLUMN - 8, 16, strstack.enumItem(s)->getValue(), &fontInfo);
+ }
+ return 1;
+}
+
+int SimpleDebuggerUI::onLeftButtonDown(int x, int y)
+{
+ SimpleDebuggerUI_PARENT::onLeftButtonDown(x, y);
+ if (edit) edit->onGetFocus();
+// leave = 1;
+ return 1;
+}
+
+void SimpleDebuggerUI::disassemble(Canvas *c)
+{
+ RECT r;
+ getClientRect(&r);
+ int x = 4;
+
+ int y = (r.bottom - r.top - 4) / 2 + 4;
+
+ int ln = jitd->findLine(jitd->getVIP());
+ if (ln != -1)
+ {
+ Wasabi::FontInfo fontInfo;
+ SourceCodeLine *l = jitd->enumLine(ln);
+ int sourcecode = l->getSourceFile() != NULL;
+ int g;
+ int j = 0;
+ for (g = y;g < r.bottom - (INPUTHEIGHT + 4 + (NCONSOLELINES*LINEHEIGHT)) - LINEHEIGHT;g += LINEHEIGHT)
+ {
+ if (!sourcecode || j == 0)
+ l = jitd->enumLine(ln + j);
+ if (!l) break;
+
+ if (j == 0)
+ {
+ RECT br;
+ br.left = 4;
+ br.top = g;
+ br.right = r.right - (RIGHTCOLUMN + 4);
+ br.bottom = br.top + LINEHEIGHT;
+ c->fillRect(&br, RGB(0, 255, 0));
+ fontInfo.color = RGB(0, 0, 0);
+ }
+ if (!sourcecode)
+ {
+ String str;
+ unsigned const char *d = (unsigned const char *)(l->getPointer() + jitd->getCodeBlock());
+ for (int k = 0;k < l->getLength();k++)
+ {
+ if (!str.isempty()) str += " ";
+ str += StringPrintf("%02X", *d);
+ d++;
+ }
+ c->textOut(x, g, StringPrintfW(L"%08X", l->getPointer()), &fontInfo);
+ c->textOut(x + 70, g, AutoWide(str), &fontInfo);
+ c->textOut(x + 70 + 150, g, l->getLine(), &fontInfo);
+ }
+ else
+ {
+ c->textOutEllipsed(x, g, r.right - r.left - (RIGHTCOLUMN + 4 + x), 16, (getLine(l->getSourceFile(), l->getSourceFileLine() + j)), &fontInfo);
+ }
+
+ j++;
+ }
+ j = 1;
+ for (g = y - LINEHEIGHT;g > 1;g -= LINEHEIGHT)
+ {
+ if (!sourcecode || j == 0)
+ l = jitd->enumLine(ln - j);
+ if (!l) break;
+ if (!sourcecode)
+ {
+ String str;
+ unsigned const char *d = (unsigned const char *)(l->getPointer() + jitd->getCodeBlock());
+ for (int k = 0;k < l->getLength();k++)
+ {
+ if (!str.isempty()) str += " ";
+ str += StringPrintf("%02X", *d);
+ d++;
+ }
+ c->textOut(x, g, StringPrintfW(L"%08X", l->getPointer()), &fontInfo);
+ c->textOut(x + 70, g, AutoWide(str), &fontInfo);
+ c->textOut(x + 70 + 150, g, (l->getLine()), &fontInfo);
+ }
+ else
+ {
+ c->textOutEllipsed(x, g, r.right - r.left - (RIGHTCOLUMN + 4 + x), 16, (getLine(l->getSourceFile(), l->getSourceFileLine() - j)), &fontInfo);
+ }
+ j++;
+ }
+ }
+}
+
+int SimpleDebuggerUI::onResize()
+{
+ SimpleDebuggerUI_PARENT::onResize();
+ if (edit != NULL)
+ {
+ RECT r;
+ getClientRect(&r);
+ edit->resize(1, r.bottom - (INPUTHEIGHT + 1), r.right - r.left - (REGWIDTH + 1), INPUTHEIGHT);
+ }
+ return 1;
+}
+
+int SimpleDebuggerUI::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)
+{
+ if (child == edit)
+ {
+ if (msg == ChildNotify::EDITWND_ENTER_PRESSED)
+ {
+ onCommand(cmdbuf);
+ }
+ }
+ return SimpleDebuggerUI_PARENT::childNotify(child, msg, p1, p2);
+}
+
+BEGIN_STRINGDICTIONARY(_debuggercommands)
+SDI(L"b", DEBUG_CMD_BREAKPOINT);
+SDI(L"break", DEBUG_CMD_BREAKPOINT);
+SDI(L"x", DEBUG_CMD_CONTINUE);
+SDI(L"continue", DEBUG_CMD_CONTINUE);
+SDI(L"i", DEBUG_CMD_STEPINTO);
+SDI(L"stepinto", DEBUG_CMD_STEPINTO);
+SDI(L"o", DEBUG_CMD_STEPOVER);
+SDI(L"stepover", DEBUG_CMD_STEPOVER);
+SDI(L"p", DEBUG_CMD_STEPOUT);
+SDI(L"stepout", DEBUG_CMD_STEPOUT);
+SDI(L"k", DEBUG_CMD_KILL);
+SDI(L"kill", DEBUG_CMD_KILL);
+SDI(L"?", DEBUG_CMD_HELP);
+SDI(L"help", DEBUG_CMD_HELP);
+END_STRINGDICTIONARY(_debuggercommands, debuggercommands)
+
+
+void SimpleDebuggerUI::onCommand(const wchar_t *cmd)
+{
+ if (*cmd == 0)
+ {
+ stepOver();
+ return;
+ }
+ ParamParser pp(cmd, L" ");
+ int i = debuggercommands.getId(pp.enumItem(0));
+ switch (i)
+ {
+ case DEBUG_CMD_BREAKPOINT:
+ addBreakPoint(pp.enumItem(1));
+ break;
+ case DEBUG_CMD_CONTINUE:
+ continueExecution();
+ break;
+ case DEBUG_CMD_STEPINTO:
+ stepInto();
+ break;
+ case DEBUG_CMD_STEPOVER:
+ stepOver();
+ break;
+ case DEBUG_CMD_KILL:
+ killScript();
+ break;
+ case DEBUG_CMD_HELP:
+ showHelp();
+ break;
+ }
+}
+
+int SimpleDebuggerUI::evaluate(const wchar_t *ascii)
+{
+ if (!_wcsicmp(ascii, L"VSD")) return jitd->getVSD();
+ if (!_wcsicmp(ascii, L"VIP")) return jitd->getVIP();
+ if (!_wcsicmp(ascii, L"VSP")) return jitd->getVSP();
+ if (!_wcsicmp(ascii, L"VCC")) return jitd->getVCC();
+ wchar_t *end;
+ return wcstol(ascii, &end, 16);
+}
+
+void SimpleDebuggerUI::addBreakPoint(const wchar_t *pointer_ascii)
+{
+ /*int i = */evaluate(pointer_ascii);
+}
+
+void SimpleDebuggerUI::continueExecution()
+{
+ retcode = JITD_RETURN_CONTINUE;
+ leave = 1;
+}
+
+void SimpleDebuggerUI::stepInto()
+{
+ retcode = JITD_RETURN_STEPINTO;
+ leave = 1;
+}
+
+void SimpleDebuggerUI::stepOver()
+{
+ int ln = jitd->findLine(jitd->getVIP());
+ ln++;
+ SourceCodeLine *l = jitd->enumLine(ln);
+
+ if (l != NULL) // else ret as last opcode
+ jitd->setSysBreakpoint(l->getPointer());
+
+ retcode = JITD_RETURN_CONTINUE;
+ leave = 1;
+}
+
+void SimpleDebuggerUI::killScript()
+{
+ retcode = JITD_RETURN_TERMINATE;
+ leave = 1;
+}
+
+void SimpleDebuggerUI::showHelp()
+{}
+
+int SimpleDebuggerUI::onGetFocus()
+{
+ SimpleDebuggerUI_PARENT::onGetFocus();
+ if (edit) edit->onGetFocus();
+ return 1;
+}
+
+void SimpleDebuggerUI::onSetVisible(int show)
+{
+ SimpleDebuggerUI_PARENT::onSetVisible(show);
+ if (edit) edit->onGetFocus();
+}
+#undef fgets
+const wchar_t *SimpleDebuggerUI::getLine(const wchar_t *filename, int fileline)
+{
+ if (fileline <= 0)
+ return L"";
+ static StringW str;
+ FILE *f = _wfopen(filename, L"rt");
+ if (!f)
+ {
+ str = L"couldn't load ";
+ str += filename;
+ return str;
+ }
+
+ char t[256] = {0};
+ char u[256] = {0};
+ int n = fileline;
+ while (n--)
+ {
+ *u = 0;
+ char *p;
+ do
+ {
+ p = *u ? t : u;
+ fgets(p, 255, f);
+ t[255] = 0;
+ }
+ while (!feof(f) && p[STRLEN(p)-1] != '\n' && p[STRLEN(p)-1] != '\r');
+ }
+
+ char *p = u;
+ while (p && *p && p < u + 256)
+ {
+ if (*p < 0x21) *p = ' ';
+ p++;
+ }
+
+ str = AutoWide(u, CP_UTF8);
+ fclose(f);
+
+ return str;
+}
+
diff --git a/Src/Wasabi/api/script/debugger/sdebuggerui.h b/Src/Wasabi/api/script/debugger/sdebuggerui.h
new file mode 100644
index 00000000..39f73ee5
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/sdebuggerui.h
@@ -0,0 +1,65 @@
+#ifndef __SIMPLEDEBUGGERUI_H
+#define __SIMPLEDEBUGGERUI_H
+
+#include "debuggerui.h"
+#include <api/wnd/wndclass/clickwnd.h>
+
+class MakiDisassembler;
+class EditWnd;
+class String;
+class SourceCodeLine;
+
+#define SimpleDebuggerUI_PARENT ClickWnd
+
+enum {
+ DEBUG_CMD_BREAKPOINT = 0,
+ DEBUG_CMD_CONTINUE,
+ DEBUG_CMD_STEPINTO,
+ DEBUG_CMD_STEPOVER,
+ DEBUG_CMD_STEPOUT,
+ DEBUG_CMD_KILL,
+ DEBUG_CMD_HELP,
+};
+
+
+class MakiJITD;
+
+class SimpleDebuggerUI : public SimpleDebuggerUI_PARENT, public DebuggerUII {
+ public:
+ SimpleDebuggerUI();
+ virtual ~SimpleDebuggerUI();
+
+ virtual int onPaint(Canvas *c);
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onResize();
+ virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2);
+ virtual void onSetVisible(int show);
+
+ virtual int messageLoop();
+ virtual void setJITD(MakiJITD *jitd);
+
+ virtual void disassemble(Canvas *c);
+ virtual void onCommand(const wchar_t *cmd);
+
+ virtual void addBreakPoint(const wchar_t *pointer_ascii);
+ virtual void continueExecution();
+ virtual void stepInto();
+ virtual void stepOver();
+ virtual void killScript();
+ virtual void showHelp();
+ virtual int onGetFocus();
+
+ virtual int evaluate(const wchar_t *ascii);
+ virtual const wchar_t *getLine(const wchar_t *filename, int fileline);
+
+ private:
+
+ int leave;
+ MakiJITD *jitd;
+ EditWnd *edit;
+ wchar_t cmdbuf[256];
+ int retcode;
+ PtrList<StringW> strstack;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/sourcecodeline.cpp b/Src/Wasabi/api/script/debugger/sourcecodeline.cpp
new file mode 100644
index 00000000..b6511c2b
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/sourcecodeline.cpp
@@ -0,0 +1,69 @@
+#include <precomp.h>
+#include "sourcecodeline.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS SourceCodeLineI
+START_DISPATCH;
+ CB(SOURCECODELINE_GETLINE, getLine);
+ VCB(SOURCECODELINE_SETLINE, setLine);
+ CB(SOURCECODELINE_GETPOINTER, getPointer);
+ VCB(SOURCECODELINE_SETPOINTER, setPointer);
+ CB(SOURCECODELINE_GETLENGTH, getLength);
+ VCB(SOURCECODELINE_SETLENGTH, setLength);
+ VCB(SOURCECODELINE_SETSOURCEFILE, setSourceFile);
+ CB(SOURCECODELINE_GETSOURCEFILE, getSourceFile);
+ VCB(SOURCECODELINE_SETSOURCEFILELINE, setSourceFileLine);
+ CB(SOURCECODELINE_GETSOURCEFILELINE, getSourceFileLine);
+END_DISPATCH;
+
+SourceCodeLineI::SourceCodeLineI() {
+ pointer = -1;
+ fileline = -1;
+ length = 0;
+}
+
+SourceCodeLineI::~SourceCodeLineI() {
+}
+
+const wchar_t *SourceCodeLineI::getLine()
+{
+ return line;
+}
+
+void SourceCodeLineI::setLine(const wchar_t *_line) {
+ line = _line;
+}
+
+int SourceCodeLineI::getPointer() {
+ return pointer;
+}
+
+void SourceCodeLineI::setPointer(int _pointer) {
+ pointer = _pointer;
+}
+
+int SourceCodeLineI::getLength() {
+ return length;
+}
+
+void SourceCodeLineI::setLength(int _length) {
+ length = _length;
+}
+
+void SourceCodeLineI::setSourceFile(const wchar_t *_file) {
+ file = _file;
+}
+
+const wchar_t *SourceCodeLineI::getSourceFile() {
+ return file;
+}
+
+void SourceCodeLineI::setSourceFileLine(int _linenumber) {
+ fileline = _linenumber;
+}
+
+int SourceCodeLineI::getSourceFileLine() {
+ return fileline;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/sourcecodeline.h b/Src/Wasabi/api/script/debugger/sourcecodeline.h
new file mode 100644
index 00000000..a3a341ac
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/sourcecodeline.h
@@ -0,0 +1,100 @@
+#ifndef __SOURCECODELINE_H
+#define __SOURCECODELINE_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/StringW.h>
+
+
+class SourceCodeLine : public Dispatchable {
+ public:
+ const wchar_t *getLine();
+ void setLine(const wchar_t *line);
+ int getPointer();
+ void setPointer(int pointer);
+ int getLength();
+ void setLength(int length);
+ void setSourceFile(const wchar_t *file);
+ const wchar_t *getSourceFile();
+ void setSourceFileLine(int linenumber);
+ int getSourceFileLine();
+
+ enum {
+ SOURCECODELINE_GETLINE = 0,
+ SOURCECODELINE_SETLINE = 10,
+ SOURCECODELINE_GETPOINTER = 20,
+ SOURCECODELINE_SETPOINTER = 30,
+ SOURCECODELINE_GETLENGTH = 40,
+ SOURCECODELINE_SETLENGTH = 50,
+ SOURCECODELINE_SETSOURCEFILE = 60,
+ SOURCECODELINE_GETSOURCEFILE = 70,
+ SOURCECODELINE_SETSOURCEFILELINE = 80,
+ SOURCECODELINE_GETSOURCEFILELINE = 90,
+ };
+};
+
+inline const wchar_t *SourceCodeLine::getLine() {
+ return _call(SOURCECODELINE_GETLINE, (const wchar_t*)NULL);
+}
+
+inline void SourceCodeLine::setLine(const wchar_t *line) {
+ _voidcall(SOURCECODELINE_SETLINE, line);
+}
+
+inline int SourceCodeLine::getPointer() {
+ return _call(SOURCECODELINE_GETPOINTER, (int)0);
+}
+
+inline void SourceCodeLine::setPointer(int pointer) {
+ _voidcall(SOURCECODELINE_SETPOINTER, pointer);
+}
+
+inline int SourceCodeLine::getLength() {
+ return _call(SOURCECODELINE_GETLENGTH, (int)0);
+}
+
+inline void SourceCodeLine::setLength(int length) {
+ _voidcall(SOURCECODELINE_SETLENGTH, length);
+}
+
+inline void SourceCodeLine::setSourceFile(const wchar_t *file) {
+ _voidcall(SOURCECODELINE_SETSOURCEFILE, file);
+}
+
+inline const wchar_t *SourceCodeLine::getSourceFile() {
+ return _call(SOURCECODELINE_GETSOURCEFILE, (const wchar_t *)0);
+}
+
+inline void SourceCodeLine::setSourceFileLine(int linenumber) {
+ _voidcall(SOURCECODELINE_SETSOURCEFILELINE, linenumber);
+}
+
+inline int SourceCodeLine::getSourceFileLine() {
+ return _call(SOURCECODELINE_GETSOURCEFILELINE, (int)0);
+}
+
+class SourceCodeLineI : public SourceCodeLine {
+ public:
+ SourceCodeLineI();
+ virtual ~SourceCodeLineI();
+ virtual const wchar_t *getLine();
+ virtual void setLine(const wchar_t *line);
+ virtual int getPointer();
+ virtual void setPointer(int pointer);
+ virtual int getLength();
+ virtual void setLength(int length);
+ virtual void setSourceFile(const wchar_t *file);
+ virtual const wchar_t *getSourceFile();
+ virtual void setSourceFileLine(int linenumber);
+ virtual int getSourceFileLine();
+
+ protected:
+ RECVS_DISPATCH;
+
+ StringW line;
+ StringW file;
+ int fileline;
+ int pointer;
+ int length;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/debugger/vcpudebug.cpp b/Src/Wasabi/api/script/debugger/vcpudebug.cpp
new file mode 100644
index 00000000..94087956
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/vcpudebug.cpp
@@ -0,0 +1,99 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "vcpudebug.h"
+#include <api/script/debugger/jitd.h>
+
+VCPUDebugger::VCPUDebugger() {
+ filter.setFilterObject(&reentryfilter);
+}
+
+VCPUDebugger::~VCPUDebugger() {
+}
+
+// ------------------------------------------------------------------------
+
+// instruction pointer
+int VCPUDebugger::getVIP() {
+ return WASABI_API_MAKIDEBUG->debugger_getVIP();
+}
+
+// script descriptor (vcpuid)
+int VCPUDebugger::getVSD() {
+ return WASABI_API_MAKIDEBUG->debugger_getVSD();
+}
+
+// variables stack pointer
+int VCPUDebugger::getVSP() {
+ return WASABI_API_MAKIDEBUG->debugger_getVSP();
+}
+
+// call stack pointer
+int VCPUDebugger::getVCC() {
+ return WASABI_API_MAKIDEBUG->debugger_getVCC();
+}
+
+// ------------------------------------------------------------------------
+void VCPUDebugger::trace() {
+ int i;
+ for (i=0;i<jitds.getNumItems();i++) {
+ MakiJITD *jitd = jitds.enumItem(i);
+ if (jitd->getVCPUId() == getVSD()) {
+ jitd->trace();
+ }
+ }
+}
+
+MakiJITD *VCPUDebugger::getJITD(int vcpuid) {
+ int i;
+ for (i=0;i<jitds.getNumItems();i++) {
+ MakiJITD *jitd = jitds.enumItem(i);
+ if (jitd->getVCPUId() == vcpuid)
+ return jitd;
+ }
+ return NULL;
+}
+
+// if this returns 1, you should not call eventComplete!
+int VCPUDebugger::filterEvent(int vcpuid, int eventid) {
+ MakiJITD *jitd = getJITD(vcpuid);
+ if (!jitd || !jitd->isOnHold()) {
+ WASABI_API_WND->pushModalWnd();
+ scopestack.push(0);
+ return 0;
+ }
+ filter.enterScope((vcpuid<<16) + eventid); // (vcpuid<<16) + eventid
+ if (filter.mustLeave()) {
+ filter.leaveScope();
+ return 1;
+ }
+ WASABI_API_WND->pushModalWnd();
+ scopestack.push(1);
+ return 0;
+}
+
+void VCPUDebugger::eventComplete() {
+ int n;
+ scopestack.pop(&n);
+ WASABI_API_WND->popModalWnd();
+ if (n) {
+ filter.leaveScope();
+ }
+}
+
+int VCPUDebugger::isActive() {
+ foreach(jitds)
+ if (jitds.getfor()->isActive())
+ return 1;
+ endfor;
+ return 0;
+}
+
+MakiJITD *VCPUDebugger::createJITD(int vcpuid) {
+ MakiJITD *jitd = new MakiJITD(this, vcpuid);
+ jitds.addItem(jitd);
+ return jitd;
+}
+
+const char *VCPUDebugger::getCodeBlock(int vcpuid) {
+ return WASABI_API_MAKIDEBUG->debugger_getCodeBlock(vcpuid);
+}
diff --git a/Src/Wasabi/api/script/debugger/vcpudebug.h b/Src/Wasabi/api/script/debugger/vcpudebug.h
new file mode 100644
index 00000000..6bba084b
--- /dev/null
+++ b/Src/Wasabi/api/script/debugger/vcpudebug.h
@@ -0,0 +1,39 @@
+#ifndef __VCPUDEBUG_H
+#define __VCPUDEBUG_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/stack.h>
+#include <bfc/reentryfilter.h>
+
+class MakiJITD;
+
+class VCPUDebugger {
+ public:
+ VCPUDebugger();
+ virtual ~VCPUDebugger();
+
+ void trace();
+
+ int getVIP(); // instruction pointer
+ int getVSD(); // script descriptor (id)
+ int getVSP(); // variables stack pointer
+ int getVCC(); // call stack pointer
+
+ int filterEvent(int vcpuid, int eventid); // if this returns 1, you should return immediatly and not call eventComplete!
+ void eventComplete();
+
+ int isActive();
+
+ MakiJITD *createJITD(int vcpuid);
+ MakiJITD *getJITD(int vcpuid);
+ const char *getCodeBlock(int vcpuid);
+
+ private:
+
+ PtrList<MakiJITD> jitds;
+ ReentryFilterObject reentryfilter;
+ ReentryFilter filter;
+ Stack<int> scopestack;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/guru.cpp b/Src/Wasabi/api/script/guru.cpp
new file mode 100644
index 00000000..b245dd50
--- /dev/null
+++ b/Src/Wasabi/api/script/guru.cpp
@@ -0,0 +1,216 @@
+#include <precomp.h>
+#include <api.h>
+#ifdef WASABI_COMPILE_WND
+#include <api/wnd/basewnd.h>
+#include <tataki/canvas/bltcanvas.h>
+#endif
+#include <api/script/guru.h>
+#include <api/script/script.h>
+#include <api/script/vcpu.h>
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/skin.h>
+#endif
+
+extern HINSTANCE hInstance;
+#ifdef WASABI_COMPILE_WND
+Guru::Guru()
+{
+ fcount = 0;
+ txt=NULL;
+ code=0;
+ intinfo=0;
+}
+
+Guru::~Guru() {
+}
+#endif
+
+void Guru::spawn(SystemObject *_script, int code, const wchar_t *pub, int intinfo) {
+#ifdef WASABI_COMPILE_WND
+ script = _script;
+ if (WASABI_API_PALETTE->getSkinPartIterator() > last_iterator) {
+ mustquit = 0;
+ last_iterator = WASABI_API_PALETTE->getSkinPartIterator();
+ }
+ else
+ return;
+
+#ifdef WASABI_COMPILE_SKIN
+ int oldlock = WASABI_API_SKIN->skin_getLockUI();
+ WASABI_API_SKIN->skin_setLockUI(0);
+#endif
+
+ Guru g;
+ g.setCode(code);
+ g.setPublicTxt(pub);
+ g.setIntInfo(intinfo);
+ g.setStartHidden(1);
+ g.init(hInstance, INVALIDOSWINDOWHANDLE, TRUE);
+
+ RECT r;
+ Wasabi::Std::getViewport(&r, (POINT*)NULL);
+
+ r.left = r.left + ((r.right-r.left-640)/2);
+ r.right = r.left + 640;
+ TextInfoCanvas c(&g);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = WASABI_API_APP->getScaleY(14);
+
+#ifdef WIN32
+ fontInfo.face = L"Lucida Console";
+#else
+ fontInfo.face = L"Lucida";
+#endif
+ fontInfo.bold = true;
+
+ r.bottom = r.top + c.getTextHeight(&fontInfo)* (script != NULL ? 9 : 7);
+
+ g.resize(&r);
+ g.setVisible(1);
+ g.bringToFront();
+
+ MSG msg = {0};
+ WASABI_API_WND->pushModalWnd(&g);
+#ifdef WIN32
+ HWND old = SetCapture(g.gethWnd());
+#endif
+ while (!mustquit) {
+ mustquit = !GetMessage(&msg, g.gethWnd(), 0, 0);
+#ifdef WIN32
+ if (!msg.hwnd || !TranslateAccelerator(msg.hwnd, NULL, &msg)) {
+#endif
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+#ifdef WIN32
+ }
+#endif
+ }
+
+ WASABI_API_WND->popModalWnd(&g);
+#ifdef WIN32
+ SetCapture(old);
+#endif
+
+#else
+ StringPrintfW t(L"Guru Meditation #%04X.%04X%04X.%d%s%s", code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF, VCPU::VSD, pub?" ":"", pub?pub:"");
+ Std::messageBox(t, L"Guru Meditiation", 16);
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+ WASABI_API_SKIN->skin_setLockUI(oldlock);
+#endif
+}
+
+#ifdef WASABI_COMPILE_WND
+
+int Guru::onPaint(Canvas *canvas) {
+
+ GURU_PARENT::onPaint(canvas);
+
+ PaintBltCanvas paintcanvas;
+ if (canvas == NULL) {
+ paintcanvas.beginPaint(this);
+ canvas = &paintcanvas;
+ }
+
+ RECT r;
+ getClientRect(&r);
+
+ canvas->fillRect(&r, 0);
+
+ if (fcount%2==0)
+ {
+ int w;
+ Wasabi::FontInfo fontInfo;
+ fontInfo.color = RGB(0xFF,0,0);
+ fontInfo.pointSize = WASABI_API_APP->getScaleY(14);
+
+#ifdef WIN32
+ fontInfo.face = L"Lucida Console";
+#else
+ fontInfo.face = L"Lucida";
+#endif
+ fontInfo.bold = true;
+ fontInfo.opaque = false;
+ w = canvas->getTextHeight(&fontInfo);
+ RECT s = {40, w*2, 560, w*3};
+ canvas->textOutCentered(&s, L"Winamp Script Failure. Press the left mouse button to continue.", &fontInfo);
+ StringPrintfW t(L"Guru Meditation #%04X.%04X%04X.%d%s%s", code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF, VCPU::VSD, txt?L" ":L"", txt?txt:L"");
+ s.top=w*4;
+ s.bottom=s.top+w;
+ canvas->textOutCentered(&s, t, &fontInfo);
+
+ if (script != NULL) {
+ s.top=w*6;
+ s.bottom=s.top+w;
+ canvas->textOutCentered(&s, script->getFilename(), &fontInfo);
+ }
+
+ RECT z;
+ z.top = r.top + 5;
+ z.bottom = r.top + min(10, w-2);
+ z.left = r.left + 5;
+ z.right = r.right - 5;
+ canvas->fillRect(&z, RGB(0xFF,0,0));
+
+ z.top = r.top + 5;
+ z.bottom = r.bottom - 5;;
+ z.left = r.right - min(10, w-2);
+ z.right = r.right - 5;
+ canvas->fillRect(&z, RGB(0xFF,0,0));
+
+ z.top = r.bottom - min(10, w-2);
+ z.bottom = r.bottom - 5;
+ z.left = r.left + 5;
+ z.right = r.right - 5;
+ canvas->fillRect(&z, RGB(0xFF,0,0));
+
+ z.top = r.top + 5;
+ z.bottom = r.bottom - 5;;
+ z.left = r.left + 5;
+ z.right = r.left + min(10, w-2);
+ canvas->fillRect(&z, RGB(0xFF,0,0));
+ }
+
+ return 1;
+}
+
+int Guru::onLeftButtonUp(int x, int y) {
+ mustquit=1;
+ return GURU_PARENT::onLeftButtonUp(x,y);
+}
+
+int Guru::onInit() {
+ GURU_PARENT::onInit();
+ setTimer(GURU_TIMERID, 400);
+ return 1;
+}
+
+void Guru::setCode(int c) {
+ code = c;
+}
+
+void Guru::setPublicTxt(const wchar_t *t) {
+ txt = t;
+}
+
+void Guru::setIntInfo(int info) {
+ intinfo = info;
+}
+
+void Guru::timerCallback(int id) {
+ if (id == GURU_TIMERID) {
+ fcount++;
+ if (fcount > 7) {
+ killTimer(GURU_TIMERID);
+ }
+ invalidate();
+ return;
+ }
+ GURU_PARENT::timerCallback(id);
+}
+
+int Guru::mustquit = 0;
+int Guru::last_iterator = -1;
+SystemObject * Guru::script = NULL;
+#endif
diff --git a/Src/Wasabi/api/script/guru.h b/Src/Wasabi/api/script/guru.h
new file mode 100644
index 00000000..2af5e5b2
--- /dev/null
+++ b/Src/Wasabi/api/script/guru.h
@@ -0,0 +1,51 @@
+//PORTABLE
+#ifndef _GURU_H
+#define _GURU_H
+
+#include <api/wnd/basewnd.h>
+
+#ifdef WASABI_COMPILE_WND
+#define GURU_PARENT BaseWnd
+#else
+class _Guru {};
+#define GURU_PARENT _Guru
+#endif
+
+class SystemObject;
+
+#define GURU_TIMERID 2482
+
+class Guru : public GURU_PARENT {
+public:
+#ifdef WASABI_COMPILE_WND
+ Guru();
+ virtual ~Guru();
+#endif
+
+ static void spawn(SystemObject *_script, int code, const wchar_t *pub = NULL, int intinfo = 0);
+
+#ifdef WASABI_COMPILE_WND
+ virtual int onPaint(Canvas *canvas);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onInit();
+ void setCode(int c);
+ void setPublicTxt(const wchar_t *t);
+ void setIntInfo(int info);
+#endif
+
+#ifdef WASABI_COMPILE_WND
+protected:
+ virtual void timerCallback(int id);
+
+private:
+ int code;
+ const wchar_t *txt;
+ int fcount;
+ int intinfo;
+ static int mustquit;
+ static int last_iterator;
+ static SystemObject * script;
+#endif
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/makiapi.cpp b/Src/Wasabi/api/script/makiapi.cpp
new file mode 100644
index 00000000..de3df611
--- /dev/null
+++ b/Src/Wasabi/api/script/makiapi.cpp
@@ -0,0 +1,248 @@
+#include "precomp.h"
+#include "makiapi.h"
+#include "../../studio/api.h"
+#include "../../bfc/api/api_maki.h"
+#include "../../studio/script/vcpu.h"
+#include "../../studio/script/objecttable.h"
+#include "../../studio/script/scriptmgr.h"
+#include "../../studio/script/script.h"
+#include "../../common/script/scriptobj.h"
+
+api_maki *makiApi = NULL;
+
+ScriptApi::ScriptApi() {
+ ObjectTable::loadExternalClasses();
+ VCPU::scriptManager = new ScriptObjectManager();
+}
+
+ScriptApi::~ScriptApi() {
+ delete VCPU::scriptManager;
+ VCPU::scriptManager = NULL;
+ VCPU::shutdown();
+ ObjectTable::unloadExternalClasses();
+}
+
+void ScriptApi::maki_pushObject(void *o) {
+ VCPU::pushObject(o);
+}
+
+void ScriptApi::maki_pushInt(int i) {
+ VCPU::pushInt(i);
+}
+
+void ScriptApi::maki_pushBoolean(int b) {
+ VCPU::pushBoolean(b);
+}
+
+void ScriptApi::maki_pushFloat(float f) {
+ VCPU::pushFloat(f);
+}
+
+void ScriptApi::maki_pushDouble(double d) {
+ VCPU::pushDouble(d);
+}
+
+void ScriptApi::maki_pushString(const char *s) {
+ VCPU::pushString(s);
+}
+
+void ScriptApi::maki_pushAny(scriptVar v) {
+ VCPU::push(v);
+}
+
+void ScriptApi::maki_pushVoid() {
+ VCPU::pushVoid();
+}
+
+void *ScriptApi::maki_popObject() {
+ return VCPU::popObject();
+}
+
+int ScriptApi::maki_popInt() {
+ return VCPU::popInt();
+}
+
+bool ScriptApi::maki_popBoolean() {
+ return VCPU::popBoolean();
+}
+
+float ScriptApi::maki_popFloat() {
+ return VCPU::popFloat();
+}
+
+double ScriptApi::maki_popDouble() {
+ return VCPU::popDouble();
+}
+
+const char *ScriptApi::maki_popString() {
+ return VCPU::popString();
+}
+
+scriptVar ScriptApi::maki_popAny() {
+ return VCPU::pop().v;
+}
+
+void ScriptApi::maki_popDiscard() {
+ VCPU::popDiscard();
+}
+
+const char *ScriptApi::maki_getFunction(int dlfid, int *nparams, ScriptObjectController **p) {
+ return ObjectTable::getFunction(dlfid, nparams, p);
+}
+
+int ScriptApi::maki_addDlfRef(ScriptObjectController *o, const char *function_name, void *host) {
+ return ObjectTable::dlfAddRef(o, function_name, host);
+}
+
+void ScriptApi::maki_remDlfRef(void *host) {
+ ObjectTable::dlfRemRef(host);
+}
+
+void ScriptApi::maki_addDlfClassRef(ScriptObjectController *o, void *host) {
+ ObjectTable::dlfAddClassRef(o, host);
+}
+
+scriptVar ScriptApi::maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params) {
+ return ObjectTable::callFunction(o, dlfid, params);
+}
+
+scriptVar ScriptApi::maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid) {
+ scriptVar v = MAKE_SCRIPT_OBJECT(o);
+ return VCPU::executeEvent(v, dlfid, np, scriptid);
+}
+
+ScriptObject *ScriptApi::maki_instantiate(GUID classguid) {
+ int classid = ObjectTable::getClassFromGuid(classguid);
+ if (classid == -1) return NULL;
+ return ObjectTable::instantiate(classid);
+}
+
+void ScriptApi::maki_destroy(ScriptObject *o) {
+ ObjectTable::destroy(o);
+}
+
+void *ScriptApi::maki_encapsulate(GUID classguid, ScriptObject *o) {
+ int classid = ObjectTable::getClassFromGuid(classguid);
+ if (classid == -1) return NULL;
+ return ObjectTable::encapsulate(classid, o);
+}
+
+void ScriptApi::maki_deencapsulate(GUID classguid, void *o) {
+ int classid = ObjectTable::getClassFromGuid(classguid);
+ if (classid == -1) return;
+ ObjectTable::deencapsulate(classid, o);
+}
+
+ScriptObjectController *ScriptApi::maki_getController(GUID scriptclass) {
+ return ObjectTable::getController(scriptclass);
+}
+int ScriptApi::maki_createOrphan(int type) {
+ return VCPU::createOrphan(type);
+}
+
+void ScriptApi::maki_killOrphan(int id) {
+ VCPU::killOrphan(id);
+}
+
+int ScriptApi::maki_getScriptInt(scriptVar v) {
+ return SOM::makeInt(&v);
+}
+
+bool ScriptApi::maki_getScriptBoolean(scriptVar v) {
+ return SOM::makeBoolean(&v);
+}
+
+float ScriptApi::maki_getScriptFloat(scriptVar v) {
+ return SOM::makeFloat(&v);
+}
+
+double ScriptApi::maki_getScriptDouble(scriptVar v) {
+ return SOM::makeDouble(&v);
+}
+
+const char *ScriptApi::maki_getScriptString(scriptVar v) {
+ ASSERT(v.type == SCRIPT_STRING);
+ return v.data.sdata;
+}
+
+ScriptObject *ScriptApi::maki_getScriptObject(scriptVar v) {
+ ASSERT(!SOM::isNumeric(&v) && v.type != SCRIPT_STRING);
+ return v.data.odata;
+}
+
+scriptVar ScriptApi::maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount) {
+ switch (cmd->cmd) {
+ case MAKI_CMD_ADDREF:
+ (*linkcount)++;
+ break;
+ case MAKI_CMD_REMREF:
+ (*linkcount)--;
+ ASSERT(*linkcount >= 0);
+ if (*linkcount == 0)
+ *dlfid = -1;
+ break;
+ case MAKI_CMD_SETDLF:
+ ASSERT(*dlfid == -1);
+ *dlfid = cmd->id;
+ break;
+ case MAKI_CMD_GETDLF:
+ cmd->id = *dlfid;
+ break;
+ }
+ RETURN_SCRIPT_VOID
+}
+
+void ScriptApi::maki_setObjectAtom(const char *atomname, ScriptObject *object) {
+ VCPU::setAtom(atomname, object);
+}
+
+ScriptObject *ScriptApi::maki_getObjectAtom(const char *atomname) {
+ return VCPU::getAtom(atomname);
+}
+
+#ifdef WASABI_COMPILE_WND
+ScriptObject *ScriptApi::maki_findObject(const char *name) {
+ return ScriptObjectManager::findObject(name);
+}
+#endif
+
+void ScriptApi::vcpu_addScriptObject(ScriptObject *o) {
+ SystemObject::addScriptObject(o);
+}
+
+void ScriptApi::vcpu_removeScriptObject(ScriptObject *o) {
+ SystemObject::removeScriptObject(o);
+}
+
+int ScriptApi::vcpu_getCacheCount() {
+ return Script::getCacheCount();
+}
+
+int ScriptApi::vcpu_isValidScriptId(int id) {
+ return Script::isValidScriptId(id);
+}
+
+int ScriptApi::vcpu_mapVarId(int varid, int scriptid) {
+ return Script::varIdToGlobal(varid, scriptid);
+}
+
+int ScriptApi::vcpu_getUserAncestorId(int varid, int scriptid) {
+ return Script::getUserAncestor(varid, scriptid);
+}
+
+int ScriptApi::vcpu_getNumEvents() {
+ return Script::getNumEventsLinked();
+}
+
+int ScriptApi::vcpu_getEvent(int event, int *dlf, int *script, int *var) {
+ return Script::getLinkedEventParams(event, dlf, script, var);
+}
+
+int ScriptApi::vcpu_getComplete() {
+ return VCPU::getComplete();
+}
+
+const char * ScriptApi::vcpu_getClassName(int vcpuid, int localclassid) {
+ return VCPU::getClassName(vcpuid, localclassid);
+}
+
diff --git a/Src/Wasabi/api/script/makiapi.h b/Src/Wasabi/api/script/makiapi.h
new file mode 100644
index 00000000..e1d27aff
--- /dev/null
+++ b/Src/Wasabi/api/script/makiapi.h
@@ -0,0 +1,66 @@
+#ifndef __SCRIPTAPI_H
+#define __SCRIPTAPI_H
+
+#include <api/script/api_makii.h>
+
+class ScriptApi : public api_makiI {
+ public:
+ ScriptApi();
+ virtual ~ScriptApi();
+
+ virtual void maki_pushObject(void *o);
+ virtual void maki_pushInt(int v);
+ virtual void maki_pushBoolean(int b);
+ virtual void maki_pushFloat(float f);
+ virtual void maki_pushDouble(double d);
+ virtual void maki_pushString(const wchar_t *s);
+ virtual void maki_pushVoid();
+ virtual void maki_pushAny(scriptVar v);
+ virtual void *maki_popObject();
+ virtual int maki_popInt();
+ virtual bool maki_popBoolean();
+ virtual float maki_popFloat();
+ virtual double maki_popDouble();
+ virtual const wchar_t *maki_popString();
+ virtual scriptVar maki_popAny();
+ virtual void maki_popDiscard();
+ virtual const wchar_t *maki_getFunction(int dlfid, int *n, ScriptObjectController **p);
+ virtual int maki_addDlfRef(ScriptObjectController *o, const wchar_t *function_name, void *host);
+ virtual void maki_addDlfClassRef(ScriptObjectController *o, void *host);
+ virtual void maki_remDlfRef(void *host);
+ virtual scriptVar maki_callFunction(ScriptObject *o, int dlfid, scriptVar **params);
+ virtual scriptVar maki_triggerEvent(ScriptObject *o, int dlfid, int np, int scriptid0=-1);
+ virtual int maki_getScriptInt(scriptVar v);
+ virtual bool maki_getScriptBoolean(scriptVar v);
+ virtual float maki_getScriptFloat(scriptVar v);
+ virtual double maki_getScriptDouble(scriptVar v);
+ virtual const wchar_t *maki_getScriptString(scriptVar v);
+ virtual ScriptObject *maki_getScriptObject(scriptVar v);
+ virtual scriptVar maki_updateDlf(maki_cmd *cmd, int *dlfid, int *linkcount);
+ virtual ScriptObject *maki_instantiate(GUID classguid);
+ virtual void maki_destroy(ScriptObject *o);
+ virtual void *maki_encapsulate(GUID classguid, ScriptObject *o);
+ virtual void maki_deencapsulate(GUID classguid, void *o);
+ virtual ScriptObjectController *maki_getController(GUID scriptclass);
+ virtual int maki_createOrphan(int type);
+ virtual void maki_killOrphan(int id);
+ virtual void maki_setObjectAtom(const wchar_t *atomname, ScriptObject *object);
+ virtual ScriptObject *maki_getObjectAtom(const wchar_t *atomname);
+#ifdef WASABI_COMPILE_WND
+ virtual ScriptObject *maki_findObject(const wchar_t *name);
+#endif
+ virtual void vcpu_addScriptObject(ScriptObject *o);
+ virtual void vcpu_removeScriptObject(ScriptObject *o);
+ virtual int vcpu_getCacheCount();
+ virtual int vcpu_isValidScriptId(int id);
+ virtual int vcpu_mapVarId(int varid, int scriptid);
+ virtual int vcpu_getUserAncestorId(int varid, int scriptid);
+ virtual int vcpu_getNumEvents();
+ virtual int vcpu_getEvent(int event, int *dlf, int *script, int *var);
+ virtual int vcpu_getComplete();
+ virtual const wchar_t *vcpu_getClassName(int vcpuid, int localclassid);
+};
+
+extern api_maki *makiApi;
+
+#endif
diff --git a/Src/Wasabi/api/script/objcontroller.cpp b/Src/Wasabi/api/script/objcontroller.cpp
new file mode 100644
index 00000000..0cae1ccc
--- /dev/null
+++ b/Src/Wasabi/api/script/objcontroller.cpp
@@ -0,0 +1,156 @@
+#include <bfc/wasabi_std.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/c_script/scripthook.h>
+#include "api.h"
+
+#define CBCLASS ScriptObjectControllerI
+START_DISPATCH;
+ CB(GETCLASSGUID, getClassGuid);
+ CB(GETCLASSNAME, getClassName);
+ CB(GETANCESTORCLASSNAME, getAncestorClassName);
+ CB(GETNUMFUNCTIONS, getNumFunctions);
+ CB(GETEXPORTEDFUNCTIONS, getExportedFunctions);
+ CB(INSTANTIATE, instantiate);
+ VCB(DESTROY, destroy);
+ CB(ENCAPSULATE, encapsulate);
+ VCB(DEENCAPSULATE, deencapsulate);
+ VCB(SETCLASSID, setClassId);
+ CB(GETCLASSID, getClassId);
+ VCB(SETANCESTORCLASSID, setAncestorClassId);
+ CB(GETANCESTORCLASSID, getAncestorClassId);
+ CB(GETINSTANTIABLE, getInstantiable);
+ CB(GETREFERENCEABLE, getReferenceable);
+ CB(GETANCESTORCONTROLLER, getAncestorController);
+ VCB(ADDCLASSHOOK, addClassHook);
+ VCB(ADDOBJHOOK, addObjectHook);
+ VCB(REMHOOKS, removeHooks);
+ VCB(ONREGISTERCLASS, onRegisterClass);
+ CB(CAST, cast);
+END_DISPATCH;
+
+ScriptObjectControllerI::ScriptObjectControllerI() {
+ my_class_id = -1;
+ my_ancestor_class_id = -1;
+ rootController = NULL;
+ incast = 0;
+}
+
+ScriptObjectControllerI::~ScriptObjectControllerI() {
+}
+
+int ScriptObjectControllerI::processHooks(ScriptObject *o, int dlfid, scriptVar **table, int nparams) {
+ //CUT: int n=-1;
+ for (int j=0;j<classhooks.getNumItems();j++) {
+ classhooks.enumItem(j)->eventCallback(o, dlfid, table, nparams);
+ }
+ for (int i=0;i<objhooks.getNumItems();i++) {
+ object_hook_struct *s = objhooks.enumItem(i);
+ if (s->object == o) {
+ s->hook->eventCallback(o, dlfid, table, nparams);
+ }
+ }
+ return 0;
+}
+
+ScriptObject *ScriptObjectControllerI::cast(ScriptObject *o, GUID g) {
+ if (incast) return NULL;
+ incast = 1;
+ ASSERT(o != NULL);
+ ScriptObject *obj = NULL;
+ void *i = o->vcpu_getInterfaceObject(g, &obj);
+ incast = 0;
+ if (i != NULL) {
+ if (obj != NULL) return obj;
+ return o;
+ }
+ return NULL;
+}
+
+void ScriptObjectControllerI::addClassHook(ScriptHook *h) {
+ classhooks.addItem(h);
+}
+
+void ScriptObjectControllerI::addObjectHook(ScriptHook *h, ScriptObject *o) {
+ object_hook_struct *s = new object_hook_struct;
+ s->hook = h;
+ s->object = o;
+ objhooks.addItem(s);
+/* if (getAncestorController())
+ getAncestorController()->addObjectHook(h, o);
+ else
+ if (rootController && this != rootController) rootController->addObjectHook(h, o);*/
+}
+
+void ScriptObjectControllerI::removeHooks(ScriptHook *h) {
+ classhooks.removeItem(h);
+ for (int i=0;i<objhooks.getNumItems();i++) {
+ object_hook_struct *o = objhooks.enumItem(i);
+ if (o->hook == h) {
+ delete o;
+ objhooks.removeByPos(i);
+ i--;
+ }
+ }
+/* if (getAncestorController())
+ getAncestorController()->removeHooks(h);
+ else
+ if (rootController && this != rootController) rootController->removeHooks(h);*/
+}
+
+void ScriptObjectControllerI::onRegisterClass(ScriptObjectController *root) {
+ rootController = root;
+}
+
+
+scriptVar MAKE_SCRIPT_INT(int i) {
+ scriptVar r;
+ r.type = SCRIPT_INT;
+ r.data.idata = i;
+ return r;
+}
+
+scriptVar MAKE_SCRIPT_VOID() {
+ scriptVar r; r.type = SCRIPT_VOID;
+ r.data.idata = 0;
+ return r;
+}
+
+scriptVar MAKE_SCRIPT_FLOAT(float f) {
+ scriptVar r; r.type = SCRIPT_FLOAT;
+ r.data.fdata = f;
+ return r;
+}
+
+scriptVar MAKE_SCRIPT_DOUBLE(double d) {
+ scriptVar r; r.type = SCRIPT_DOUBLE;
+ r.data.ddata = d;
+ return r;
+}
+
+scriptVar MAKE_SCRIPT_BOOLEAN(int b) {
+ scriptVar r; r.type = SCRIPT_BOOLEAN;
+ r.data.idata = b;
+ return r;
+}
+
+scriptVar MAKE_SCRIPT_OBJECT(ScriptObject *o) {
+ scriptVar r;
+ r.type = SCRIPT_OBJECT;
+ r.data.odata = o;
+ return r;
+}
+
+scriptVar MAKE_SCRIPT_STRING(const wchar_t *s)
+{
+ scriptVar r;
+ r.type = SCRIPT_STRING;
+ r.data.sdata = s;
+ return r;
+}
+
+void *GET_SCRIPT_OBJECT_AS(scriptVar v, GUID g) {
+ ScriptObject *o = GET_SCRIPT_OBJECT(v);
+ if (!o) return NULL;
+ return o->vcpu_getInterface(g);
+}
+
diff --git a/Src/Wasabi/api/script/objcontroller.h b/Src/Wasabi/api/script/objcontroller.h
new file mode 100644
index 00000000..15400853
--- /dev/null
+++ b/Src/Wasabi/api/script/objcontroller.h
@@ -0,0 +1,316 @@
+#ifndef __SCRIPTOBJECTCONTROLLER_H
+#define __SCRIPTOBJECTCONTROLLER_H
+
+#include <api/script/scriptguid.h>
+
+//#include <wasabicfg.h>
+
+#include <bfc/ptrlist.h>
+#include <bfc/dispatch.h>
+#include <api/script/scriptobj.h>
+#include <api/script/vcputypes.h>
+#include <api/service/svcs/svc_scriptobj.h>
+
+#define SCRIPT_MAXARGS 10 // 10 args max per function
+
+#define MAKI_CMD_NONE 0
+#define MAKI_CMD_SETDLF 1
+#define MAKI_CMD_GETDLF 2
+#define MAKI_CMD_ADDREF 3
+#define MAKI_CMD_REMREF 4
+#define MAKI_CMD_RESETDLF 5
+
+#define SCRIPT_FUNCTION_INIT static int __dlfid=-1, __linkcount=0; if (__cmd != NULL) return WASABI_API_MAKI->maki_updateDlf(__cmd, &__dlfid, &__linkcount);
+#define SCRIPT_FUNCTION_CHECKABORTEVENT if (__dlfid==-1) RETURN_SCRIPT_VOID;
+#define SCRIPT_FUNCTION_CHECKABORTEVENT_SYS(o) { SCRIPT_FUNCTION_CHECKABORTEVENT { SystemObject *so = static_cast<SystemObject *>(o->vcpu_getInterface(systemObjectGuid)); if (!so || !so->isLoaded()) RETURN_SCRIPT_VOID; } }
+#define PROCESS_HOOKS0(object, controller) { controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, NULL, 0); }
+#define PROCESS_HOOKS1(object, controller, p1) { scriptVar *__table[1] = {&p1}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 1); }
+#define PROCESS_HOOKS2(object, controller, p1, p2) { scriptVar *__table[2] = {&p1, &p2}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 2); }
+#define PROCESS_HOOKS3(object, controller, p1, p2, p3) { scriptVar *__table[3] = {&p1, &p2, &p3}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 3); }
+#define PROCESS_HOOKS4(object, controller, p1, p2, p3, p4) { scriptVar *__table[4] = {&p1, &p2, &p3, &p4}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 4); }
+#define PROCESS_HOOKS5(object, controller, p1, p2, p3, p4, p5) { scriptVar *__table[5] = {&p1, &p2, &p3, &p4, &p5}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 5); }
+#define PROCESS_HOOKS6(object, controller, p1, p2, p3, p4, p5, p6) { scriptVar *__table[6] = {&p1, &p2, &p3, &p4, &p5, &p6}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 6); }
+#define PROCESS_HOOKS7(object, controller, p1, p2, p3, p4, p5, p6, p7) { scriptVar *__table[7] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 7); }
+#define PROCESS_HOOKS8(object, controller, p1, p2, p3, p4, p5, p6, p7, p8) { scriptVar *__table[8] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 8); }
+#define PROCESS_HOOKS9(object, controller, p1, p2, p3, p4, p5, p6, p7, p8, p9) { scriptVar *__table[9] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 9); }
+#define PROCESS_HOOKS10(object, controller, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) { scriptVar *__table[10] = {&p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10}; controller->processHooks(static_cast<ScriptObject *>(object), DLF_ID, __table, 10); }
+#define SCRIPT_EXEC_EVENT0(object) { return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 0); }
+#define SCRIPT_EXEC_EVENT1(object, p1) { WASABI_API_MAKI->maki_pushAny(p1); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 1); }
+#define SCRIPT_EXEC_EVENT2(object, p1, p2) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 2); }
+#define SCRIPT_EXEC_EVENT3(object, p1, p2, p3) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 3); }
+#define SCRIPT_EXEC_EVENT4(object, p1, p2, p3, p4) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 4); }
+#define SCRIPT_EXEC_EVENT5(object, p1, p2, p3, p4, p5) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); WASABI_API_MAKI->maki_pushAny(p5); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 5); }
+#define SCRIPT_EXEC_EVENT6(object, p1, p2, p3, p4, p5, p6) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); WASABI_API_MAKI->maki_pushAny(p5); WASABI_API_MAKI->maki_pushAny(p6); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 6); }
+#define SCRIPT_EXEC_EVENT7(object, p1, p2, p3, p4, p5, p6, p7) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); WASABI_API_MAKI->maki_pushAny(p5); WASABI_API_MAKI->maki_pushAny(p6); WASABI_API_MAKI->maki_pushAny(p7); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 7); }
+#define SCRIPT_EXEC_EVENT8(object, p1, p2, p3, p4, p5, p6, p7, p8) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); WASABI_API_MAKI->maki_pushAny(p5); WASABI_API_MAKI->maki_pushAny(p6); WASABI_API_MAKI->maki_pushAny(p7); WASABI_API_MAKI->maki_pushAny(p8); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 8); }
+#define SCRIPT_EXEC_EVENT9(object, p1, p2, p3, p4, p5, p6, p7, p8, p9) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); WASABI_API_MAKI->maki_pushAny(p5); WASABI_API_MAKI->maki_pushAny(p6); WASABI_API_MAKI->maki_pushAny(p7); WASABI_API_MAKI->maki_pushAny(p8); WASABI_API_MAKI->maki_pushAny(p9); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 9); }
+#define SCRIPT_EXEC_EVENT10(object, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) { WASABI_API_MAKI->maki_pushAny(p1); WASABI_API_MAKI->maki_pushAny(p2); WASABI_API_MAKI->maki_pushAny(p3); WASABI_API_MAKI->maki_pushAny(p4); WASABI_API_MAKI->maki_pushAny(p5); WASABI_API_MAKI->maki_pushAny(p6); WASABI_API_MAKI->maki_pushAny(p7); WASABI_API_MAKI->maki_pushAny(p8); WASABI_API_MAKI->maki_pushAny(p9); WASABI_API_MAKI->maki_pushAny(p10); return WASABI_API_MAKI->maki_triggerEvent(object, DLF_ID, 10); }
+
+#define SCRIPT_FUNCTION_PARAMS maki_cmd *__cmd, int __vsd
+#define SCRIPT_CALL NULL, -1
+#define GET_SCRIPT_INT(v) WASABI_API_MAKI->maki_getScriptInt(v)
+//CUT#define GET_SCRIPT_INT(v) ((v).getAsInt())
+#define GET_SCRIPT_BOOLEAN(v) WASABI_API_MAKI->maki_getScriptBoolean(v)
+#define GET_SCRIPT_FLOAT(v) WASABI_API_MAKI->maki_getScriptFloat(v)
+#define GET_SCRIPT_DOUBLE(v) WASABI_API_MAKI->maki_getScriptDouble(v)
+#define GET_SCRIPT_STRING(v) WASABI_API_MAKI->maki_getScriptString(v)
+#define GET_SCRIPT_OBJECT(v) WASABI_API_MAKI->maki_getScriptObject(v)
+
+scriptVar COMEXP MAKE_SCRIPT_INT(int i);
+scriptVar COMEXP MAKE_SCRIPT_VOID();
+scriptVar COMEXP MAKE_SCRIPT_FLOAT(float f);
+scriptVar COMEXP MAKE_SCRIPT_DOUBLE(double d);
+scriptVar COMEXP MAKE_SCRIPT_BOOLEAN(int b);
+scriptVar COMEXP MAKE_SCRIPT_OBJECT(ScriptObject *o);
+scriptVar COMEXP MAKE_SCRIPT_STRING(const wchar_t *s);
+void COMEXP *GET_SCRIPT_OBJECT_AS(scriptVar v, GUID g);
+
+#define FIXUP_FUNCTION_DLF SCRIPT_FUNCTION_INIT
+/*#define FIXUP_FUNCTION_DLF \
+static int fn_DLF=-1; \
+if (fn_DLF == -1 && DLFid == -1) { RETURN_SCRIPT_ZERO } \
+if (fn_DLF == -1 && DLFid != -1 && o == NULL) { \
+ fn_DLF = DLFid; \
+ RETURN_SCRIPT_VOID \
+ } else if (DLFid != -1) { \
+ ASSERTPR(0, "DLFId already set"); \
+ RETURN_SCRIPT_VOID \
+ }*/
+
+#define DLF_ID __dlfid
+
+#define RETURN_SCRIPT_EVENT \
+{ scriptVar script_event_return={SCRIPT_EVENT,0}; \
+return script_event_return; }
+
+#define RETURN_SCRIPT_VOID \
+{ scriptVar script_event_return={SCRIPT_VOID,0}; \
+return script_event_return; }
+
+#define RETURN_SCRIPT_ZERO \
+{ scriptVar script_event_return={SCRIPT_INT,0}; \
+return script_event_return; }
+
+#define RETURN_SCRIPT_NULL \
+{ scriptVar script_event_return={SCRIPT_OBJECT,NULL}; \
+return script_event_return; }
+
+#define SCRIPT_FUNCTION_INT(_class, func, call) \
+scriptVar _class::func(int DLFid, ScriptObject *o) { \
+ FIXUP_FUNCTION_DLF \
+ ASSERT(o != NULL); \
+ scriptVar s = SOM::makeVar(SCRIPT_INT); \
+ SOM::assign(&s, ((_class *)o)->call()); \
+ return s;\
+}
+
+#define DEC_SCRIPT_FUNCTION_INT(func1, func2) \
+ static scriptVar func1(int DLFid, ScriptObject *o); \
+ virtual int func2();
+
+
+#define EVENT_ID __dlfid
+
+typedef struct {
+ const wchar_t *function_name;
+ int nparams;
+ void *physical_ptr;
+} function_descriptor_struct;
+
+typedef struct {
+ ScriptHook *hook;
+ ScriptObject *object;
+} object_hook_struct;
+
+static const GUID ROOT_GUID =
+{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
+
+
+class ScriptObjectController : public Dispatchable {
+ protected:
+ ScriptObjectController() {};
+
+ public:
+
+ void onRegisterClass(ScriptObjectController *rootController);
+ GUID getClassGuid();
+ const wchar_t *getClassName();
+ const wchar_t *getAncestorClassName();
+ ScriptObjectController *getAncestorController();
+ int getNumFunctions();
+ const function_descriptor_struct *getExportedFunctions();
+ ScriptObject *instantiate();
+ void destroy(ScriptObject *o);
+ void *encapsulate(ScriptObject *o);
+ void deencapsulate(void *o);
+ ScriptObject *cast(ScriptObject *o, GUID g);
+ void setClassId(int id);
+ int getClassId();
+ void setAncestorClassId(int id);
+ int getAncestorClassId();
+ int getInstantiable();
+ int getReferenceable();
+ int processHooks(ScriptObject *o, int dlfid, scriptVar **table, int nparams);
+ void addClassHook(ScriptHook *h);
+ void addObjectHook(ScriptHook *h, ScriptObject *o);
+ void removeHooks(ScriptHook *h);
+
+ enum {
+ GETCLASSGUID = 100,
+ GETCLASSNAME = 200,
+ GETANCESTORCLASSNAME = 300,
+ GETNUMFUNCTIONS = 400,
+ GETEXPORTEDFUNCTIONS = 500,
+ INSTANTIATE = 600,
+ DESTROY = 700,
+ GETCLASSID = 800,
+ SETCLASSID = 900,
+ SETANCESTORCLASSID = 1000,
+ GETANCESTORCLASSID = 1100,
+ GETINSTANTIABLE = 1200,
+ GETREFERENCEABLE = 1300,
+ PROCESSHOOKS = 1400,
+ GETANCESTORCONTROLLER = 1500,
+ ADDCLASSHOOK = 1600,
+ ADDOBJHOOK = 1700,
+ REMHOOKS = 1800,
+ ONREGISTERCLASS = 1900,
+ ENCAPSULATE = 2000,
+ DEENCAPSULATE = 2100,
+ CAST = 2200,
+ };
+};
+
+inline GUID ScriptObjectController::getClassGuid() {
+ return _call(GETCLASSGUID, ROOT_GUID);
+}
+
+inline const wchar_t *ScriptObjectController::getClassName()
+{
+ return _call(GETCLASSNAME, (const wchar_t *)NULL);
+}
+
+inline const wchar_t *ScriptObjectController::getAncestorClassName() {
+ return _call(GETANCESTORCLASSNAME, (const wchar_t *)NULL);
+}
+
+inline int ScriptObjectController::getNumFunctions() {
+ return _call(GETNUMFUNCTIONS, 0);
+}
+
+inline const function_descriptor_struct *ScriptObjectController::getExportedFunctions() {
+ return _call(GETEXPORTEDFUNCTIONS, (const function_descriptor_struct *)NULL);
+}
+
+inline ScriptObject *ScriptObjectController::instantiate() {
+ return _call(INSTANTIATE, (ScriptObject *)NULL);
+}
+
+inline void ScriptObjectController::destroy(ScriptObject *o) {
+ _voidcall(DESTROY, o);
+}
+
+inline int ScriptObjectController::getClassId() {
+ return _call(GETCLASSID, 0);
+}
+
+inline void ScriptObjectController::setClassId(int id) {
+ _voidcall(SETCLASSID, id);
+}
+
+inline int ScriptObjectController::getAncestorClassId() {
+ return _call(GETANCESTORCLASSID, 0);
+}
+
+inline void ScriptObjectController::setAncestorClassId(int id) {
+ _voidcall(SETANCESTORCLASSID, id);
+}
+
+inline int ScriptObjectController::getInstantiable() {
+ return _call(GETINSTANTIABLE, 0);
+}
+
+inline int ScriptObjectController::getReferenceable() {
+ return _call(GETREFERENCEABLE, 0);
+}
+
+inline ScriptObjectController *ScriptObjectController::getAncestorController() {
+ return _call(GETANCESTORCONTROLLER, (ScriptObjectController *)NULL);
+}
+
+inline int ScriptObjectController::processHooks(ScriptObject *o, int dlfid, scriptVar **table, int nparams) {
+ return _call(PROCESSHOOKS, 0, o, dlfid, table, nparams);
+}
+
+inline void ScriptObjectController::addClassHook(ScriptHook *h) {
+ _voidcall(ADDCLASSHOOK, h);
+}
+
+inline void ScriptObjectController::addObjectHook(ScriptHook *h, ScriptObject *o) {
+ _voidcall(ADDOBJHOOK, h, o);
+}
+
+inline void ScriptObjectController::removeHooks(ScriptHook *h) {
+ _voidcall(REMHOOKS, h);
+}
+
+inline void ScriptObjectController::onRegisterClass(ScriptObjectController *rootController) {
+ _voidcall(ONREGISTERCLASS, rootController);
+}
+
+inline void *ScriptObjectController::encapsulate(ScriptObject *o) {
+ return _call(ENCAPSULATE, (void *) NULL, o);
+}
+
+inline void ScriptObjectController::deencapsulate(void *o) {
+ _voidcall(DEENCAPSULATE, o);
+}
+
+inline ScriptObject *ScriptObjectController::cast(ScriptObject *o, GUID g) {
+ return _call(CAST, (ScriptObject *)NULL, o, g);
+}
+
+class ScriptObjectControllerI : public ScriptObjectController {
+ public:
+
+ ScriptObjectControllerI();
+ virtual ~ScriptObjectControllerI();
+
+ virtual void onRegisterClass(ScriptObjectController *rootController);
+ virtual GUID getClassGuid()=0;
+ virtual const wchar_t *getClassName()=0;
+ virtual const wchar_t *getAncestorClassName()=0;
+ virtual ScriptObjectController *getAncestorController()=0;
+ virtual int getNumFunctions()=0;
+ virtual const function_descriptor_struct *getExportedFunctions()=0;
+ virtual ScriptObject *instantiate()=0;
+ virtual void destroy(ScriptObject *o)=0;
+ virtual void *encapsulate(ScriptObject *o)=0;
+ virtual void deencapsulate(void *o)=0;
+ virtual ScriptObject *cast(ScriptObject *o, GUID g);
+
+ virtual void setClassId(int id) { my_class_id = id; }
+ virtual int getClassId() { return my_class_id; }
+ virtual void setAncestorClassId(int id) { my_ancestor_class_id = id; }
+ virtual int getAncestorClassId() { return my_ancestor_class_id; }
+ virtual int getInstantiable() { return 1; };
+ virtual int getReferenceable() { return 1; };
+ virtual int processHooks(ScriptObject *o, int dlfid, scriptVar **table, int nparams);
+ virtual void addClassHook(ScriptHook *h);
+ virtual void addObjectHook(ScriptHook *h, ScriptObject *o);
+ virtual void removeHooks(ScriptHook *h);
+
+ private:
+ int my_class_id;
+ int my_ancestor_class_id;
+
+ PtrList<object_hook_struct> objhooks;
+ PtrList<ScriptHook> classhooks;
+ ScriptObjectController *rootController;
+ int incast;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objcontrollert.cpp b/Src/Wasabi/api/script/objcontrollert.cpp
new file mode 100644
index 00000000..ceeb0d64
--- /dev/null
+++ b/Src/Wasabi/api/script/objcontrollert.cpp
@@ -0,0 +1 @@
+#include "precomp.h"
diff --git a/Src/Wasabi/api/script/objcontrollert.h b/Src/Wasabi/api/script/objcontrollert.h
new file mode 100644
index 00000000..5d0e37ef
--- /dev/null
+++ b/Src/Wasabi/api/script/objcontrollert.h
@@ -0,0 +1,67 @@
+#ifndef __SCRIPTOBJECTCONTROLLERT_H
+#define __SCRIPTOBJECTCONTROLLERT_H
+
+#include "objcontroller.h"
+
+template <class T, class A>
+class ScriptObjectControllerT : public ScriptObjectControllerI {
+public:
+ virtual const wchar_t *getClassName() { return T::scriptobject_getClassName(); }
+ virtual const wchar_t *getAncestorClassName() { return A::scriptobject_getClassName(); }
+ virtual ScriptObjectController *getAncestorController() {
+ return WASABI_API_MAKI->maki_getController(A::scriptobject_getClassGuid());
+ }
+ virtual GUID getClassGuid() { return T::scriptobject_getClassGuid(); }
+ virtual ScriptObject *instantiate() {
+ return (new T)->getScriptObject();
+ }
+ virtual void destroy(ScriptObject *o) {
+ T *t = static_cast<T *>(o->vcpu_getInterface(T::scriptobject_getClassGuid()));
+ delete t;
+ }
+ virtual void *encapsulate(ScriptObject *o) { return NULL; }
+ virtual void deencapsulate(void *o) { }
+
+#if 0
+ virtual int getNumFunctions() { return fn_descs.getNumItems(); }
+ virtual const function_descriptor_struct *getExportedFunctions() {
+ return fn_descs.enumRef(0);
+ }
+protected:
+ void addFn(const wchar_t *fnname, scriptcb *cb) {
+ function_descriptor_struct fds;
+ fds.function_name = fnname;
+ fds.nparams = cb->getNumParams();
+ fds.physical_ptr = cb->
+ }
+private:
+ TList fn_descs;
+#endif
+};
+
+#if 0
+class scriptcb {
+public:
+ virtual void *getNumParams()=0;
+ virtual void *getfn()=0;
+};
+
+template <class T>
+class scriptcb0v : public scriptcb {
+ typedef void (T::*fnPtrType)();
+public:
+ scriptcb0v(fnPtrType _fn) : fn(_fn) { }
+ static scriptVar call(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ T *t = static_cast<T *>(o->vcpu_getInterface(T::scriptobject_getClassGuid()));
+ if (t) (t->*fn)();
+ RETURN_SCRIPT_VOID;
+ }
+ virtual void *getNumParams() { return 0; }
+ virtual void *getfn() {
+ return static_cast<void *>(call);
+ }
+};
+#endif
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/PlaylistScriptObject.cpp b/Src/Wasabi/api/script/objects/PlaylistScriptObject.cpp
new file mode 100644
index 00000000..aa177956
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/PlaylistScriptObject.cpp
@@ -0,0 +1,438 @@
+// -----------------------------------------------------------------------------------------------------
+// Playlist Script Object
+//
+// functions for <pledit.mi>
+// -----------------------------------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "main.h"
+
+#include "PlaylistScriptObject.h"
+
+#include <bfc/wasabi_std.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/scriptobj.h>
+#include <api/script/scriptguid.h>
+
+#ifdef WASABI_COMPILE_MEDIACORE
+#include <api/service/svcs/svc_player.h>
+#include <api/core/buttons.h>
+#include <api/core/api_core.h>
+#include <api/core/corehandle.h> // safe to include even if core isn't there
+#endif
+
+static PlaylistScriptController _playlistController;
+ScriptObjectController *playlistController = &_playlistController;
+
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(PlaylistObject_Svc);
+DECLARE_SERVICE(ScriptObjectCreator<PlaylistScriptObjectSvc>);
+END_SERVICES(PlaylistObject_Svc, _PlaylistObject_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_PlaylistObjectSvc; }
+#else
+extern "C" { int __link_PlaylistObjectSvc; }
+#endif
+
+#endif
+
+
+// -----------------------------------------------------------------------------------------------------
+// Functions Table
+function_descriptor_struct PlaylistScriptController::exportedFunction[] =
+{
+ {L"showCurrentlyPlayingTrack", 0, (void*)SPlaylist::script_vcpu_showCurrentlyPlayingEntry},
+ {L"showTrack", 1, (void*)SPlaylist::script_vcpu_showEntry},
+ {L"getNumTracks", 0, (void*)SPlaylist::script_vcpu_getNumItems},
+ {L"getCurrentIndex", 0, (void*)SPlaylist::script_vcpu_getCurrentIndex},
+ {L"getRating", 1, (void*)SPlaylist::script_vcpu_getTrackRating},
+ {L"setRating", 2, (void*)SPlaylist::script_vcpu_setTrackRating},
+ {L"enqueueFile", 1, (void*)SPlaylist::script_vcpu_enqueueFile },
+ {L"clear", 0, (void*)SPlaylist::script_vcpu_clear },
+ {L"removeTrack", 1, (void*)SPlaylist::script_vcpu_removeTrack },
+ {L"swapTracks", 2, (void*)SPlaylist::script_vcpu_swapTrack },
+ {L"moveUp", 1, (void*)SPlaylist::script_vcpu_moveUp },
+ {L"moveDown", 1, (void*)SPlaylist::script_vcpu_moveDown },
+ {L"moveTo", 2, (void*)SPlaylist::script_vcpu_moveTo },
+ {L"getTitle", 1, (void*)SPlaylist::script_vcpu_getTitle },
+ {L"getLength", 1, (void*)SPlaylist::script_vcpu_getLength },
+ {L"getMetaData", 2, (void*)SPlaylist::script_vcpu_getExtendedInfo },
+ {L"getNumSelectedTracks", 0, (void*)SPlaylist::script_vcpu_getNumSelectedItems },
+ {L"getNextSelectedTrack", 1, (void*)SPlaylist::script_vcpu_getNextSelectedItem },
+ {L"getFileName", 1, (void*)SPlaylist::script_vcpu_getFileName },
+ {L"playTrack", 1, (void*)SPlaylist::script_vcpu_playTrack },
+ {L"onPleditModified", 0, (void*)SPlaylist::script_vcpu_onPleditModified },
+};
+
+ScriptObjectController *PlaylistScriptObjectSvc::getController(int n)
+{
+ switch (n) {
+ case 0:
+ return playlistController;
+ }
+ return NULL;
+}
+
+ScriptObject *PlaylistScriptController::instantiate()
+{
+ SPlaylist *c = new SPlaylist;
+ if (!c) return NULL;
+ return c->getScriptObject();
+}
+
+void PlaylistScriptController::destroy(ScriptObject *o)
+{
+ SPlaylist *obj = static_cast<SPlaylist *>(o->vcpu_getInterface(playlistScriptObjectGUID));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *PlaylistScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void PlaylistScriptController::deencapsulate(void *o)
+{
+}
+
+int PlaylistScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+SPlaylist::SPlaylist()
+{
+ getScriptObject()->vcpu_setInterface(playlistScriptObjectGUID, (void *)static_cast<SPlaylist *>(this));
+ getScriptObject()->vcpu_setClassName(L"PlEdit");
+ getScriptObject()->vcpu_setController(playlistController);
+
+ SOList.addItem(this);
+}
+
+SPlaylist::~SPlaylist()
+{
+ SOList.removeItem(this);
+}
+
+// Script helper functions
+
+void SPlaylist::onPleditModified ()
+{
+ //This one is not working
+ for (int i=0; i < SOList.getNumItems(); i++)
+ {
+ //script_vcpu_onPleditModified(SCRIPT_CALL, getScriptObject());
+ script_vcpu_onPleditModified(SCRIPT_CALL, SOList.enumItem(i)->getScriptObject());
+ //Std::messageBox(SOList.enumItem(i)->getClassName(), t, 0);
+ }
+}
+
+void SPlaylist::showEntry( int i)
+{
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+ SendMessageW(hPeWindow, WM_USER, 666, i);
+}
+
+void SPlaylist::swap(int track1, int track2)
+{
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+
+ int i = wa2.PE_getCurrentIndex();
+
+ int param = ((track1) << 16) | (track2);
+ SendMessageW(hPeWindow, WM_USER, IPC_PE_SWAPINDEX, param);
+
+ //Swap our currently playing item as well
+ if (i == track1)
+ {
+ wa2.PE_setCurrentIndex(track2);
+ }
+ else if (i == track2)
+ {
+ wa2.PE_setCurrentIndex(track1);
+ }
+}
+
+fileinfoW *SPlaylist::getFileInfoStructW1 (int item)
+{
+ static fileinfoW fi;
+ fi.index = item;
+ *(fi.file) = 0;
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+ SendMessageW(hPeWindow, WM_USER, IPC_PE_GETINDEXINFOW_INPROC, (LPARAM)&fi);
+ return &fi;
+}
+
+// Script Calls
+
+scriptVar SPlaylist::script_vcpu_showCurrentlyPlayingEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+
+ showEntry (wa2.PE_getCurrentIndex());
+
+ RETURN_SCRIPT_VOID;
+}
+
+
+scriptVar SPlaylist::script_vcpu_showEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i)
+{
+ SCRIPT_FUNCTION_INIT
+
+ showEntry (GET_SCRIPT_INT(i));
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+
+ int i = wa2.PE_getNumItems();
+
+ return MAKE_SCRIPT_INT(i);
+}
+
+scriptVar SPlaylist::script_vcpu_getCurrentIndex(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+
+ int i = wa2.PE_getCurrentIndex();
+
+ return MAKE_SCRIPT_INT(i);
+}
+
+scriptVar SPlaylist::script_vcpu_setTrackRating(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i, scriptVar rating)
+{
+ SCRIPT_FUNCTION_INIT
+
+ HWND hwnd_winamp = wa2.getMainWindow();
+
+ int cur_pos = wa2.PE_getCurrentIndex();
+ wa2.PE_setCurrentIndex(GET_SCRIPT_INT(i));
+ SendMessageW(hwnd_winamp, WM_WA_IPC, GET_SCRIPT_INT(rating), IPC_SETRATING);
+ wa2.PE_setCurrentIndex(cur_pos);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_getTrackRating(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i)
+{
+ SCRIPT_FUNCTION_INIT
+
+ HWND hwnd_winamp = wa2.getMainWindow();
+
+ int cur_pos = wa2.PE_getCurrentIndex();
+ wa2.PE_setCurrentIndex(GET_SCRIPT_INT(i));
+ int r = 0;
+ r = SendMessageW(hwnd_winamp, WM_WA_IPC, GET_SCRIPT_INT(i), IPC_GETRATING);
+ wa2.PE_setCurrentIndex(cur_pos);
+
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar SPlaylist::script_vcpu_enqueueFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar file)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ wa2.enqueueFile (GET_SCRIPT_STRING(file));
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_clear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ wa2.clearPlaylist();
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_removeTrack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+ SendMessageW(hPeWindow, WM_USER, IPC_PE_DELETEINDEX, GET_SCRIPT_INT(i));
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_swapTrack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track1, scriptVar _track2)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track1 = GET_SCRIPT_INT(_track1);
+ int track2 = GET_SCRIPT_INT(_track2);
+
+ if (track1 >= wa2.PE_getNumItems() || track1 < 0 || track2 >= wa2.PE_getNumItems() || track2 < 0) RETURN_SCRIPT_VOID;
+ swap ((track1), (track2));
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_moveUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+ if (track < wa2.PE_getNumItems()-1) swap (track, track+1);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_moveDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+ if (track > 0) swap (track, track-1);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_moveTo(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track, scriptVar _pos)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+ int pos = GET_SCRIPT_INT(_pos);
+
+ if (track == pos || pos >= wa2.PE_getNumItems() || pos < 0 || track >= wa2.PE_getNumItems() || track < 0)
+ {
+ RETURN_SCRIPT_VOID;
+ }
+
+ // Martin> This can be done much faster :P
+ /*if (track > pos)
+ {
+ for (int i = track; i > pos; i--)
+ {
+ swap (i, i-1);
+ }
+ }
+ else
+ {
+ for (int i = track; i < pos; i++)
+ {
+ swap (i, i+1);
+ }
+ }*/
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+ fileinfoW *fi = getFileInfoStructW1(track);
+ SendMessageW(hPeWindow, WM_USER, IPC_PE_DELETEINDEX, fi->index);
+ fi->index = pos;
+ static COPYDATASTRUCT cds;
+ cds.dwData = IPC_PE_INSERTFILENAMEW;
+ cds.lpData = fi;
+ SendMessageW(hPeWindow, WM_COPYDATA, NULL, (LPARAM)&cds);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPlaylist::script_vcpu_getTitle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+
+ // Martin> There might be a better way to convert this;)
+ // benski> yes, there is :) see below. There's a unicode equivalent API for this, just wasn't enabled in wa2frontend object
+ // so I added it
+ fileinfo2W *fi = wa2.PE_getFileTitleW(track);
+ if (fi)
+ return MAKE_SCRIPT_STRING(fi->filetitle);
+ else
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar SPlaylist::script_vcpu_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+
+ fileinfo2W *fi = wa2.PE_getFileTitleW(track);
+ if (fi)
+ return MAKE_SCRIPT_STRING((fi->filelength));
+ else
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar SPlaylist::script_vcpu_getFileName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+
+ fileinfoW *fi = getFileInfoStructW1(track);
+
+ return MAKE_SCRIPT_STRING(fi->file);
+}
+
+
+scriptVar SPlaylist::script_vcpu_getExtendedInfo(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track, scriptVar _name)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+ const wchar_t *name = GET_SCRIPT_STRING(_name);
+
+ fileinfoW *fi = getFileInfoStructW1(track);
+
+ wa2.getMetaData((fi->file), name, staticStr, 4096);
+
+ return MAKE_SCRIPT_STRING(staticStr);
+}
+
+scriptVar SPlaylist::script_vcpu_getNumSelectedItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
+ int ret = SendMessageW(hPeWindow, WM_USER, IPC_PE_GETSELECTEDCOUNT, 0);
+
+ return MAKE_SCRIPT_INT(ret);
+}
+
+scriptVar SPlaylist::script_vcpu_getNextSelectedItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ int track = GET_SCRIPT_INT(_track);
+
+ track = SendMessageW(wa2.getMainWindow(), WM_USER, track, IPC_PLAYLIST_GET_NEXT_SELECTED);
+
+ return MAKE_SCRIPT_INT(track);
+}
+
+scriptVar SPlaylist::script_vcpu_playTrack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track)
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ int track = GET_SCRIPT_INT(_track);
+ WASABI_API_MEDIACORE->core_userButton(0, UserButton::STOP);
+ wa2.PE_setCurrentIndex(track);
+ WASABI_API_MEDIACORE->core_userButton(0, UserButton::PLAY);
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SPlaylist::script_vcpu_onPleditModified(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, playlistController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+wchar_t SPlaylist::staticStr[4096] = {0};
+PtrList < SPlaylist > SPlaylist::SOList; \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/PlaylistScriptObject.h b/Src/Wasabi/api/script/objects/PlaylistScriptObject.h
new file mode 100644
index 00000000..db21e54b
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/PlaylistScriptObject.h
@@ -0,0 +1,102 @@
+#ifndef NULLSOFT_GEN_FF_PLAYLISTSCRIPTOBJECT_H
+#define NULLSOFT_GEN_FF_PLAYLISTSCRIPTOBJECT_H
+
+#include "wa2frontend.h"
+
+class SPlaylist;
+
+#include <api/script/script.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+#include <api/script/objcontroller.h>
+
+#include <api/service/svcs/svc_scriptobji.h>
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Provider Service
+
+class PlaylistScriptObjectSvc : public svc_scriptObjectI {
+
+public:
+ PlaylistScriptObjectSvc() {};
+ virtual ~PlaylistScriptObjectSvc() {};
+
+ static const char *getServiceName() { return "PlEdit maki object"; }
+ virtual ScriptObjectController *getController(int n);
+};
+
+// -----------------------------------------------------------------------------------------------------
+// PlaylistScriptObject GUID
+// {345BEEBC-0229-4921-90BE-6CB6A49A79D9}
+static const GUID playlistScriptObjectGUID =
+{ 0x345beebc, 0x229, 0x4921, { 0x90, 0xbe, 0x6c, 0xb6, 0xa4, 0x9a, 0x79, 0xd9 } };
+
+#define SPLAYLIST_SCRIPTPARENT RootObjectInstance
+
+// -----------------------------------------------------------------------------------------------------
+// ScriptObject Service
+
+class PlaylistScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"PlEdit"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return playlistScriptObjectGUID; }
+ //virtual int getInstantiable() { return 0; }
+ //virtual int getReferenceable() { return 0; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern ScriptObjectController *playlistController;
+
+class SPlaylist : public SPLAYLIST_SCRIPTPARENT {
+public:
+ SPlaylist();
+ virtual ~SPlaylist();
+
+ static PtrList < SPlaylist > SOList;
+
+ static void onPleditModified();
+ static void showEntry (int i);
+ static void swap (int a, int b);
+ static fileinfoW * getFileInfoStructW1 (int index);
+
+ // Maki functions table
+ static scriptVar script_vcpu_showCurrentlyPlayingEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_showEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i);
+ static scriptVar script_vcpu_getCurrentIndex(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getTrackRating(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i);
+ static scriptVar script_vcpu_setTrackRating(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i, scriptVar rating);
+ static scriptVar script_vcpu_enqueueFile (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar file);
+ static scriptVar script_vcpu_clear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_removeTrack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i);
+ static scriptVar script_vcpu_swapTrack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar track, scriptVar to);
+ static scriptVar script_vcpu_moveUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar track);
+ static scriptVar script_vcpu_moveDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar track);
+ static scriptVar script_vcpu_moveTo(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar track, scriptVar to);
+ static scriptVar script_vcpu_getTitle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track);
+ static scriptVar script_vcpu_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track);
+ static scriptVar script_vcpu_getExtendedInfo(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _track, scriptVar _name);
+ static scriptVar script_vcpu_getNumSelectedItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getNextSelectedItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _num);
+ static scriptVar script_vcpu_getFileName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _num);
+ static scriptVar script_vcpu_playTrack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _num);
+ static scriptVar script_vcpu_onPleditModified(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+private:
+ static wchar_t staticStr[4096];
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/c_script/c_browser.cpp b/Src/Wasabi/api/script/objects/c_script/c_browser.cpp
new file mode 100644
index 00000000..fdb167b9
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_browser.cpp
@@ -0,0 +1,127 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_browser.h"
+#include <api/script/objcontroller.h>
+
+C_Browser::C_Browser(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ C_hook(object);
+}
+
+C_Browser::C_Browser() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Browser::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, browserGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ navigateurl_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"navigateUrl", this);
+ back_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"back", this);
+ forward_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"forward", this);
+ stop_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"stop", this);
+ refresh_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"refresh", this);
+ home_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"home", this);
+ settargetname_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetName", this);
+ onbeforenavigate_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onBeforeNavigate", this);
+ ondocumentcomplete_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onDocumentComplete", this);
+ onmedialink_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMediaLink", this);
+ }
+ inited = 1;
+}
+
+C_Browser::~C_Browser() {
+}
+
+ScriptObject *C_Browser::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_BROWSER_PARENT::getScriptObject();
+}
+
+void C_Browser::navigateUrl(const wchar_t *url)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(url);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), navigateurl_id, params);
+}
+
+void C_Browser::back() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), back_id, NULL);
+}
+
+void C_Browser::forward() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), forward_id, NULL);
+}
+
+void C_Browser::stop() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), stop_id, NULL);
+}
+
+void C_Browser::refresh() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), refresh_id, NULL);
+}
+
+void C_Browser::home() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), home_id, NULL);
+}
+
+void C_Browser::setTargetName(const wchar_t *targetname) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(targetname);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargetname_id, params);
+}
+
+int C_Browser::onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *targetframename) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(url);
+ scriptVar b = MAKE_SCRIPT_INT(flags);
+ scriptVar c = MAKE_SCRIPT_STRING(targetframename);
+ scriptVar *params[3] = {&a, &b, &c};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onbeforenavigate_id, params));
+}
+
+void C_Browser::onDocumentComplete(const wchar_t *url) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(url);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ondocumentcomplete_id, params);
+}
+
+void C_Browser::onMediaLink(const wchar_t *url)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(url);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmedialink_id, params);
+}
+
+int C_Browser::loaded=0;
+int C_Browser::navigateurl_id=0;
+int C_Browser::back_id=0;
+int C_Browser::forward_id=0;
+int C_Browser::stop_id=0;
+int C_Browser::refresh_id=0;
+int C_Browser::home_id=0;
+int C_Browser::settargetname_id=0;
+int C_Browser::onbeforenavigate_id=0;
+int C_Browser::ondocumentcomplete_id=0;
+int C_Browser::onmedialink_id=0;
+
diff --git a/Src/Wasabi/api/script/objects/c_script/c_browser.h b/Src/Wasabi/api/script/objects/c_script/c_browser.h
new file mode 100644
index 00000000..63b12b25
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_browser.h
@@ -0,0 +1,49 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_BROWSER_H
+#define __C_BROWSER_H
+
+#include "c_guiobject.h"
+
+#define C_BROWSER_PARENT C_GuiObject
+
+class C_Browser : public C_BROWSER_PARENT {
+ public:
+
+ C_Browser(ScriptObject *object);
+ C_Browser();
+ virtual ~C_Browser();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void navigateUrl(const wchar_t *url);
+ virtual void back();
+ virtual void forward();
+ virtual void stop();
+ virtual void refresh();
+ virtual void home();
+ virtual void setTargetName(const wchar_t *targetname);
+ virtual int onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *targetframename);
+ virtual void onDocumentComplete(const wchar_t *url);
+ virtual void onMediaLink(const wchar_t *url);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int navigateurl_id;
+ static int back_id;
+ static int forward_id;
+ static int stop_id;
+ static int refresh_id;
+ static int home_id;
+ static int settargetname_id;
+ static int onbeforenavigate_id;
+ static int ondocumentcomplete_id;
+ static int onmedialink_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_button.cpp b/Src/Wasabi/api/script/objects/c_script/c_button.cpp
new file mode 100644
index 00000000..f22c73b6
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_button.cpp
@@ -0,0 +1,104 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_button.h"
+#include <api/script/objcontroller.h>
+
+C_Button::C_Button(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ C_hook(object);
+}
+
+C_Button::C_Button() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Button::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, buttonGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ onactivate_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onActivate", this);
+ onleftclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeftClick", this);
+ onrightclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onRightClick", this);
+ setactivated_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setActivated", this);
+ setactivatednocallback_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setActivatedNoCallback", this);
+ getactivated_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getActivated", this);
+ leftclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"leftClick", this);
+ rightclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"rightClick", this);
+ }
+ inited = 1;
+}
+
+C_Button::~C_Button() {
+}
+
+ScriptObject *C_Button::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_BUTTON_PARENT::getScriptObject();
+}
+
+void C_Button::onActivate(int activated) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(activated);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onactivate_id, params);
+}
+
+void C_Button::onLeftClick() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleftclick_id, NULL);
+}
+
+void C_Button::onRightClick() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onrightclick_id, NULL);
+}
+
+void C_Button::setActivated(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setactivated_id, params);
+}
+
+void C_Button::setActivatedNoCallback(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setactivatednocallback_id, params);
+}
+
+int C_Button::getActivated() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getactivated_id, NULL));
+}
+
+void C_Button::leftClick() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), leftclick_id, NULL);
+}
+
+void C_Button::rightClick() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), rightclick_id, NULL);
+}
+
+int C_Button::loaded=0;
+int C_Button::onactivate_id=0;
+int C_Button::onleftclick_id=0;
+int C_Button::onrightclick_id=0;
+int C_Button::setactivated_id=0;
+int C_Button::setactivatednocallback_id=0;
+int C_Button::getactivated_id=0;
+int C_Button::leftclick_id=0;
+int C_Button::rightclick_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_button.h b/Src/Wasabi/api/script/objects/c_script/c_button.h
new file mode 100644
index 00000000..44af7579
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_button.h
@@ -0,0 +1,45 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_BUTTON_H
+#define __C_BUTTON_H
+
+#include "c_guiobject.h"
+
+#define C_BUTTON_PARENT C_GuiObject
+
+class C_Button : public C_BUTTON_PARENT {
+ public:
+
+ C_Button(ScriptObject *object);
+ C_Button();
+ virtual ~C_Button();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onActivate(int activated);
+ virtual void onLeftClick();
+ virtual void onRightClick();
+ virtual void setActivated(int onoff);
+ virtual void setActivatedNoCallback(int onoff);
+ virtual int getActivated();
+ virtual void leftClick();
+ virtual void rightClick();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onactivate_id;
+ static int onleftclick_id;
+ static int onrightclick_id;
+ static int setactivated_id;
+ static int setactivatednocallback_id;
+ static int getactivated_id;
+ static int leftclick_id;
+ static int rightclick_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_checkbox.cpp b/Src/Wasabi/api/script/objects/c_script/c_checkbox.cpp
new file mode 100644
index 00000000..f5e82571
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_checkbox.cpp
@@ -0,0 +1,84 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_checkbox.h"
+#include <api/script/objcontroller.h>
+
+C_CheckBox::C_CheckBox(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ C_hook(object);
+}
+
+C_CheckBox::C_CheckBox() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_CheckBox::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, checkBoxGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ ontoggle_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onToggle", this);
+ setchecked_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setChecked", this);
+ ischecked_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isChecked", this);
+ settext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setText", this);
+ gettext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getText", this);
+ }
+ inited = 1;
+}
+
+C_CheckBox::~C_CheckBox() {
+}
+
+ScriptObject *C_CheckBox::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_CHECKBOX_PARENT::getScriptObject();
+}
+
+void C_CheckBox::onToggle(int newstate) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(newstate);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ontoggle_id, params);
+}
+
+void C_CheckBox::setChecked(int checked) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(checked);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setchecked_id, params);
+}
+
+int C_CheckBox::isChecked() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), ischecked_id, NULL));
+}
+
+void C_CheckBox::setText(const wchar_t *txt)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(txt);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settext_id, params);
+}
+
+const wchar_t *C_CheckBox::getText() {
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettext_id, NULL));
+}
+
+int C_CheckBox::loaded=0;
+int C_CheckBox::ontoggle_id=0;
+int C_CheckBox::setchecked_id=0;
+int C_CheckBox::ischecked_id=0;
+int C_CheckBox::settext_id=0;
+int C_CheckBox::gettext_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_checkbox.h b/Src/Wasabi/api/script/objects/c_script/c_checkbox.h
new file mode 100644
index 00000000..7a42a810
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_checkbox.h
@@ -0,0 +1,39 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_CHECKBOX_H
+#define __C_CHECKBOX_H
+
+#include "c_guiobject.h"
+
+#define C_CHECKBOX_PARENT C_GuiObject
+
+class C_CheckBox : public C_CHECKBOX_PARENT {
+ public:
+
+ C_CheckBox(ScriptObject *object);
+ C_CheckBox();
+ virtual ~C_CheckBox();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onToggle(int newstate);
+ virtual void setChecked(int checked);
+ virtual int isChecked();
+ virtual void setText(const wchar_t *txt);
+ virtual const wchar_t *getText();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ontoggle_id;
+ static int setchecked_id;
+ static int ischecked_id;
+ static int settext_id;
+ static int gettext_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_container.cpp b/Src/Wasabi/api/script/objects/c_script/c_container.cpp
new file mode 100644
index 00000000..d9db7641
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_container.cpp
@@ -0,0 +1,179 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_container.h"
+#include <api/script/objcontroller.h>
+
+C_Container::C_Container(ScriptObject *object) : C_RootObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_Container::C_Container() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Container::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, containerGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ onswitchtolayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSwitchToLayout", this);
+ onbeforeswitchtolayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onBeforeSwitchToLayout", this);
+ setxmlparam_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setXmlParam", this);
+ onhidelayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onHideLayout", this);
+ onshowlayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onShowLayout", this);
+ getlayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getLayout", this);
+ getnumlayouts_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumLayouts", this);
+ enumlayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumLayout", this);
+ switchtolayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"switchToLayout", this);
+ show_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"show", this);
+ hide_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"hide", this);
+ close_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"close", this);
+ toggle_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"toggle", this);
+ isdynamic_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isDynamic", this);
+ setname_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setName", this);
+ getcurlayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getCurLayout", this);
+ }
+ inited = 1;
+}
+
+C_Container::~C_Container() {
+}
+
+ScriptObject *C_Container::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_CONTAINER_PARENT::getScriptObject();
+}
+
+void C_Container::onSwitchToLayout(ScriptObject *newlayout) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(newlayout);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onswitchtolayout_id, params);
+}
+
+void C_Container::onBeforeSwitchToLayout(ScriptObject *oldlayout, ScriptObject *newlayout) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(oldlayout);
+ scriptVar b = MAKE_SCRIPT_OBJECT(newlayout);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onbeforeswitchtolayout_id, params);
+}
+
+void C_Container::setXmlParam(const wchar_t *param, const wchar_t *value)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(param);
+ scriptVar b = MAKE_SCRIPT_STRING(value);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setxmlparam_id, params);
+}
+
+void C_Container::onHideLayout(ScriptObject *_layout) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(_layout);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onhidelayout_id, params);
+}
+
+void C_Container::onShowLayout(ScriptObject *_layout) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(_layout);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onshowlayout_id, params);
+}
+
+ScriptObject *C_Container::getLayout(const wchar_t *layout_id)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(layout_id);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getlayout_id, params));
+}
+
+int C_Container::getNumLayouts() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumlayouts_id, NULL));
+}
+
+ScriptObject *C_Container::enumLayout(int num) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(num);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumlayout_id, params));
+}
+
+void C_Container::switchToLayout(const wchar_t *layout_id)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(layout_id);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), switchtolayout_id, params);
+}
+
+void C_Container::show() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), show_id, NULL);
+}
+
+void C_Container::hide() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), hide_id, NULL);
+}
+
+void C_Container::close() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), close_id, NULL);
+}
+
+void C_Container::toggle() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), toggle_id, NULL);
+}
+
+int C_Container::isDynamic() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isdynamic_id, NULL));
+}
+
+void C_Container::setName(const wchar_t *name)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(name);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setname_id, params);
+}
+
+ScriptObject *C_Container::getCurLayout() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcurlayout_id, NULL));
+}
+
+int C_Container::loaded=0;
+int C_Container::onswitchtolayout_id=0;
+int C_Container::onbeforeswitchtolayout_id=0;
+int C_Container::setxmlparam_id=0;
+int C_Container::onhidelayout_id=0;
+int C_Container::onshowlayout_id=0;
+int C_Container::getlayout_id=0;
+int C_Container::getnumlayouts_id=0;
+int C_Container::enumlayout_id=0;
+int C_Container::switchtolayout_id=0;
+int C_Container::show_id=0;
+int C_Container::hide_id=0;
+int C_Container::close_id=0;
+int C_Container::toggle_id=0;
+int C_Container::isdynamic_id=0;
+int C_Container::setname_id=0;
+int C_Container::getcurlayout_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_container.h b/Src/Wasabi/api/script/objects/c_script/c_container.h
new file mode 100644
index 00000000..f3fbe908
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_container.h
@@ -0,0 +1,61 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_CONTAINER_H
+#define __C_CONTAINER_H
+
+#include "c_rootobj.h"
+
+#define C_CONTAINER_PARENT C_RootObject
+
+class C_Container : public C_CONTAINER_PARENT {
+ public:
+
+ C_Container(ScriptObject *object);
+ C_Container();
+ virtual ~C_Container();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onSwitchToLayout(ScriptObject *newlayout);
+ virtual void onBeforeSwitchToLayout(ScriptObject *oldlayout, ScriptObject *newlayout);
+ virtual void setXmlParam(const wchar_t *param, const wchar_t *value);
+ virtual void onHideLayout(ScriptObject *_layout);
+ virtual void onShowLayout(ScriptObject *_layout);
+ virtual ScriptObject *getLayout(const wchar_t *layout_id);
+ virtual int getNumLayouts();
+ virtual ScriptObject *enumLayout(int num);
+ virtual void switchToLayout(const wchar_t *layout_id);
+ virtual void show();
+ virtual void hide();
+ virtual void close();
+ virtual void toggle();
+ virtual int isDynamic();
+ virtual void setName(const wchar_t *name);
+ virtual ScriptObject *getCurLayout();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onswitchtolayout_id;
+ static int onbeforeswitchtolayout_id;
+ static int setxmlparam_id;
+ static int onhidelayout_id;
+ static int onshowlayout_id;
+ static int getlayout_id;
+ static int getnumlayouts_id;
+ static int enumlayout_id;
+ static int switchtolayout_id;
+ static int show_id;
+ static int hide_id;
+ static int close_id;
+ static int toggle_id;
+ static int isdynamic_id;
+ static int setname_id;
+ static int getcurlayout_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_dropdownlist.cpp b/Src/Wasabi/api/script/objects/c_script/c_dropdownlist.cpp
new file mode 100644
index 00000000..2dc719fb
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_dropdownlist.cpp
@@ -0,0 +1,184 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_dropdownlist.h"
+#include <api/script/objcontroller.h>
+
+C_DropDownList::C_DropDownList(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_DropDownList::C_DropDownList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_DropDownList::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, dropDownListGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ getitemselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemSelected", this);
+ onselect_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSelect", this);
+ setlistheight_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setListHeight", this);
+ openlist_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"openList", this);
+ closelist_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"closeList", this);
+ setitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setItems", this);
+ additem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"addItem", this);
+ delitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"delItem", this);
+ finditem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"findItem", this);
+ getnumitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumItems", this);
+ selectitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectItem", this);
+ getitemtext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemText", this);
+ getselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSelected", this);
+ getselectedtext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSelectedText", this);
+ getcustomtext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getCustomText", this);
+ deleteallitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"deleteAllItems", this);
+ setnoitemtext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setNoItemText", this);
+ }
+ inited = 1;
+}
+
+C_DropDownList::~C_DropDownList() {
+}
+
+ScriptObject *C_DropDownList::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_DROPDOWNLIST_PARENT::getScriptObject();
+}
+
+const wchar_t *C_DropDownList::getItemSelected()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemselected_id, NULL));
+}
+
+void C_DropDownList::onSelect(int id, int hover) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(id);
+ scriptVar b = MAKE_SCRIPT_INT(hover);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onselect_id, params);
+}
+
+void C_DropDownList::setListHeight(int h) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(h);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setlistheight_id, params);
+}
+
+void C_DropDownList::openList() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), openlist_id, NULL);
+}
+
+void C_DropDownList::closeList() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), closelist_id, NULL);
+}
+
+void C_DropDownList::setItems(const wchar_t *lotsofitems)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(lotsofitems);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setitems_id, params);
+}
+
+int C_DropDownList::addItem(const wchar_t *_text) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(_text);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), additem_id, params));
+}
+
+void C_DropDownList::delItem(int id) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(id);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), delitem_id, params);
+}
+
+int C_DropDownList::findItem(const wchar_t *_text) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(_text);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), finditem_id, params));
+}
+
+int C_DropDownList::getNumItems() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumitems_id, NULL));
+}
+
+void C_DropDownList::selectItem(int id, int hover) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(id);
+ scriptVar b = MAKE_SCRIPT_INT(hover);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectitem_id, params);
+}
+
+const wchar_t *C_DropDownList::getItemText(int id) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(id);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemtext_id, params));
+}
+
+int C_DropDownList::getSelected() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getselected_id, NULL));
+}
+
+const wchar_t *C_DropDownList::getSelectedText() {
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getselectedtext_id, NULL));
+}
+
+const wchar_t *C_DropDownList::getCustomText() {
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcustomtext_id, NULL));
+}
+
+void C_DropDownList::deleteAllItems() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), deleteallitems_id, NULL);
+}
+
+void C_DropDownList::setNoItemText(const wchar_t *txt) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(txt);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setnoitemtext_id, params);
+}
+
+int C_DropDownList::loaded=0;
+int C_DropDownList::getitemselected_id=0;
+int C_DropDownList::onselect_id=0;
+int C_DropDownList::setlistheight_id=0;
+int C_DropDownList::openlist_id=0;
+int C_DropDownList::closelist_id=0;
+int C_DropDownList::setitems_id=0;
+int C_DropDownList::additem_id=0;
+int C_DropDownList::delitem_id=0;
+int C_DropDownList::finditem_id=0;
+int C_DropDownList::getnumitems_id=0;
+int C_DropDownList::selectitem_id=0;
+int C_DropDownList::getitemtext_id=0;
+int C_DropDownList::getselected_id=0;
+int C_DropDownList::getselectedtext_id=0;
+int C_DropDownList::getcustomtext_id=0;
+int C_DropDownList::deleteallitems_id=0;
+int C_DropDownList::setnoitemtext_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_dropdownlist.h b/Src/Wasabi/api/script/objects/c_script/c_dropdownlist.h
new file mode 100644
index 00000000..3beba99f
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_dropdownlist.h
@@ -0,0 +1,63 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_DROPDOWNLIST_H
+#define __C_DROPDOWNLIST_H
+
+#include "c_guiobject.h"
+
+#define C_DROPDOWNLIST_PARENT C_GuiObject
+
+class C_DropDownList : public C_DROPDOWNLIST_PARENT {
+ public:
+
+ C_DropDownList(ScriptObject *object);
+ C_DropDownList();
+ virtual ~C_DropDownList();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual const wchar_t *getItemSelected();
+ virtual void onSelect(int id, int hover);
+ virtual void setListHeight(int h);
+ virtual void openList();
+ virtual void closeList();
+ virtual void setItems(const wchar_t *lotsofitems);
+ virtual int addItem(const wchar_t *_text);
+ virtual void delItem(int id);
+ virtual int findItem(const wchar_t *_text);
+ virtual int getNumItems();
+ virtual void selectItem(int id, int hover);
+ virtual const wchar_t *getItemText(int id);
+ virtual int getSelected();
+ virtual const wchar_t *getSelectedText();
+ virtual const wchar_t *getCustomText();
+ virtual void deleteAllItems();
+ virtual void setNoItemText(const wchar_t *txt);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int getitemselected_id;
+ static int onselect_id;
+ static int setlistheight_id;
+ static int openlist_id;
+ static int closelist_id;
+ static int setitems_id;
+ static int additem_id;
+ static int delitem_id;
+ static int finditem_id;
+ static int getnumitems_id;
+ static int selectitem_id;
+ static int getitemtext_id;
+ static int getselected_id;
+ static int getselectedtext_id;
+ static int getcustomtext_id;
+ static int deleteallitems_id;
+ static int setnoitemtext_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_edit.cpp b/Src/Wasabi/api/script/objects/c_script/c_edit.cpp
new file mode 100644
index 00000000..4ce40920
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_edit.cpp
@@ -0,0 +1,135 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_edit.h"
+#include <api/script/objcontroller.h>
+
+C_Edit::C_Edit(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_Edit::C_Edit() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Edit::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, editGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ onenter_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onEnter", this);
+ onabort_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onAbort", this);
+ onidleeditupdate_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onIdleEditUpdate", this);
+ oneditupdate_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onEditUpdate", this);
+ settext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setText", this);
+ setautoenter_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setAutoEnter", this);
+ getautoenter_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getAutoEnter", this);
+ gettext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getText", this);
+ selectall_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectAll", this);
+ enter_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enter", this);
+ setidleenabled_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setIdleEnabled", this);
+ getidleenabled_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getIdleEnabled", this);
+ }
+ inited = 1;
+}
+
+C_Edit::~C_Edit() {
+}
+
+ScriptObject *C_Edit::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_EDIT_PARENT::getScriptObject();
+}
+
+void C_Edit::onEnter() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onenter_id, NULL);
+}
+
+void C_Edit::onAbort() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onabort_id, NULL);
+}
+
+void C_Edit::onIdleEditUpdate() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onidleeditupdate_id, NULL);
+}
+
+void C_Edit::onEditUpdate() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), oneditupdate_id, NULL);
+}
+
+void C_Edit::setText(const wchar_t *txt)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(txt);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settext_id, params);
+}
+
+void C_Edit::setAutoEnter(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setautoenter_id, params);
+}
+
+int C_Edit::getAutoEnter() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getautoenter_id, NULL));
+}
+
+const wchar_t *C_Edit::getText()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettext_id, NULL));
+}
+
+void C_Edit::selectAll() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectall_id, NULL);
+}
+
+void C_Edit::enter() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), enter_id, NULL);
+}
+
+void C_Edit::setIdleEnabled(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setidleenabled_id, params);
+}
+
+int C_Edit::getIdleEnabled() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getidleenabled_id, NULL));
+}
+
+int C_Edit::loaded=0;
+int C_Edit::onenter_id=0;
+int C_Edit::onabort_id=0;
+int C_Edit::onidleeditupdate_id=0;
+int C_Edit::oneditupdate_id=0;
+int C_Edit::settext_id=0;
+int C_Edit::setautoenter_id=0;
+int C_Edit::getautoenter_id=0;
+int C_Edit::gettext_id=0;
+int C_Edit::selectall_id=0;
+int C_Edit::enter_id=0;
+int C_Edit::setidleenabled_id=0;
+int C_Edit::getidleenabled_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_edit.h b/Src/Wasabi/api/script/objects/c_script/c_edit.h
new file mode 100644
index 00000000..09f96b24
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_edit.h
@@ -0,0 +1,53 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_EDIT_H
+#define __C_EDIT_H
+
+#include "c_guiobject.h"
+
+#define C_EDIT_PARENT C_GuiObject
+
+class C_Edit : public C_EDIT_PARENT {
+ public:
+
+ C_Edit(ScriptObject *object);
+ C_Edit();
+ virtual ~C_Edit();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onEnter();
+ virtual void onAbort();
+ virtual void onIdleEditUpdate();
+ virtual void onEditUpdate();
+ virtual void setText(const wchar_t *txt);
+ virtual void setAutoEnter(int onoff);
+ virtual int getAutoEnter();
+ virtual const wchar_t *getText();
+ virtual void selectAll();
+ virtual void enter();
+ virtual void setIdleEnabled(int onoff);
+ virtual int getIdleEnabled();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onenter_id;
+ static int onabort_id;
+ static int onidleeditupdate_id;
+ static int oneditupdate_id;
+ static int settext_id;
+ static int setautoenter_id;
+ static int getautoenter_id;
+ static int gettext_id;
+ static int selectall_id;
+ static int enter_id;
+ static int setidleenabled_id;
+ static int getidleenabled_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_group.cpp b/Src/Wasabi/api/script/objects/c_script/c_group.cpp
new file mode 100644
index 00000000..8d0cb037
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_group.cpp
@@ -0,0 +1,99 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_group.h"
+#include <api/script/objcontroller.h>
+
+C_Group::C_Group(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_Group::C_Group() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Group::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, groupGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ getobject_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getObject", this);
+ getnumobjects_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumObjects", this);
+ enumobject_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumObject", this);
+ oncreateobject_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onCreateObject", this);
+ getmouseposx_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getMousePosX", this);
+ getmouseposy_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getMousePosY", this);
+ islayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isLayout", this);
+ }
+ inited = 1;
+}
+
+C_Group::~C_Group() {
+}
+
+ScriptObject *C_Group::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_GROUP_PARENT::getScriptObject();
+}
+
+ScriptObject *C_Group::getObject(const wchar_t *object_id)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(object_id);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getobject_id, params));
+}
+
+int C_Group::getNumObjects() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumobjects_id, NULL));
+}
+
+ScriptObject *C_Group::enumObject(int num) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(num);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumobject_id, params));
+}
+
+void C_Group::onCreateObject(ScriptObject *newobj) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(newobj);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), oncreateobject_id, params);
+}
+
+int C_Group::getMousePosX() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getmouseposx_id, NULL));
+}
+
+int C_Group::getMousePosY() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getmouseposy_id, NULL));
+}
+
+int C_Group::isLayout() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), islayout_id, NULL));
+}
+
+int C_Group::loaded=0;
+int C_Group::getobject_id=0;
+int C_Group::getnumobjects_id=0;
+int C_Group::enumobject_id=0;
+int C_Group::oncreateobject_id=0;
+int C_Group::getmouseposx_id=0;
+int C_Group::getmouseposy_id=0;
+int C_Group::islayout_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_group.h b/Src/Wasabi/api/script/objects/c_script/c_group.h
new file mode 100644
index 00000000..2204ec6f
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_group.h
@@ -0,0 +1,43 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_GROUP_H
+#define __C_GROUP_H
+
+#include "c_guiobject.h"
+
+#define C_GROUP_PARENT C_GuiObject
+
+class C_Group : public C_GROUP_PARENT {
+ public:
+
+ C_Group(ScriptObject *object);
+ C_Group();
+ virtual ~C_Group();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual ScriptObject *getObject(const wchar_t *object_id);
+ virtual int getNumObjects();
+ virtual ScriptObject *enumObject(int num);
+ virtual void onCreateObject(ScriptObject *newobj);
+ virtual int getMousePosX();
+ virtual int getMousePosY();
+ virtual int isLayout();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int getobject_id;
+ static int getnumobjects_id;
+ static int enumobject_id;
+ static int oncreateobject_id;
+ static int getmouseposx_id;
+ static int getmouseposy_id;
+ static int islayout_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_grouplist.cpp b/Src/Wasabi/api/script/objects/c_script/c_grouplist.cpp
new file mode 100644
index 00000000..e5462602
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_grouplist.cpp
@@ -0,0 +1,85 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+#include <api/api.h>
+#include "c_grouplist.h"
+#include <api/script/objcontroller.h>
+
+C_GroupList::C_GroupList(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_GroupList::C_GroupList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_GroupList::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, groupListGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ instantiate_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"instantiate", this);
+ getnumitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumItems", this);
+ enumitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumItem", this);
+ removeall_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"removeAll", this);
+ scrolltopercent_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollToPercent", this);
+ }
+ inited = 1;
+}
+
+C_GroupList::~C_GroupList() {
+}
+
+ScriptObject *C_GroupList::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_GROUPLIST_PARENT::getScriptObject();
+}
+
+ScriptObject *C_GroupList::instantiate(const char *group_id, int num_groups) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(group_id);
+ scriptVar b = MAKE_SCRIPT_INT(num_groups);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), instantiate_id, params));
+}
+
+int C_GroupList::getNumItems() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumitems_id, NULL));
+}
+
+ScriptObject *C_GroupList::enumItem(int num) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(num);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumitem_id, params));
+}
+
+void C_GroupList::removeAll() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), removeall_id, NULL);
+}
+
+void C_GroupList::scrollToPercent(int percent) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(percent);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrolltopercent_id, params);
+}
+
+int C_GroupList::loaded=0;
+int C_GroupList::instantiate_id=0;
+int C_GroupList::getnumitems_id=0;
+int C_GroupList::enumitem_id=0;
+int C_GroupList::removeall_id=0;
+int C_GroupList::scrolltopercent_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_grouplist.h b/Src/Wasabi/api/script/objects/c_script/c_grouplist.h
new file mode 100644
index 00000000..0977e0c4
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_grouplist.h
@@ -0,0 +1,39 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_GROUPLIST_H
+#define __C_GROUPLIST_H
+
+#include "c_guiobject.h"
+
+#define C_GROUPLIST_PARENT C_GuiObject
+
+class C_GroupList : public C_GROUPLIST_PARENT {
+ public:
+
+ C_GroupList(ScriptObject *object);
+ C_GroupList();
+ virtual ~C_GroupList();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual ScriptObject *instantiate(const char *group_id, int num_groups);
+ virtual int getNumItems();
+ virtual ScriptObject *enumItem(int num);
+ virtual void removeAll();
+ virtual void scrollToPercent(int percent);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int instantiate_id;
+ static int getnumitems_id;
+ static int enumitem_id;
+ static int removeall_id;
+ static int scrolltopercent_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_guilist.cpp b/Src/Wasabi/api/script/objects/c_script/c_guilist.cpp
new file mode 100644
index 00000000..f28e168a
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_guilist.cpp
@@ -0,0 +1,722 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_guilist.h"
+#include <api/script/objcontroller.h>
+
+C_GuiList::C_GuiList(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_GuiList::C_GuiList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_GuiList::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, guiListGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ getnumitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumItems", this);
+ getwantautodeselect_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getWantAutoDeselect", this);
+ setwantautodeselect_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setWantAutoDeselect", this);
+ onsetvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSetVisible", this);
+ setautosort_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setAutoSort", this);
+ next_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"next", this);
+ selectcurrent_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectCurrent", this);
+ selectfirstentry_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectFirstEntry", this);
+ previous_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"previous", this);
+ pagedown_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"pagedown", this);
+ pageup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"pageup", this);
+ home_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"home", this);
+ end_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"end", this);
+ reset_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"reset", this);
+ addcolumn_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"addColumn", this);
+ getnumcolumns_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumColumns", this);
+ getcolumnwidth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getColumnWidth", this);
+ setcolumnwidth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setColumnWidth", this);
+ getcolumnlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getColumnLabel", this);
+ setcolumnlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setColumnLabel", this);
+ getcolumnnumeric_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getColumnNumeric", this);
+ setcolumndynamic_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setColumnDynamic", this);
+ iscolumndynamic_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isColumnDynamic", this);
+ setminimumsize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setMinimumSize", this);
+ additem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"addItem", this);
+ insertitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"insertItem", this);
+ getlastaddeditempos_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getLastAddedItemPos", this);
+ setsubitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSubItem", this);
+ deleteallitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"deleteAllItems", this);
+ deletebypos_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"deleteByPos", this);
+ getitemlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemLabel", this);
+ setitemlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setItemLabel", this);
+ getitemselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemSelected", this);
+ isitemfocused_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isItemFocused", this);
+ getitemfocused_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemFocused", this);
+ setitemfocused_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setItemFocused", this);
+ ensureitemvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"ensureItemVisible", this);
+ invalidatecolumns_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"invalidateColumns", this);
+ scrollabsolute_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollAbsolute", this);
+ scrollrelative_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollRelative", this);
+ scrollleft_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollLeft", this);
+ scrollright_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollRight", this);
+ scrollup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollUp", this);
+ scrolldown_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollDown", this);
+ getsubitemtext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSubitemText", this);
+ getfirstitemselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getFirstItemSelected", this);
+ getnextitemselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNextItemSelected", this);
+ selectall_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectAll", this);
+ deselectall_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"deselectAll", this);
+ invertselection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"invertSelection", this);
+ invalidateitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"invalidateItem", this);
+ getfirstitemvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getFirstItemVisible", this);
+ getlastitemvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getLastItemVisible", this);
+ setfontsize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setFontSize", this);
+ getfontsize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getFontSize", this);
+ jumptonext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"jumpToNext", this);
+ scrolltoitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"scrollToItem", this);
+ resort_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"resort", this);
+ getsortdirection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSortDirection", this);
+ getsortcolumn_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSortColumn", this);
+ setsortcolumn_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSortColumn", this);
+ setsortdirection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSortDirection", this);
+ getitemcount_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemCount", this);
+ setselectionstart_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSelectionStart", this);
+ setselectionend_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSelectionEnd", this);
+ setselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSelected", this);
+ toggleselection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"toggleSelection", this);
+ getheaderheight_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getHeaderHeight", this);
+ getpreventmultipleselection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getPreventMultipleSelection", this);
+ setpreventmultipleselection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setPreventMultipleSelection", this);
+ moveitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"moveItem", this);
+ onselectall_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSelectAll", this);
+ ondelete_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onDelete", this);
+ ondoubleclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onDoubleClick", this);
+ onleftclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeftClick", this);
+ onsecondleftclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSecondLeftClick", this);
+ onrightclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onRightClick", this);
+ oncolumndblclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onColumnDblClick", this);
+ oncolumnlabelclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onColumnLabelClick", this);
+ onitemselection_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onItemSelection", this);
+ }
+ inited = 1;
+}
+
+C_GuiList::~C_GuiList() {
+}
+
+ScriptObject *C_GuiList::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_GUILIST_PARENT::getScriptObject();
+}
+
+int C_GuiList::getNumItems() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumitems_id, NULL));
+}
+
+int C_GuiList::getWantAutoDeselect() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getwantautodeselect_id, NULL));
+}
+
+void C_GuiList::setWantAutoDeselect(int want) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(want);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setwantautodeselect_id, params);
+}
+
+void C_GuiList::onSetVisible(int show) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(show);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onsetvisible_id, params);
+}
+
+void C_GuiList::setAutoSort(int dosort) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(dosort);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setautosort_id, params);
+}
+
+void C_GuiList::next() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), next_id, NULL);
+}
+
+void C_GuiList::selectCurrent() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectcurrent_id, NULL);
+}
+
+void C_GuiList::selectFirstEntry() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectfirstentry_id, NULL);
+}
+
+void C_GuiList::previous() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), previous_id, NULL);
+}
+
+void C_GuiList::pagedown() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), pagedown_id, NULL);
+}
+
+void C_GuiList::pageup() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), pageup_id, NULL);
+}
+
+void C_GuiList::home() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), home_id, NULL);
+}
+
+void C_GuiList::end() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), end_id, NULL);
+}
+
+void C_GuiList::reset() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), reset_id, NULL);
+}
+
+int C_GuiList::addColumn(const wchar_t *name, int width, int numeric)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(name);
+ scriptVar b = MAKE_SCRIPT_INT(width);
+ scriptVar c = MAKE_SCRIPT_INT(numeric);
+ scriptVar *params[3] = {&a, &b, &c};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), addcolumn_id, params));
+}
+
+int C_GuiList::getNumColumns() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumcolumns_id, NULL));
+}
+
+int C_GuiList::getColumnWidth(int column) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcolumnwidth_id, params));
+}
+
+void C_GuiList::setColumnWidth(int column, int newwidth) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar b = MAKE_SCRIPT_INT(newwidth);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setcolumnwidth_id, params);
+}
+
+const wchar_t *C_GuiList::getColumnLabel(int column) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcolumnlabel_id, params));
+}
+
+void C_GuiList::setColumnLabel(int column, const wchar_t *newlabel) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar b = MAKE_SCRIPT_STRING(newlabel);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setcolumnlabel_id, params);
+}
+
+int C_GuiList::getColumnNumeric(int column) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcolumnnumeric_id, params));
+}
+
+void C_GuiList::setColumnDynamic(int column, int isdynamic) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar b = MAKE_SCRIPT_INT(isdynamic);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setcolumndynamic_id, params);
+}
+
+int C_GuiList::isColumnDynamic(int column) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(column);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), iscolumndynamic_id, params));
+}
+
+void C_GuiList::setMinimumSize(int size) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(size);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setminimumsize_id, params);
+}
+
+int C_GuiList::addItem(const wchar_t *label)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(label);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), additem_id, params));
+}
+
+int C_GuiList::insertItem(int pos, const wchar_t *label) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_STRING(label);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), insertitem_id, params));
+}
+
+int C_GuiList::getLastAddedItemPos() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getlastaddeditempos_id, NULL));
+}
+
+void C_GuiList::setSubItem(int pos, int subpos, const wchar_t *txt) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_INT(subpos);
+ scriptVar c = MAKE_SCRIPT_STRING(txt);
+ scriptVar *params[3] = {&a, &b, &c};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setsubitem_id, params);
+}
+
+void C_GuiList::deleteAllItems() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), deleteallitems_id, NULL);
+}
+
+int C_GuiList::deleteByPos(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), deletebypos_id, params));
+}
+
+const wchar_t *C_GuiList::getItemLabel(int pos, int subpos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_INT(subpos);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemlabel_id, params));
+}
+
+void C_GuiList::setItemLabel(int pos, const wchar_t *_text) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_STRING(_text);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setitemlabel_id, params);
+}
+
+int C_GuiList::getItemSelected(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemselected_id, params));
+}
+
+int C_GuiList::isItemFocused(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isitemfocused_id, params));
+}
+
+int C_GuiList::getItemFocused() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemfocused_id, NULL));
+}
+
+void C_GuiList::setItemFocused(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setitemfocused_id, params);
+}
+
+void C_GuiList::ensureItemVisible(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ensureitemvisible_id, params);
+}
+
+void C_GuiList::invalidateColumns() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), invalidatecolumns_id, NULL);
+}
+
+int C_GuiList::scrollAbsolute(int x) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrollabsolute_id, params));
+}
+
+int C_GuiList::scrollRelative(int x) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrollrelative_id, params));
+}
+
+void C_GuiList::scrollLeft(int lines) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(lines);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrollleft_id, params);
+}
+
+void C_GuiList::scrollRight(int lines) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(lines);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrollright_id, params);
+}
+
+void C_GuiList::scrollUp(int lines) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(lines);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrollup_id, params);
+}
+
+void C_GuiList::scrollDown(int lines) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(lines);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrolldown_id, params);
+}
+
+const wchar_t *C_GuiList::getSubitemText(int pos, int subpos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_INT(subpos);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsubitemtext_id, params));
+}
+
+int C_GuiList::getFirstItemSelected() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getfirstitemselected_id, NULL));
+}
+
+int C_GuiList::getNextItemSelected(int lastpos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(lastpos);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnextitemselected_id, params));
+}
+
+int C_GuiList::selectAll() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectall_id, NULL));
+}
+
+int C_GuiList::deselectAll() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), deselectall_id, NULL));
+}
+
+int C_GuiList::invertSelection() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), invertselection_id, NULL));
+}
+
+int C_GuiList::invalidateItem(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), invalidateitem_id, params));
+}
+
+int C_GuiList::getFirstItemVisible() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getfirstitemvisible_id, NULL));
+}
+
+int C_GuiList::getLastItemVisible() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getlastitemvisible_id, NULL));
+}
+
+int C_GuiList::setFontSize(int size) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(size);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), setfontsize_id, params));
+}
+
+int C_GuiList::getFontSize() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getfontsize_id, NULL));
+}
+
+void C_GuiList::jumpToNext(int c) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(c);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), jumptonext_id, params);
+}
+
+void C_GuiList::scrollToItem(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), scrolltoitem_id, params);
+}
+
+void C_GuiList::resort() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), resort_id, NULL);
+}
+
+int C_GuiList::getSortDirection() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsortdirection_id, NULL));
+}
+
+int C_GuiList::getSortColumn() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsortcolumn_id, NULL));
+}
+
+void C_GuiList::setSortColumn(int col) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(col);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setsortcolumn_id, params);
+}
+
+void C_GuiList::setSortDirection(int dir) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(dir);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setsortdirection_id, params);
+}
+
+int C_GuiList::getItemCount() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemcount_id, NULL));
+}
+
+void C_GuiList::setSelectionStart(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setselectionstart_id, params);
+}
+
+void C_GuiList::setSelectionEnd(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setselectionend_id, params);
+}
+
+void C_GuiList::setSelected(int pos, int selected) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_INT(selected);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setselected_id, params);
+}
+
+void C_GuiList::toggleSelection(int pos, int setfocus) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar b = MAKE_SCRIPT_INT(setfocus);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), toggleselection_id, params);
+}
+
+int C_GuiList::getHeaderHeight() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getheaderheight_id, NULL));
+}
+
+int C_GuiList::getPreventMultipleSelection() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getpreventmultipleselection_id, NULL));
+}
+
+int C_GuiList::setPreventMultipleSelection(int val) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(val);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), setpreventmultipleselection_id, params));
+}
+
+void C_GuiList::moveItem(int from, int to) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(from);
+ scriptVar b = MAKE_SCRIPT_INT(to);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), moveitem_id, params);
+}
+
+void C_GuiList::onSelectAll() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onselectall_id, NULL);
+}
+
+void C_GuiList::onDelete() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ondelete_id, NULL);
+}
+
+void C_GuiList::onDoubleClick(int itemnum) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(itemnum);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ondoubleclick_id, params);
+}
+
+void C_GuiList::onLeftClick(int itemnum) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(itemnum);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleftclick_id, params);
+}
+
+void C_GuiList::onSecondLeftClick(int itemnum) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(itemnum);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onsecondleftclick_id, params);
+}
+
+int C_GuiList::onRightClick(int itemnum) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(itemnum);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onrightclick_id, params));
+}
+
+int C_GuiList::onColumnDblClick(int col, int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(col);
+ scriptVar b = MAKE_SCRIPT_INT(x);
+ scriptVar c = MAKE_SCRIPT_INT(y);
+ scriptVar *params[3] = {&a, &b, &c};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), oncolumndblclick_id, params));
+}
+
+int C_GuiList::onColumnLabelClick(int col, int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(col);
+ scriptVar b = MAKE_SCRIPT_INT(x);
+ scriptVar c = MAKE_SCRIPT_INT(y);
+ scriptVar *params[3] = {&a, &b, &c};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), oncolumnlabelclick_id, params));
+}
+
+void C_GuiList::onItemSelection(int itemnum, int selected) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(itemnum);
+ scriptVar b = MAKE_SCRIPT_INT(selected);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onitemselection_id, params);
+}
+
+int C_GuiList::loaded=0;
+int C_GuiList::getnumitems_id=0;
+int C_GuiList::getwantautodeselect_id=0;
+int C_GuiList::setwantautodeselect_id=0;
+int C_GuiList::onsetvisible_id=0;
+int C_GuiList::setautosort_id=0;
+int C_GuiList::next_id=0;
+int C_GuiList::selectcurrent_id=0;
+int C_GuiList::selectfirstentry_id=0;
+int C_GuiList::previous_id=0;
+int C_GuiList::pagedown_id=0;
+int C_GuiList::pageup_id=0;
+int C_GuiList::home_id=0;
+int C_GuiList::end_id=0;
+int C_GuiList::reset_id=0;
+int C_GuiList::addcolumn_id=0;
+int C_GuiList::getnumcolumns_id=0;
+int C_GuiList::getcolumnwidth_id=0;
+int C_GuiList::setcolumnwidth_id=0;
+int C_GuiList::getcolumnlabel_id=0;
+int C_GuiList::setcolumnlabel_id=0;
+int C_GuiList::getcolumnnumeric_id=0;
+int C_GuiList::setcolumndynamic_id=0;
+int C_GuiList::iscolumndynamic_id=0;
+int C_GuiList::setminimumsize_id=0;
+int C_GuiList::additem_id=0;
+int C_GuiList::insertitem_id=0;
+int C_GuiList::getlastaddeditempos_id=0;
+int C_GuiList::setsubitem_id=0;
+int C_GuiList::deleteallitems_id=0;
+int C_GuiList::deletebypos_id=0;
+int C_GuiList::getitemlabel_id=0;
+int C_GuiList::setitemlabel_id=0;
+int C_GuiList::getitemselected_id=0;
+int C_GuiList::isitemfocused_id=0;
+int C_GuiList::getitemfocused_id=0;
+int C_GuiList::setitemfocused_id=0;
+int C_GuiList::ensureitemvisible_id=0;
+int C_GuiList::invalidatecolumns_id=0;
+int C_GuiList::scrollabsolute_id=0;
+int C_GuiList::scrollrelative_id=0;
+int C_GuiList::scrollleft_id=0;
+int C_GuiList::scrollright_id=0;
+int C_GuiList::scrollup_id=0;
+int C_GuiList::scrolldown_id=0;
+int C_GuiList::getsubitemtext_id=0;
+int C_GuiList::getfirstitemselected_id=0;
+int C_GuiList::getnextitemselected_id=0;
+int C_GuiList::selectall_id=0;
+int C_GuiList::deselectall_id=0;
+int C_GuiList::invertselection_id=0;
+int C_GuiList::invalidateitem_id=0;
+int C_GuiList::getfirstitemvisible_id=0;
+int C_GuiList::getlastitemvisible_id=0;
+int C_GuiList::setfontsize_id=0;
+int C_GuiList::getfontsize_id=0;
+int C_GuiList::jumptonext_id=0;
+int C_GuiList::scrolltoitem_id=0;
+int C_GuiList::resort_id=0;
+int C_GuiList::getsortdirection_id=0;
+int C_GuiList::getsortcolumn_id=0;
+int C_GuiList::setsortcolumn_id=0;
+int C_GuiList::setsortdirection_id=0;
+int C_GuiList::getitemcount_id=0;
+int C_GuiList::setselectionstart_id=0;
+int C_GuiList::setselectionend_id=0;
+int C_GuiList::setselected_id=0;
+int C_GuiList::toggleselection_id=0;
+int C_GuiList::getheaderheight_id=0;
+int C_GuiList::getpreventmultipleselection_id=0;
+int C_GuiList::setpreventmultipleselection_id=0;
+int C_GuiList::moveitem_id=0;
+int C_GuiList::onselectall_id=0;
+int C_GuiList::ondelete_id=0;
+int C_GuiList::ondoubleclick_id=0;
+int C_GuiList::onleftclick_id=0;
+int C_GuiList::onsecondleftclick_id=0;
+int C_GuiList::onrightclick_id=0;
+int C_GuiList::oncolumndblclick_id=0;
+int C_GuiList::oncolumnlabelclick_id=0;
+int C_GuiList::onitemselection_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_guilist.h b/Src/Wasabi/api/script/objects/c_script/c_guilist.h
new file mode 100644
index 00000000..8fbc54d3
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_guilist.h
@@ -0,0 +1,189 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_GUILIST_H
+#define __C_GUILIST_H
+
+#include "c_guiobject.h"
+
+#define C_GUILIST_PARENT C_GuiObject
+
+class C_GuiList : public C_GUILIST_PARENT {
+ public:
+
+ C_GuiList(ScriptObject *object);
+ C_GuiList();
+ virtual ~C_GuiList();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual int getNumItems();
+ virtual int getWantAutoDeselect();
+ virtual void setWantAutoDeselect(int want);
+ virtual void onSetVisible(int show);
+ virtual void setAutoSort(int dosort);
+ virtual void next();
+ virtual void selectCurrent();
+ virtual void selectFirstEntry();
+ virtual void previous();
+ virtual void pagedown();
+ virtual void pageup();
+ virtual void home();
+ virtual void end();
+ virtual void reset();
+ virtual int addColumn(const wchar_t *name, int width, int numeric);
+ virtual int getNumColumns();
+ virtual int getColumnWidth(int column);
+ virtual void setColumnWidth(int column, int newwidth);
+ virtual const wchar_t *getColumnLabel(int column);
+ virtual void setColumnLabel(int column, const wchar_t *newlabel);
+ virtual int getColumnNumeric(int column);
+ virtual void setColumnDynamic(int column, int isdynamic);
+ virtual int isColumnDynamic(int column);
+ virtual void setMinimumSize(int size);
+ virtual int addItem(const wchar_t *label);
+ virtual int insertItem(int pos, const wchar_t *label);
+ virtual int getLastAddedItemPos();
+ virtual void setSubItem(int pos, int subpos, const wchar_t *txt);
+ virtual void deleteAllItems();
+ virtual int deleteByPos(int pos);
+ virtual const wchar_t *getItemLabel(int pos, int subpos);
+ virtual void setItemLabel(int pos, const wchar_t *_text);
+ virtual int getItemSelected(int pos);
+ virtual int isItemFocused(int pos);
+ virtual int getItemFocused();
+ virtual void setItemFocused(int pos);
+ virtual void ensureItemVisible(int pos);
+ virtual void invalidateColumns();
+ virtual int scrollAbsolute(int x);
+ virtual int scrollRelative(int x);
+ virtual void scrollLeft(int lines);
+ virtual void scrollRight(int lines);
+ virtual void scrollUp(int lines);
+ virtual void scrollDown(int lines);
+ virtual const wchar_t *getSubitemText(int pos, int subpos);
+ virtual int getFirstItemSelected();
+ virtual int getNextItemSelected(int lastpos);
+ virtual int selectAll();
+ virtual int deselectAll();
+ virtual int invertSelection();
+ virtual int invalidateItem(int pos);
+ virtual int getFirstItemVisible();
+ virtual int getLastItemVisible();
+ virtual int setFontSize(int size);
+ virtual int getFontSize();
+ virtual void jumpToNext(int c);
+ virtual void scrollToItem(int pos);
+ virtual void resort();
+ virtual int getSortDirection();
+ virtual int getSortColumn();
+ virtual void setSortColumn(int col);
+ virtual void setSortDirection(int dir);
+ virtual int getItemCount();
+ virtual void setSelectionStart(int pos);
+ virtual void setSelectionEnd(int pos);
+ virtual void setSelected(int pos, int selected);
+ virtual void toggleSelection(int pos, int setfocus);
+ virtual int getHeaderHeight();
+ virtual int getPreventMultipleSelection();
+ virtual int setPreventMultipleSelection(int val);
+ virtual void moveItem(int from, int to);
+ virtual void onSelectAll();
+ virtual void onDelete();
+ virtual void onDoubleClick(int itemnum);
+ virtual void onLeftClick(int itemnum);
+ virtual void onSecondLeftClick(int itemnum);
+ virtual int onRightClick(int itemnum);
+ virtual int onColumnDblClick(int col, int x, int y);
+ virtual int onColumnLabelClick(int col, int x, int y);
+ virtual void onItemSelection(int itemnum, int selected);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int getnumitems_id;
+ static int getwantautodeselect_id;
+ static int setwantautodeselect_id;
+ static int onsetvisible_id;
+ static int setautosort_id;
+ static int next_id;
+ static int selectcurrent_id;
+ static int selectfirstentry_id;
+ static int previous_id;
+ static int pagedown_id;
+ static int pageup_id;
+ static int home_id;
+ static int end_id;
+ static int reset_id;
+ static int addcolumn_id;
+ static int getnumcolumns_id;
+ static int getcolumnwidth_id;
+ static int setcolumnwidth_id;
+ static int getcolumnlabel_id;
+ static int setcolumnlabel_id;
+ static int getcolumnnumeric_id;
+ static int setcolumndynamic_id;
+ static int iscolumndynamic_id;
+ static int setminimumsize_id;
+ static int additem_id;
+ static int insertitem_id;
+ static int getlastaddeditempos_id;
+ static int setsubitem_id;
+ static int deleteallitems_id;
+ static int deletebypos_id;
+ static int getitemlabel_id;
+ static int setitemlabel_id;
+ static int getitemselected_id;
+ static int isitemfocused_id;
+ static int getitemfocused_id;
+ static int setitemfocused_id;
+ static int ensureitemvisible_id;
+ static int invalidatecolumns_id;
+ static int scrollabsolute_id;
+ static int scrollrelative_id;
+ static int scrollleft_id;
+ static int scrollright_id;
+ static int scrollup_id;
+ static int scrolldown_id;
+ static int getsubitemtext_id;
+ static int getfirstitemselected_id;
+ static int getnextitemselected_id;
+ static int selectall_id;
+ static int deselectall_id;
+ static int invertselection_id;
+ static int invalidateitem_id;
+ static int getfirstitemvisible_id;
+ static int getlastitemvisible_id;
+ static int setfontsize_id;
+ static int getfontsize_id;
+ static int jumptonext_id;
+ static int scrolltoitem_id;
+ static int resort_id;
+ static int getsortdirection_id;
+ static int getsortcolumn_id;
+ static int setsortcolumn_id;
+ static int setsortdirection_id;
+ static int getitemcount_id;
+ static int setselectionstart_id;
+ static int setselectionend_id;
+ static int setselected_id;
+ static int toggleselection_id;
+ static int getheaderheight_id;
+ static int getpreventmultipleselection_id;
+ static int setpreventmultipleselection_id;
+ static int moveitem_id;
+ static int onselectall_id;
+ static int ondelete_id;
+ static int ondoubleclick_id;
+ static int onleftclick_id;
+ static int onsecondleftclick_id;
+ static int onrightclick_id;
+ static int oncolumndblclick_id;
+ static int oncolumnlabelclick_id;
+ static int onitemselection_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_guiobject.cpp b/Src/Wasabi/api/script/objects/c_script/c_guiobject.cpp
new file mode 100644
index 00000000..0b7add98
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_guiobject.cpp
@@ -0,0 +1,739 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_guiobject.h"
+#include <api/script/objcontroller.h>
+
+C_GuiObject::C_GuiObject(ScriptObject *object) : C_RootObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_GuiObject::C_GuiObject() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_GuiObject::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, guiObjectGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ show_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"show", this);
+ hide_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"hide", this);
+ isvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isVisible", this);
+ onsetvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSetVisible", this);
+ setalpha_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setAlpha", this);
+ getalpha_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getAlpha", this);
+ onleftbuttonup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeftButtonUp", this);
+ onleftbuttondown_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeftButtonDown", this);
+ onrightbuttonup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onRightButtonUp", this);
+ onrightbuttondown_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onRightButtonDown", this);
+ onrightbuttondblclk_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onRightButtonDblClk", this);
+ onleftbuttondblclk_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeftButtonDblClk", this);
+ onmousemove_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMouseMove", this);
+ onenterarea_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onEnterArea", this);
+ onleavearea_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeaveArea", this);
+ setenabled_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setEnabled", this);
+ getenabled_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getEnabled", this);
+ onenable_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onEnable", this);
+ resize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"resize", this);
+ onresize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onResize", this);
+ ismouseover_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isMouseOver", this);
+ getleft_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getLeft", this);
+ gettop_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getTop", this);
+ getwidth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getWidth", this);
+ getheight_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getHeight", this);
+ settargetx_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetX", this);
+ settargety_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetY", this);
+ settargetw_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetW", this);
+ settargeth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetH", this);
+ settargeta_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetA", this);
+ settargetspeed_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setTargetSpeed", this);
+ gototarget_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"gotoTarget", this);
+ ontargetreached_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onTargetReached", this);
+ canceltarget_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"cancelTarget", this);
+ reversetarget_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"reverseTarget", this);
+ onstartup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onStartup", this);
+ isgoingtotarget_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isGoingToTarget", this);
+ setxmlparam_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setXmlParam", this);
+ getxmlparam_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getXmlParam", this);
+ init_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"init", this);
+ bringtofront_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"bringToFront", this);
+ bringtoback_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"bringToBack", this);
+ bringabove_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"bringAbove", this);
+ bringbelow_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"bringBelow", this);
+ getguix_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiX", this);
+ getguiy_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiY", this);
+ getguiw_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiW", this);
+ getguih_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiH", this);
+ getguirelatx_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiRelatX", this);
+ getguirelaty_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiRelatY", this);
+ getguirelatw_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiRelatW", this);
+ getguirelath_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getGuiRelatH", this);
+ isactive_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isActive", this);
+ getparent_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getParent", this);
+ getparentlayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getParentLayout", this);
+ gettopparent_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getTopParent", this);
+ runmodal_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"runModal", this);
+ endmodal_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"endModal", this);
+ findobject_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"findObject", this);
+ findobjectxy_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"findObjectXY", this);
+ getname_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getName", this);
+ clienttoscreenx_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"clientToScreenX", this);
+ clienttoscreeny_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"clientToScreenY", this);
+ clienttoscreenw_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"clientToScreenW", this);
+ clienttoscreenh_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"clientToScreenH", this);
+ screentoclientx_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"screenToClientX", this);
+ screentoclienty_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"screenToClientY", this);
+ screentoclientw_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"screenToClientW", this);
+ screentoclienth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"screenToClientH", this);
+ getautowidth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getAutoWidth", this);
+ getautoheight_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getAutoHeight", this);
+ setfocus_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setFocus", this);
+ onchar_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onChar", this);
+ onaccelerator_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onAccelerator", this);
+ ismouseoverrect_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isMouseOverRect", this);
+ getinterface_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getInterface", this);
+ onkeydown_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onKeyDown", this);
+ onkeyup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onKeyUp", this);
+ ongetfocus_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onGetFocus", this);
+ onkillfocus_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onKillFocus", this);
+ sendaction_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"sendAction", this);
+ onaction_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onAction", this);
+ }
+ inited = 1;
+}
+
+C_GuiObject::~C_GuiObject() {
+}
+
+ScriptObject *C_GuiObject::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_GUIOBJECT_PARENT::getScriptObject();
+}
+
+void C_GuiObject::show() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), show_id, NULL);
+}
+
+void C_GuiObject::hide() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), hide_id, NULL);
+}
+
+int C_GuiObject::isVisible() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isvisible_id, NULL));
+}
+
+void C_GuiObject::onSetVisible(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onsetvisible_id, params);
+}
+
+void C_GuiObject::setAlpha(int alpha) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(alpha);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setalpha_id, params);
+}
+
+int C_GuiObject::getAlpha() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getalpha_id, NULL));
+}
+
+void C_GuiObject::onLeftButtonUp(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleftbuttonup_id, params);
+}
+
+void C_GuiObject::onLeftButtonDown(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleftbuttondown_id, params);
+}
+
+void C_GuiObject::onRightButtonUp(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onrightbuttonup_id, params);
+}
+
+void C_GuiObject::onRightButtonDown(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onrightbuttondown_id, params);
+}
+
+void C_GuiObject::onRightButtonDblClk(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onrightbuttondblclk_id, params);
+}
+
+void C_GuiObject::onLeftButtonDblClk(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleftbuttondblclk_id, params);
+}
+
+void C_GuiObject::onMouseMove(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmousemove_id, params);
+}
+
+void C_GuiObject::onEnterArea() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onenterarea_id, NULL);
+}
+
+void C_GuiObject::onLeaveArea() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleavearea_id, NULL);
+}
+
+void C_GuiObject::setEnabled(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setenabled_id, params);
+}
+
+int C_GuiObject::getEnabled() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getenabled_id, NULL));
+}
+
+void C_GuiObject::onEnable(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onenable_id, params);
+}
+
+void C_GuiObject::resize(int x, int y, int w, int h) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar c = MAKE_SCRIPT_INT(w);
+ scriptVar d = MAKE_SCRIPT_INT(h);
+ scriptVar *params[4] = {&a, &b, &c, &d};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), resize_id, params);
+}
+
+void C_GuiObject::onResize(int x, int y, int w, int h) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar c = MAKE_SCRIPT_INT(w);
+ scriptVar d = MAKE_SCRIPT_INT(h);
+ scriptVar *params[4] = {&a, &b, &c, &d};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onresize_id, params);
+}
+
+int C_GuiObject::isMouseOver(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), ismouseover_id, params));
+}
+
+int C_GuiObject::getLeft() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getleft_id, NULL));
+}
+
+int C_GuiObject::getTop() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettop_id, NULL));
+}
+
+int C_GuiObject::getWidth() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getwidth_id, NULL));
+}
+
+int C_GuiObject::getHeight() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getheight_id, NULL));
+}
+
+void C_GuiObject::setTargetX(int x) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargetx_id, params);
+}
+
+void C_GuiObject::setTargetY(int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(y);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargety_id, params);
+}
+
+void C_GuiObject::setTargetW(int w) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(w);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargetw_id, params);
+}
+
+void C_GuiObject::setTargetH(int r) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(r);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargeth_id, params);
+}
+
+void C_GuiObject::setTargetA(int alpha) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(alpha);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargeta_id, params);
+}
+
+void C_GuiObject::setTargetSpeed(float insecond) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_FLOAT(insecond);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settargetspeed_id, params);
+}
+
+void C_GuiObject::gotoTarget() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), gototarget_id, NULL);
+}
+
+void C_GuiObject::onTargetReached() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ontargetreached_id, NULL);
+}
+
+void C_GuiObject::cancelTarget() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), canceltarget_id, NULL);
+}
+
+void C_GuiObject::reverseTarget(int reverse) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(reverse);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), reversetarget_id, params);
+}
+
+void C_GuiObject::onStartup() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onstartup_id, NULL);
+}
+
+int C_GuiObject::isGoingToTarget() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isgoingtotarget_id, NULL));
+}
+
+void C_GuiObject::setXmlParam(const wchar_t *param, const wchar_t *value)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(param);
+ scriptVar b = MAKE_SCRIPT_STRING(value);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setxmlparam_id, params);
+}
+
+const wchar_t *C_GuiObject::getXmlParam(const wchar_t *param)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(param);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getxmlparam_id, params));
+}
+
+void C_GuiObject::init(ScriptObject *parent) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(parent);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), init_id, params);
+}
+
+void C_GuiObject::bringToFront() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), bringtofront_id, NULL);
+}
+
+void C_GuiObject::bringToBack() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), bringtoback_id, NULL);
+}
+
+void C_GuiObject::bringAbove(ScriptObject *guiobj) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(guiobj);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), bringabove_id, params);
+}
+
+void C_GuiObject::bringBelow(ScriptObject *guiobj) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(guiobj);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), bringbelow_id, params);
+}
+
+int C_GuiObject::getGuiX() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguix_id, NULL));
+}
+
+int C_GuiObject::getGuiY() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguiy_id, NULL));
+}
+
+int C_GuiObject::getGuiW() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguiw_id, NULL));
+}
+
+int C_GuiObject::getGuiH() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguih_id, NULL));
+}
+
+int C_GuiObject::getGuiRelatX() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguirelatx_id, NULL));
+}
+
+int C_GuiObject::getGuiRelatY() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguirelaty_id, NULL));
+}
+
+int C_GuiObject::getGuiRelatW() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguirelatw_id, NULL));
+}
+
+int C_GuiObject::getGuiRelatH() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getguirelath_id, NULL));
+}
+
+int C_GuiObject::isActive() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isactive_id, NULL));
+}
+
+ScriptObject *C_GuiObject::getParent() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getparent_id, NULL));
+}
+
+ScriptObject *C_GuiObject::getParentLayout() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getparentlayout_id, NULL));
+}
+
+ScriptObject *C_GuiObject::getTopParent() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettopparent_id, NULL));
+}
+
+int C_GuiObject::runModal() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), runmodal_id, NULL));
+}
+
+void C_GuiObject::endModal(int retcode) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(retcode);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), endmodal_id, params);
+}
+
+ScriptObject *C_GuiObject::findObject(const wchar_t *id)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(id);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), findobject_id, params));
+}
+
+ScriptObject *C_GuiObject::findObjectXY(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), findobjectxy_id, params));
+}
+
+const wchar_t *C_GuiObject::getName()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getname_id, NULL));
+}
+
+int C_GuiObject::clientToScreenX(int x) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), clienttoscreenx_id, params));
+}
+
+int C_GuiObject::clientToScreenY(int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(y);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), clienttoscreeny_id, params));
+}
+
+int C_GuiObject::clientToScreenW(int w) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(w);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), clienttoscreenw_id, params));
+}
+
+int C_GuiObject::clientToScreenH(int h) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(h);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), clienttoscreenh_id, params));
+}
+
+int C_GuiObject::screenToClientX(int x) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), screentoclientx_id, params));
+}
+
+int C_GuiObject::screenToClientY(int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(y);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), screentoclienty_id, params));
+}
+
+int C_GuiObject::screenToClientW(int w) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(w);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), screentoclientw_id, params));
+}
+
+int C_GuiObject::screenToClientH(int h) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(h);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), screentoclienth_id, params));
+}
+
+int C_GuiObject::getAutoWidth() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getautowidth_id, NULL));
+}
+
+int C_GuiObject::getAutoHeight() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getautoheight_id, NULL));
+}
+
+void C_GuiObject::setFocus() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setfocus_id, NULL);
+}
+
+void C_GuiObject::onChar(const wchar_t *c)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(c);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onchar_id, params);
+}
+
+void C_GuiObject::onAccelerator(const wchar_t *accel) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(accel);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onaccelerator_id, params);
+}
+
+int C_GuiObject::isMouseOverRect() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), ismouseoverrect_id, NULL));
+}
+
+ScriptObject *C_GuiObject::getInterface(const wchar_t *interface_guid)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(interface_guid);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getinterface_id, params));
+}
+
+void C_GuiObject::onKeyDown(int vk_code) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(vk_code);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onkeydown_id, params);
+}
+
+void C_GuiObject::onKeyUp(int vk_code) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(vk_code);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onkeyup_id, params);
+}
+
+void C_GuiObject::onGetFocus() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ongetfocus_id, NULL);
+}
+
+void C_GuiObject::onKillFocus() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onkillfocus_id, NULL);
+}
+
+int C_GuiObject::sendAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(action);
+ scriptVar b = MAKE_SCRIPT_STRING(param);
+ scriptVar c = MAKE_SCRIPT_INT(x);
+ scriptVar d = MAKE_SCRIPT_INT(y);
+ scriptVar e = MAKE_SCRIPT_INT((int)p1);
+ scriptVar f = MAKE_SCRIPT_INT((int)p2);
+ scriptVar *params[6] = {&a, &b, &c, &d, &e, &f};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), sendaction_id, params));
+}
+
+int C_GuiObject::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, ScriptObject *source)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(action);
+ scriptVar b = MAKE_SCRIPT_STRING(param);
+ scriptVar c = MAKE_SCRIPT_INT(x);
+ scriptVar d = MAKE_SCRIPT_INT(y);
+ scriptVar e = MAKE_SCRIPT_INT((int)p1);
+ scriptVar f = MAKE_SCRIPT_INT((int)p2);
+ scriptVar g = MAKE_SCRIPT_OBJECT(source);
+ scriptVar *params[7] = {&a, &b, &c, &d, &e, &f, &g};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onaction_id, params));
+}
+
+int C_GuiObject::loaded=0;
+int C_GuiObject::show_id=0;
+int C_GuiObject::hide_id=0;
+int C_GuiObject::isvisible_id=0;
+int C_GuiObject::onsetvisible_id=0;
+int C_GuiObject::setalpha_id=0;
+int C_GuiObject::getalpha_id=0;
+int C_GuiObject::onleftbuttonup_id=0;
+int C_GuiObject::onleftbuttondown_id=0;
+int C_GuiObject::onrightbuttonup_id=0;
+int C_GuiObject::onrightbuttondown_id=0;
+int C_GuiObject::onrightbuttondblclk_id=0;
+int C_GuiObject::onleftbuttondblclk_id=0;
+int C_GuiObject::onmousemove_id=0;
+int C_GuiObject::onenterarea_id=0;
+int C_GuiObject::onleavearea_id=0;
+int C_GuiObject::setenabled_id=0;
+int C_GuiObject::getenabled_id=0;
+int C_GuiObject::onenable_id=0;
+int C_GuiObject::resize_id=0;
+int C_GuiObject::onresize_id=0;
+int C_GuiObject::ismouseover_id=0;
+int C_GuiObject::getleft_id=0;
+int C_GuiObject::gettop_id=0;
+int C_GuiObject::getwidth_id=0;
+int C_GuiObject::getheight_id=0;
+int C_GuiObject::settargetx_id=0;
+int C_GuiObject::settargety_id=0;
+int C_GuiObject::settargetw_id=0;
+int C_GuiObject::settargeth_id=0;
+int C_GuiObject::settargeta_id=0;
+int C_GuiObject::settargetspeed_id=0;
+int C_GuiObject::gototarget_id=0;
+int C_GuiObject::ontargetreached_id=0;
+int C_GuiObject::canceltarget_id=0;
+int C_GuiObject::reversetarget_id=0;
+int C_GuiObject::onstartup_id=0;
+int C_GuiObject::isgoingtotarget_id=0;
+int C_GuiObject::setxmlparam_id=0;
+int C_GuiObject::getxmlparam_id=0;
+int C_GuiObject::init_id=0;
+int C_GuiObject::bringtofront_id=0;
+int C_GuiObject::bringtoback_id=0;
+int C_GuiObject::bringabove_id=0;
+int C_GuiObject::bringbelow_id=0;
+int C_GuiObject::getguix_id=0;
+int C_GuiObject::getguiy_id=0;
+int C_GuiObject::getguiw_id=0;
+int C_GuiObject::getguih_id=0;
+int C_GuiObject::getguirelatx_id=0;
+int C_GuiObject::getguirelaty_id=0;
+int C_GuiObject::getguirelatw_id=0;
+int C_GuiObject::getguirelath_id=0;
+int C_GuiObject::isactive_id=0;
+int C_GuiObject::getparent_id=0;
+int C_GuiObject::getparentlayout_id=0;
+int C_GuiObject::gettopparent_id=0;
+int C_GuiObject::runmodal_id=0;
+int C_GuiObject::endmodal_id=0;
+int C_GuiObject::findobject_id=0;
+int C_GuiObject::findobjectxy_id=0;
+int C_GuiObject::getname_id=0;
+int C_GuiObject::clienttoscreenx_id=0;
+int C_GuiObject::clienttoscreeny_id=0;
+int C_GuiObject::clienttoscreenw_id=0;
+int C_GuiObject::clienttoscreenh_id=0;
+int C_GuiObject::screentoclientx_id=0;
+int C_GuiObject::screentoclienty_id=0;
+int C_GuiObject::screentoclientw_id=0;
+int C_GuiObject::screentoclienth_id=0;
+int C_GuiObject::getautowidth_id=0;
+int C_GuiObject::getautoheight_id=0;
+int C_GuiObject::setfocus_id=0;
+int C_GuiObject::onchar_id=0;
+int C_GuiObject::onaccelerator_id=0;
+int C_GuiObject::ismouseoverrect_id=0;
+int C_GuiObject::getinterface_id=0;
+int C_GuiObject::onkeydown_id=0;
+int C_GuiObject::onkeyup_id=0;
+int C_GuiObject::ongetfocus_id=0;
+int C_GuiObject::onkillfocus_id=0;
+int C_GuiObject::sendaction_id=0;
+int C_GuiObject::onaction_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_guiobject.h b/Src/Wasabi/api/script/objects/c_script/c_guiobject.h
new file mode 100644
index 00000000..3922dd20
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_guiobject.h
@@ -0,0 +1,193 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_GUIOBJECT_H
+#define __C_GUIOBJECT_H
+
+#include "c_rootobj.h"
+
+#define C_GUIOBJECT_PARENT C_RootObject
+
+class C_GuiObject : public C_GUIOBJECT_PARENT {
+ public:
+
+ C_GuiObject(ScriptObject *object);
+ C_GuiObject();
+ virtual ~C_GuiObject();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void show();
+ virtual void hide();
+ virtual int isVisible();
+ virtual void onSetVisible(int onoff);
+ virtual void setAlpha(int alpha);
+ virtual int getAlpha();
+ virtual void onLeftButtonUp(int x, int y);
+ virtual void onLeftButtonDown(int x, int y);
+ virtual void onRightButtonUp(int x, int y);
+ virtual void onRightButtonDown(int x, int y);
+ virtual void onRightButtonDblClk(int x, int y);
+ virtual void onLeftButtonDblClk(int x, int y);
+ virtual void onMouseMove(int x, int y);
+ virtual void onEnterArea();
+ virtual void onLeaveArea();
+ virtual void setEnabled(int onoff);
+ virtual int getEnabled();
+ virtual void onEnable(int onoff);
+ virtual void resize(int x, int y, int w, int h);
+ virtual void onResize(int x, int y, int w, int h);
+ virtual int isMouseOver(int x, int y);
+ virtual int getLeft();
+ virtual int getTop();
+ virtual int getWidth();
+ virtual int getHeight();
+ virtual void setTargetX(int x);
+ virtual void setTargetY(int y);
+ virtual void setTargetW(int w);
+ virtual void setTargetH(int r);
+ virtual void setTargetA(int alpha);
+ virtual void setTargetSpeed(float insecond);
+ virtual void gotoTarget();
+ virtual void onTargetReached();
+ virtual void cancelTarget();
+ virtual void reverseTarget(int reverse);
+ virtual void onStartup();
+ virtual int isGoingToTarget();
+ virtual void setXmlParam(const wchar_t *param, const wchar_t *value);
+ virtual const wchar_t *getXmlParam(const wchar_t *param);
+ virtual void init(ScriptObject *parent);
+ virtual void bringToFront();
+ virtual void bringToBack();
+ virtual void bringAbove(ScriptObject *guiobj);
+ virtual void bringBelow(ScriptObject *guiobj);
+ virtual int getGuiX();
+ virtual int getGuiY();
+ virtual int getGuiW();
+ virtual int getGuiH();
+ virtual int getGuiRelatX();
+ virtual int getGuiRelatY();
+ virtual int getGuiRelatW();
+ virtual int getGuiRelatH();
+ virtual int isActive();
+ virtual ScriptObject *getParent();
+ virtual ScriptObject *getParentLayout();
+ virtual ScriptObject *getTopParent();
+ virtual int runModal();
+ virtual void endModal(int retcode);
+ virtual ScriptObject *findObject(const wchar_t *id);
+ virtual ScriptObject *findObjectXY(int x, int y);
+ virtual const wchar_t *getName();
+ virtual int clientToScreenX(int x);
+ virtual int clientToScreenY(int y);
+ virtual int clientToScreenW(int w);
+ virtual int clientToScreenH(int h);
+ virtual int screenToClientX(int x);
+ virtual int screenToClientY(int y);
+ virtual int screenToClientW(int w);
+ virtual int screenToClientH(int h);
+ virtual int getAutoWidth();
+ virtual int getAutoHeight();
+ virtual void setFocus();
+ virtual void onChar(const wchar_t *c);
+ virtual void onAccelerator(const wchar_t *accel);
+ virtual int isMouseOverRect();
+ virtual ScriptObject *getInterface(const wchar_t *interface_guid);
+ virtual void onKeyDown(int vk_code);
+ virtual void onKeyUp(int vk_code);
+ virtual void onGetFocus();
+ virtual void onKillFocus();
+ virtual int sendAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2);
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, ScriptObject *source);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int show_id;
+ static int hide_id;
+ static int isvisible_id;
+ static int onsetvisible_id;
+ static int setalpha_id;
+ static int getalpha_id;
+ static int onleftbuttonup_id;
+ static int onleftbuttondown_id;
+ static int onrightbuttonup_id;
+ static int onrightbuttondown_id;
+ static int onrightbuttondblclk_id;
+ static int onleftbuttondblclk_id;
+ static int onmousemove_id;
+ static int onenterarea_id;
+ static int onleavearea_id;
+ static int setenabled_id;
+ static int getenabled_id;
+ static int onenable_id;
+ static int resize_id;
+ static int onresize_id;
+ static int ismouseover_id;
+ static int getleft_id;
+ static int gettop_id;
+ static int getwidth_id;
+ static int getheight_id;
+ static int settargetx_id;
+ static int settargety_id;
+ static int settargetw_id;
+ static int settargeth_id;
+ static int settargeta_id;
+ static int settargetspeed_id;
+ static int gototarget_id;
+ static int ontargetreached_id;
+ static int canceltarget_id;
+ static int reversetarget_id;
+ static int onstartup_id;
+ static int isgoingtotarget_id;
+ static int setxmlparam_id;
+ static int getxmlparam_id;
+ static int init_id;
+ static int bringtofront_id;
+ static int bringtoback_id;
+ static int bringabove_id;
+ static int bringbelow_id;
+ static int getguix_id;
+ static int getguiy_id;
+ static int getguiw_id;
+ static int getguih_id;
+ static int getguirelatx_id;
+ static int getguirelaty_id;
+ static int getguirelatw_id;
+ static int getguirelath_id;
+ static int isactive_id;
+ static int getparent_id;
+ static int getparentlayout_id;
+ static int gettopparent_id;
+ static int runmodal_id;
+ static int endmodal_id;
+ static int findobject_id;
+ static int findobjectxy_id;
+ static int getname_id;
+ static int clienttoscreenx_id;
+ static int clienttoscreeny_id;
+ static int clienttoscreenw_id;
+ static int clienttoscreenh_id;
+ static int screentoclientx_id;
+ static int screentoclienty_id;
+ static int screentoclientw_id;
+ static int screentoclienth_id;
+ static int getautowidth_id;
+ static int getautoheight_id;
+ static int setfocus_id;
+ static int onchar_id;
+ static int onaccelerator_id;
+ static int ismouseoverrect_id;
+ static int getinterface_id;
+ static int onkeydown_id;
+ static int onkeyup_id;
+ static int ongetfocus_id;
+ static int onkillfocus_id;
+ static int sendaction_id;
+ static int onaction_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_guitree.cpp b/Src/Wasabi/api/script/objects/c_script/c_guitree.cpp
new file mode 100644
index 00000000..aa97f3ee
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_guitree.cpp
@@ -0,0 +1,491 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_guitree.h"
+#include <api/script/objcontroller.h>
+
+C_GuiTree::C_GuiTree(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_GuiTree::C_GuiTree() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_GuiTree::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, guiTreeGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ onwantautocontextmenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onWantAutoContextMenu", this);
+ onmousewheelup_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMouseWheelUp", this);
+ onmousewheeldown_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMouseWheelDown", this);
+ oncontextmenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onContextMenu", this);
+ onchar_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onChar", this);
+ onitemrecvdrop_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onItemRecvDrop", this);
+ onlabelchange_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLabelChange", this);
+ onitemselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onItemSelected", this);
+ onitemdeselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onItemDeselected", this);
+ getnumrootitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumRootItems", this);
+ enumrootitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumRootItem", this);
+ jumptonext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"jumpToNext", this);
+ ensureitemvisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"ensureItemVisible", this);
+ getcontentswidth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getContentsWidth", this);
+ getcontentsheight_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getContentsHeight", this);
+ addtreeitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"addTreeItem", this);
+ removetreeitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"removeTreeItem", this);
+ movetreeitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"moveTreeItem", this);
+ deleteallitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"deleteAllItems", this);
+ expanditem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"expandItem", this);
+ expanditemdeferred_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"expandItemDeferred", this);
+ collapseitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"collapseItem", this);
+ collapseitemdeferred_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"collapseItemDeferred", this);
+ selectitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectItem", this);
+ selectitemdeferred_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"selectItemDeferred", this);
+ delitemdeferred_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"delItemDeferred", this);
+ hiliteitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"hiliteItem", this);
+ unhiliteitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"unhiliteItem", this);
+ getcuritem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getCurItem", this);
+ hittest_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"hitTest", this);
+ edititemlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"editItemLabel", this);
+ canceleditlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"cancelEditLabel", this);
+ setautoedit_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setAutoEdit", this);
+ getautoedit_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getAutoEdit", this);
+ getbylabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getByLabel", this);
+ setsorted_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSorted", this);
+ getsorted_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSorted", this);
+ sorttreeitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"sortTreeItems", this);
+ getsibling_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSibling", this);
+ setautocollapse_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setAutoCollapse", this);
+ setfontsize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setFontSize", this);
+ getfontsize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getFontSize", this);
+ getnumvisiblechilditems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumVisibleChildItems", this);
+ getnumvisibleitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumVisibleItems", this);
+ enumvisibleitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumVisibleItems", this);
+ enumvisiblechilditems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumVisibleChildItems", this);
+ enumallitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"enumAllItems", this);
+ getitemrectx_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemRectX", this);
+ getitemrecty_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemRectY", this);
+ getitemrectw_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemRectW", this);
+ getitemrecth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getItemRectH", this);
+ }
+ inited = 1;
+}
+
+C_GuiTree::~C_GuiTree() {
+}
+
+ScriptObject *C_GuiTree::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_GUITREE_PARENT::getScriptObject();
+}
+
+int C_GuiTree::onWantAutoContextMenu() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onwantautocontextmenu_id, NULL));
+}
+
+int C_GuiTree::onMouseWheelUp(int clicked, int lines) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(clicked);
+ scriptVar b = MAKE_SCRIPT_INT(lines);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmousewheelup_id, params));
+}
+
+int C_GuiTree::onMouseWheelDown(int clicked, int lines) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(clicked);
+ scriptVar b = MAKE_SCRIPT_INT(lines);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmousewheeldown_id, params));
+}
+
+int C_GuiTree::onContextMenu(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), oncontextmenu_id, params));
+}
+
+int C_GuiTree::onChar(int c) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(c);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onchar_id, params));
+}
+
+void C_GuiTree::onItemRecvDrop(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onitemrecvdrop_id, params);
+}
+
+void C_GuiTree::onLabelChange(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onlabelchange_id, params);
+}
+
+void C_GuiTree::onItemSelected(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onitemselected_id, params);
+}
+
+void C_GuiTree::onItemDeselected(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onitemdeselected_id, params);
+}
+
+int C_GuiTree::getNumRootItems() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumrootitems_id, NULL));
+}
+
+ScriptObject *C_GuiTree::enumRootItem(int which) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(which);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumrootitem_id, params));
+}
+
+void C_GuiTree::jumpToNext(int c) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(c);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), jumptonext_id, params);
+}
+
+void C_GuiTree::ensureItemVisible(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ensureitemvisible_id, params);
+}
+
+int C_GuiTree::getContentsWidth() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcontentswidth_id, NULL));
+}
+
+int C_GuiTree::getContentsHeight() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcontentsheight_id, NULL));
+}
+
+ScriptObject *C_GuiTree::addTreeItem(ScriptObject *item, ScriptObject *par, int sorted, int haschildtab) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar b = MAKE_SCRIPT_OBJECT(par);
+ scriptVar c = MAKE_SCRIPT_INT(sorted);
+ scriptVar d = MAKE_SCRIPT_INT(haschildtab);
+ scriptVar *params[4] = {&a, &b, &c, &d};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), addtreeitem_id, params));
+}
+
+int C_GuiTree::removeTreeItem(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), removetreeitem_id, params));
+}
+
+void C_GuiTree::moveTreeItem(ScriptObject *item, ScriptObject *newparent) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar b = MAKE_SCRIPT_OBJECT(newparent);
+ scriptVar *params[2] = {&a, &b};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), movetreeitem_id, params);
+}
+
+void C_GuiTree::deleteAllItems() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), deleteallitems_id, NULL);
+}
+
+int C_GuiTree::expandItem(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), expanditem_id, params));
+}
+
+void C_GuiTree::expandItemDeferred(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), expanditemdeferred_id, params);
+}
+
+int C_GuiTree::collapseItem(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), collapseitem_id, params));
+}
+
+void C_GuiTree::collapseItemDeferred(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), collapseitemdeferred_id, params);
+}
+
+void C_GuiTree::selectItem(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectitem_id, params);
+}
+
+void C_GuiTree::selectItemDeferred(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), selectitemdeferred_id, params);
+}
+
+void C_GuiTree::delItemDeferred(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), delitemdeferred_id, params);
+}
+
+void C_GuiTree::hiliteItem(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), hiliteitem_id, params);
+}
+
+void C_GuiTree::unhiliteItem(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), unhiliteitem_id, params);
+}
+
+ScriptObject *C_GuiTree::getCurItem() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcuritem_id, NULL));
+}
+
+ScriptObject *C_GuiTree::hitTest(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), hittest_id, params));
+}
+
+void C_GuiTree::editItemLabel(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), edititemlabel_id, params);
+}
+
+void C_GuiTree::cancelEditLabel(int destroyit) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(destroyit);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), canceleditlabel_id, params);
+}
+
+void C_GuiTree::setAutoEdit(int ae) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(ae);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setautoedit_id, params);
+}
+
+int C_GuiTree::getAutoEdit() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getautoedit_id, NULL));
+}
+
+ScriptObject *C_GuiTree::getByLabel(ScriptObject *item, const wchar_t *name)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar b = MAKE_SCRIPT_STRING(name);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getbylabel_id, params));
+}
+
+void C_GuiTree::setSorted(int dosort) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(dosort);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setsorted_id, params);
+}
+
+int C_GuiTree::getSorted() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsorted_id, NULL));
+}
+
+void C_GuiTree::sortTreeItems() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), sorttreeitems_id, NULL);
+}
+
+ScriptObject *C_GuiTree::getSibling(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsibling_id, params));
+}
+
+void C_GuiTree::setAutoCollapse(int doautocollapse) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(doautocollapse);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setautocollapse_id, params);
+}
+
+int C_GuiTree::setFontSize(int newsize) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(newsize);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), setfontsize_id, params));
+}
+
+int C_GuiTree::getFontSize() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getfontsize_id, NULL));
+}
+
+int C_GuiTree::getNumVisibleChildItems(ScriptObject *c) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(c);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumvisiblechilditems_id, params));
+}
+
+int C_GuiTree::getNumVisibleItems() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumvisibleitems_id, NULL));
+}
+
+ScriptObject *C_GuiTree::enumVisibleItems(int n) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(n);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumvisibleitems_id, params));
+}
+
+ScriptObject *C_GuiTree::enumVisibleChildItems(ScriptObject *c, int n) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(c);
+ scriptVar b = MAKE_SCRIPT_INT(n);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumvisiblechilditems_id, params));
+}
+
+ScriptObject *C_GuiTree::enumAllItems(int n) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(n);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), enumallitems_id, params));
+}
+
+int C_GuiTree::getItemRectX(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemrectx_id, params));
+}
+
+int C_GuiTree::getItemRectY(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemrecty_id, params));
+}
+
+int C_GuiTree::getItemRectW(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemrectw_id, params));
+}
+
+int C_GuiTree::getItemRectH(ScriptObject *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getitemrecth_id, params));
+}
+
+int C_GuiTree::loaded=0;
+int C_GuiTree::onwantautocontextmenu_id=0;
+int C_GuiTree::onmousewheelup_id=0;
+int C_GuiTree::onmousewheeldown_id=0;
+int C_GuiTree::oncontextmenu_id=0;
+int C_GuiTree::onchar_id=0;
+int C_GuiTree::onitemrecvdrop_id=0;
+int C_GuiTree::onlabelchange_id=0;
+int C_GuiTree::onitemselected_id=0;
+int C_GuiTree::onitemdeselected_id=0;
+int C_GuiTree::getnumrootitems_id=0;
+int C_GuiTree::enumrootitem_id=0;
+int C_GuiTree::jumptonext_id=0;
+int C_GuiTree::ensureitemvisible_id=0;
+int C_GuiTree::getcontentswidth_id=0;
+int C_GuiTree::getcontentsheight_id=0;
+int C_GuiTree::addtreeitem_id=0;
+int C_GuiTree::removetreeitem_id=0;
+int C_GuiTree::movetreeitem_id=0;
+int C_GuiTree::deleteallitems_id=0;
+int C_GuiTree::expanditem_id=0;
+int C_GuiTree::expanditemdeferred_id=0;
+int C_GuiTree::collapseitem_id=0;
+int C_GuiTree::collapseitemdeferred_id=0;
+int C_GuiTree::selectitem_id=0;
+int C_GuiTree::selectitemdeferred_id=0;
+int C_GuiTree::delitemdeferred_id=0;
+int C_GuiTree::hiliteitem_id=0;
+int C_GuiTree::unhiliteitem_id=0;
+int C_GuiTree::getcuritem_id=0;
+int C_GuiTree::hittest_id=0;
+int C_GuiTree::edititemlabel_id=0;
+int C_GuiTree::canceleditlabel_id=0;
+int C_GuiTree::setautoedit_id=0;
+int C_GuiTree::getautoedit_id=0;
+int C_GuiTree::getbylabel_id=0;
+int C_GuiTree::setsorted_id=0;
+int C_GuiTree::getsorted_id=0;
+int C_GuiTree::sorttreeitems_id=0;
+int C_GuiTree::getsibling_id=0;
+int C_GuiTree::setautocollapse_id=0;
+int C_GuiTree::setfontsize_id=0;
+int C_GuiTree::getfontsize_id=0;
+int C_GuiTree::getnumvisiblechilditems_id=0;
+int C_GuiTree::getnumvisibleitems_id=0;
+int C_GuiTree::enumvisibleitems_id=0;
+int C_GuiTree::enumvisiblechilditems_id=0;
+int C_GuiTree::enumallitems_id=0;
+int C_GuiTree::getitemrectx_id=0;
+int C_GuiTree::getitemrecty_id=0;
+int C_GuiTree::getitemrectw_id=0;
+int C_GuiTree::getitemrecth_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_guitree.h b/Src/Wasabi/api/script/objects/c_script/c_guitree.h
new file mode 100644
index 00000000..296e0043
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_guitree.h
@@ -0,0 +1,131 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_GUITREE_H
+#define __C_GUITREE_H
+
+#include "c_guiobject.h"
+
+#define C_GUITREE_PARENT C_GuiObject
+
+class C_GuiTree : public C_GUITREE_PARENT {
+ public:
+
+ C_GuiTree(ScriptObject *object);
+ C_GuiTree();
+ virtual ~C_GuiTree();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual int onWantAutoContextMenu();
+ virtual int onMouseWheelUp(int clicked, int lines);
+ virtual int onMouseWheelDown(int clicked, int lines);
+ virtual int onContextMenu(int x, int y);
+ virtual int onChar(int c);
+ virtual void onItemRecvDrop(ScriptObject *item);
+ virtual void onLabelChange(ScriptObject *item);
+ virtual void onItemSelected(ScriptObject *item);
+ virtual void onItemDeselected(ScriptObject *item);
+ virtual int getNumRootItems();
+ virtual ScriptObject *enumRootItem(int which);
+ virtual void jumpToNext(int c);
+ virtual void ensureItemVisible(ScriptObject *item);
+ virtual int getContentsWidth();
+ virtual int getContentsHeight();
+ virtual ScriptObject *addTreeItem(ScriptObject *item, ScriptObject *par, int sorted, int haschildtab);
+ virtual int removeTreeItem(ScriptObject *item);
+ virtual void moveTreeItem(ScriptObject *item, ScriptObject *newparent);
+ virtual void deleteAllItems();
+ virtual int expandItem(ScriptObject *item);
+ virtual void expandItemDeferred(ScriptObject *item);
+ virtual int collapseItem(ScriptObject *item);
+ virtual void collapseItemDeferred(ScriptObject *item);
+ virtual void selectItem(ScriptObject *item);
+ virtual void selectItemDeferred(ScriptObject *item);
+ virtual void delItemDeferred(ScriptObject *item);
+ virtual void hiliteItem(ScriptObject *item);
+ virtual void unhiliteItem(ScriptObject *item);
+ virtual ScriptObject *getCurItem();
+ virtual ScriptObject *hitTest(int x, int y);
+ virtual void editItemLabel(ScriptObject *item);
+ virtual void cancelEditLabel(int destroyit);
+ virtual void setAutoEdit(int ae);
+ virtual int getAutoEdit();
+ virtual ScriptObject *getByLabel(ScriptObject *item, const wchar_t *name);
+ virtual void setSorted(int dosort);
+ virtual int getSorted();
+ virtual void sortTreeItems();
+ virtual ScriptObject *getSibling(ScriptObject *item);
+ virtual void setAutoCollapse(int doautocollapse);
+ virtual int setFontSize(int newsize);
+ virtual int getFontSize();
+ virtual int getNumVisibleChildItems(ScriptObject *c);
+ virtual int getNumVisibleItems();
+ virtual ScriptObject *enumVisibleItems(int n);
+ virtual ScriptObject *enumVisibleChildItems(ScriptObject *c, int n);
+ virtual ScriptObject *enumAllItems(int n);
+ virtual int getItemRectX(ScriptObject *item);
+ virtual int getItemRectY(ScriptObject *item);
+ virtual int getItemRectW(ScriptObject *item);
+ virtual int getItemRectH(ScriptObject *item);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onwantautocontextmenu_id;
+ static int onmousewheelup_id;
+ static int onmousewheeldown_id;
+ static int oncontextmenu_id;
+ static int onchar_id;
+ static int onitemrecvdrop_id;
+ static int onlabelchange_id;
+ static int onitemselected_id;
+ static int onitemdeselected_id;
+ static int getnumrootitems_id;
+ static int enumrootitem_id;
+ static int jumptonext_id;
+ static int ensureitemvisible_id;
+ static int getcontentswidth_id;
+ static int getcontentsheight_id;
+ static int addtreeitem_id;
+ static int removetreeitem_id;
+ static int movetreeitem_id;
+ static int deleteallitems_id;
+ static int expanditem_id;
+ static int expanditemdeferred_id;
+ static int collapseitem_id;
+ static int collapseitemdeferred_id;
+ static int selectitem_id;
+ static int selectitemdeferred_id;
+ static int delitemdeferred_id;
+ static int hiliteitem_id;
+ static int unhiliteitem_id;
+ static int getcuritem_id;
+ static int hittest_id;
+ static int edititemlabel_id;
+ static int canceleditlabel_id;
+ static int setautoedit_id;
+ static int getautoedit_id;
+ static int getbylabel_id;
+ static int setsorted_id;
+ static int getsorted_id;
+ static int sorttreeitems_id;
+ static int getsibling_id;
+ static int setautocollapse_id;
+ static int setfontsize_id;
+ static int getfontsize_id;
+ static int getnumvisiblechilditems_id;
+ static int getnumvisibleitems_id;
+ static int enumvisibleitems_id;
+ static int enumvisiblechilditems_id;
+ static int enumallitems_id;
+ static int getitemrectx_id;
+ static int getitemrecty_id;
+ static int getitemrectw_id;
+ static int getitemrecth_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_layout.cpp b/Src/Wasabi/api/script/objects/c_script/c_layout.cpp
new file mode 100644
index 00000000..cc87042f
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_layout.cpp
@@ -0,0 +1,236 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_layout.h"
+#include <api/script/objcontroller.h>
+
+C_Layout::C_Layout(ScriptObject *object) : C_Group(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_Layout::C_Layout() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Layout::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, layoutGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ ondock_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onDock", this);
+ onundock_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onUndock", this);
+ onscale_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onScale", this);
+ getscale_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getScale", this);
+ setscale_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setScale", this);
+ setdesktopalpha_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setDesktopAlpha", this);
+ getdesktopalpha_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getDesktopAlpha", this);
+ getcontainer_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getContainer", this);
+ center_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"center", this);
+ onmove_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMove", this);
+ onendmove_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onEndMove", this);
+ onuserresize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onUserResize", this);
+ snapadjust_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"snapAdjust", this);
+ getsnapadjusttop_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSnapAdjustTop", this);
+ getsnapadjustright_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSnapAdjustRight", this);
+ getsnapadjustleft_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSnapAdjustLeft", this);
+ getsnapadjustbottom_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSnapAdjustBottom", this);
+ setredrawonresize_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setRedrawOnResize", this);
+ beforeredock_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"beforeRedock", this);
+ redock_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"redock", this);
+ istransparencysafe_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isTransparencySafe", this);
+ islayoutanimationsafe_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isLayoutAnimationSafe", this);
+ onmouseenterlayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMouseEnterLayout", this);
+ onmouseleavelayout_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onMouseLeaveLayout", this);
+ onsnapadjustchanged_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSnapAdjustChanged", this);
+ }
+ inited = 1;
+}
+
+C_Layout::~C_Layout() {
+}
+
+ScriptObject *C_Layout::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_LAYOUT_PARENT::getScriptObject();
+}
+
+void C_Layout::onDock() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ondock_id, NULL);
+}
+
+void C_Layout::onUndock() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onundock_id, NULL);
+}
+
+void C_Layout::onScale(double newscalevalue) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_DOUBLE(newscalevalue);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onscale_id, params);
+}
+
+double C_Layout::getScale() {
+ ASSERT(inited);
+ return GET_SCRIPT_DOUBLE(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getscale_id, NULL));
+}
+
+void C_Layout::setScale(double scalevalue) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_DOUBLE(scalevalue);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setscale_id, params);
+}
+
+void C_Layout::setDesktopAlpha(int onoff) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(onoff);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setdesktopalpha_id, params);
+}
+
+int C_Layout::getDesktopAlpha() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getdesktopalpha_id, NULL));
+}
+
+ScriptObject *C_Layout::getContainer() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcontainer_id, NULL));
+}
+
+void C_Layout::center() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), center_id, NULL);
+}
+
+void C_Layout::onMove() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmove_id, NULL);
+}
+
+void C_Layout::onEndMove() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onendmove_id, NULL);
+}
+
+void C_Layout::onUserResize(int x, int y, int w, int h) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar c = MAKE_SCRIPT_INT(w);
+ scriptVar d = MAKE_SCRIPT_INT(h);
+ scriptVar *params[4] = {&a, &b, &c, &d};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onuserresize_id, params);
+}
+
+void C_Layout::snapAdjust(int left, int top, int right, int bottom) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(left);
+ scriptVar b = MAKE_SCRIPT_INT(top);
+ scriptVar c = MAKE_SCRIPT_INT(right);
+ scriptVar d = MAKE_SCRIPT_INT(bottom);
+ scriptVar *params[4] = {&a, &b, &c, &d};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), snapadjust_id, params);
+}
+
+int C_Layout::getSnapAdjustTop() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsnapadjusttop_id, NULL));
+}
+
+int C_Layout::getSnapAdjustRight() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsnapadjustright_id, NULL));
+}
+
+int C_Layout::getSnapAdjustLeft() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsnapadjustleft_id, NULL));
+}
+
+int C_Layout::getSnapAdjustBottom() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsnapadjustbottom_id, NULL));
+}
+
+void C_Layout::setRedrawOnResize(int wantredrawonresize) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(wantredrawonresize);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setredrawonresize_id, params);
+}
+
+void C_Layout::beforeRedock() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), beforeredock_id, NULL);
+}
+
+void C_Layout::redock() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), redock_id, NULL);
+}
+
+int C_Layout::isTransparencySafe() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), istransparencysafe_id, NULL));
+}
+
+int C_Layout::isLayoutAnimationSafe() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), islayoutanimationsafe_id, NULL));
+}
+
+void C_Layout::onMouseEnterLayout() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmouseenterlayout_id, NULL);
+}
+
+void C_Layout::onMouseLeaveLayout() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onmouseleavelayout_id, NULL);
+}
+
+void C_Layout::onSnapAdjustChanged() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onsnapadjustchanged_id, NULL);
+}
+
+int C_Layout::loaded=0;
+int C_Layout::ondock_id=0;
+int C_Layout::onundock_id=0;
+int C_Layout::onscale_id=0;
+int C_Layout::getscale_id=0;
+int C_Layout::setscale_id=0;
+int C_Layout::setdesktopalpha_id=0;
+int C_Layout::getdesktopalpha_id=0;
+int C_Layout::getcontainer_id=0;
+int C_Layout::center_id=0;
+int C_Layout::onmove_id=0;
+int C_Layout::onendmove_id=0;
+int C_Layout::onuserresize_id=0;
+int C_Layout::snapadjust_id=0;
+int C_Layout::getsnapadjusttop_id=0;
+int C_Layout::getsnapadjustright_id=0;
+int C_Layout::getsnapadjustleft_id=0;
+int C_Layout::getsnapadjustbottom_id=0;
+int C_Layout::setredrawonresize_id=0;
+int C_Layout::beforeredock_id=0;
+int C_Layout::redock_id=0;
+int C_Layout::istransparencysafe_id=0;
+int C_Layout::islayoutanimationsafe_id=0;
+int C_Layout::onmouseenterlayout_id=0;
+int C_Layout::onmouseleavelayout_id=0;
+int C_Layout::onsnapadjustchanged_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_layout.h b/Src/Wasabi/api/script/objects/c_script/c_layout.h
new file mode 100644
index 00000000..158a0545
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_layout.h
@@ -0,0 +1,79 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_LAYOUT_H
+#define __C_LAYOUT_H
+
+#include "c_group.h"
+
+#define C_LAYOUT_PARENT C_Group
+
+class C_Layout : public C_LAYOUT_PARENT {
+ public:
+
+ C_Layout(ScriptObject *object);
+ C_Layout();
+ virtual ~C_Layout();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onDock();
+ virtual void onUndock();
+ virtual void onScale(double newscalevalue);
+ virtual double getScale();
+ virtual void setScale(double scalevalue);
+ virtual void setDesktopAlpha(int onoff);
+ virtual int getDesktopAlpha();
+ virtual ScriptObject *getContainer();
+ virtual void center();
+ virtual void onMove();
+ virtual void onEndMove();
+ virtual void onUserResize(int x, int y, int w, int h);
+ virtual void snapAdjust(int left, int top, int right, int bottom);
+ virtual int getSnapAdjustTop();
+ virtual int getSnapAdjustRight();
+ virtual int getSnapAdjustLeft();
+ virtual int getSnapAdjustBottom();
+ virtual void setRedrawOnResize(int wantredrawonresize);
+ virtual void beforeRedock();
+ virtual void redock();
+ virtual int isTransparencySafe();
+ virtual int isLayoutAnimationSafe();
+ virtual void onMouseEnterLayout();
+ virtual void onMouseLeaveLayout();
+ virtual void onSnapAdjustChanged();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ondock_id;
+ static int onundock_id;
+ static int onscale_id;
+ static int getscale_id;
+ static int setscale_id;
+ static int setdesktopalpha_id;
+ static int getdesktopalpha_id;
+ static int getcontainer_id;
+ static int center_id;
+ static int onmove_id;
+ static int onendmove_id;
+ static int onuserresize_id;
+ static int snapadjust_id;
+ static int getsnapadjusttop_id;
+ static int getsnapadjustright_id;
+ static int getsnapadjustleft_id;
+ static int getsnapadjustbottom_id;
+ static int setredrawonresize_id;
+ static int beforeredock_id;
+ static int redock_id;
+ static int istransparencysafe_id;
+ static int islayoutanimationsafe_id;
+ static int onmouseenterlayout_id;
+ static int onmouseleavelayout_id;
+ static int onsnapadjustchanged_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_menubutton.cpp b/Src/Wasabi/api/script/objects/c_script/c_menubutton.cpp
new file mode 100644
index 00000000..a79909e1
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_menubutton.cpp
@@ -0,0 +1,80 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_menubutton.h"
+#include <api/script/objcontroller.h>
+
+C_MenuButton::C_MenuButton(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_MenuButton::C_MenuButton() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_MenuButton::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, menuButtonGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ onopenmenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onOpenMenu", this);
+ onclosemenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onCloseMenu", this);
+ onselectitem_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSelectItem", this);
+ openmenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"openMenu", this);
+ closemenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"closeMenu", this);
+ }
+ inited = 1;
+}
+
+C_MenuButton::~C_MenuButton() {
+}
+
+ScriptObject *C_MenuButton::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_MENUBUTTON_PARENT::getScriptObject();
+}
+
+void C_MenuButton::onOpenMenu() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onopenmenu_id, NULL);
+}
+
+void C_MenuButton::onCloseMenu() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onclosemenu_id, NULL);
+}
+
+void C_MenuButton::onSelectItem(const wchar_t *item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(item);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onselectitem_id, params);
+}
+
+void C_MenuButton::openMenu() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), openmenu_id, NULL);
+}
+
+void C_MenuButton::closeMenu() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), closemenu_id, NULL);
+}
+
+int C_MenuButton::loaded=0;
+int C_MenuButton::onopenmenu_id=0;
+int C_MenuButton::onclosemenu_id=0;
+int C_MenuButton::onselectitem_id=0;
+int C_MenuButton::openmenu_id=0;
+int C_MenuButton::closemenu_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_menubutton.h b/Src/Wasabi/api/script/objects/c_script/c_menubutton.h
new file mode 100644
index 00000000..2da559ba
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_menubutton.h
@@ -0,0 +1,39 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_MENUBUTTON_H
+#define __C_MENUBUTTON_H
+
+#include "c_guiobject.h"
+
+#define C_MENUBUTTON_PARENT C_GuiObject
+
+class C_MenuButton : public C_MENUBUTTON_PARENT {
+ public:
+
+ C_MenuButton(ScriptObject *object);
+ C_MenuButton();
+ virtual ~C_MenuButton();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onOpenMenu();
+ virtual void onCloseMenu();
+ virtual void onSelectItem(const wchar_t *item);
+ virtual void openMenu();
+ virtual void closeMenu();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onopenmenu_id;
+ static int onclosemenu_id;
+ static int onselectitem_id;
+ static int openmenu_id;
+ static int closemenu_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_querylist.cpp b/Src/Wasabi/api/script/objects/c_script/c_querylist.cpp
new file mode 100644
index 00000000..8535bcf5
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_querylist.cpp
@@ -0,0 +1,49 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_querylist.h"
+#include <api/script/objcontroller.h>
+
+C_QueryList::C_QueryList(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_QueryList::C_QueryList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_QueryList::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, queryListGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ if (!loaded) {
+ loaded = 1;
+ onresetquery_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onResetQuery", this);
+ }
+ inited = 1;
+}
+
+C_QueryList::~C_QueryList() {
+}
+
+ScriptObject *C_QueryList::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_QUERYLIST_PARENT::getScriptObject();
+}
+
+void C_QueryList::onResetQuery() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onresetquery_id, NULL);
+}
+
+int C_QueryList::loaded=0;
+int C_QueryList::onresetquery_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_querylist.h b/Src/Wasabi/api/script/objects/c_script/c_querylist.h
new file mode 100644
index 00000000..51c18a77
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_querylist.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_QUERYLIST_H
+#define __C_QUERYLIST_H
+
+#include "c_guiobject.h"
+
+#define C_QUERYLIST_PARENT C_GuiObject
+
+class C_QueryList : public C_QUERYLIST_PARENT {
+ public:
+
+ C_QueryList(ScriptObject *object);
+ C_QueryList();
+ virtual ~C_QueryList();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onResetQuery();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onresetquery_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_rootobj.cpp b/Src/Wasabi/api/script/objects/c_script/c_rootobj.cpp
new file mode 100644
index 00000000..304d1715
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_rootobj.cpp
@@ -0,0 +1,64 @@
+#include <precomp.h>
+
+#include <api/script/scriptobj.h>
+#include <api/script/objcontroller.h>
+#include "c_rootobj.h"
+
+C_RootObject::C_RootObject(ScriptObject *o)
+{
+ inited = 0;
+ obj = NULL;
+ C_hook(o);
+}
+
+C_RootObject::C_RootObject()
+{
+ inited = 0;
+ obj = NULL;
+}
+
+void C_RootObject::C_hook(ScriptObject *o)
+{
+ ASSERT(!inited);
+ obj = o;
+ if (count++ == 0) {
+ getclassname_id = WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"getClassName", this);
+ notify_id = WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"notify", this);
+ }
+ inited=1;
+}
+
+C_RootObject::~C_RootObject()
+{
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+ //count--;
+}
+
+ScriptObject *C_RootObject::getScriptObject()
+{
+ ASSERT(inited);
+ return obj;
+}
+
+const wchar_t *C_RootObject::getClassName()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(obj, getclassname_id, NULL));
+}
+
+void C_RootObject::notify(const wchar_t *a, const wchar_t *b, int c, int d)
+{
+ ASSERT(inited);
+ scriptVar _a = MAKE_SCRIPT_STRING(a);
+ scriptVar _b = MAKE_SCRIPT_STRING(b);
+ scriptVar _c = MAKE_SCRIPT_INT(c);
+ scriptVar _d = MAKE_SCRIPT_INT(d);
+ scriptVar *params[4]={&_a, &_b, &_c, &_d};
+ WASABI_API_MAKI->maki_callFunction(obj, notify_id, params);
+}
+
+int C_RootObject::getclassname_id=0;
+int C_RootObject::notify_id=0;
+int C_RootObject::inited=0;
+int C_RootObject::count=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_rootobj.h b/Src/Wasabi/api/script/objects/c_script/c_rootobj.h
new file mode 100644
index 00000000..780b83b1
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_rootobj.h
@@ -0,0 +1,33 @@
+#ifndef __C_SCRIPTOBJ_H
+#define __C_SCRIPTOBJ_H
+
+#include <api/script/scriptobj.h>
+
+class C_RootObject{
+
+ public:
+
+ C_RootObject(ScriptObject *o);
+ C_RootObject();
+ virtual ~C_RootObject();
+
+ virtual void C_hook(ScriptObject *o);
+
+ virtual const wchar_t *getClassName();
+ virtual void notify(const wchar_t *a, const wchar_t *b, int c, int d);
+ virtual ScriptObject *getScriptObject();
+
+ operator ScriptObject *() { return getScriptObject(); }
+
+ private:
+
+ ScriptObject *obj;
+ static int getclassname_id;
+ static int notify_id;
+ static int inited;
+ static int count;
+};
+
+
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_slider.cpp b/Src/Wasabi/api/script/objects/c_script/c_slider.cpp
new file mode 100644
index 00000000..0aaaa4b1
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_slider.cpp
@@ -0,0 +1,100 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_slider.h"
+#include <api/script/objcontroller.h>
+
+C_Slider::C_Slider(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_Slider::C_Slider() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Slider::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, sliderGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ onsetposition_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSetPosition", this);
+ onpostedposition_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onPostedPosition", this);
+ onsetfinalposition_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSetFinalPosition", this);
+ setposition_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setPosition", this);
+ getposition_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getPosition", this);
+ lock_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"lock", this);
+ unlock_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"unlock", this);
+ }
+ inited = 1;
+}
+
+C_Slider::~C_Slider() {
+}
+
+ScriptObject *C_Slider::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_SLIDER_PARENT::getScriptObject();
+}
+
+void C_Slider::onSetPosition(int newpos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(newpos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onsetposition_id, params);
+}
+
+void C_Slider::onPostedPosition(int newpos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(newpos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onpostedposition_id, params);
+}
+
+void C_Slider::onSetFinalPosition(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onsetfinalposition_id, params);
+}
+
+void C_Slider::setPosition(int pos) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(pos);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setposition_id, params);
+}
+
+int C_Slider::getPosition() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getposition_id, NULL));
+}
+
+void C_Slider::lock() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), lock_id, NULL);
+}
+
+void C_Slider::unlock() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), unlock_id, NULL);
+}
+
+int C_Slider::loaded=0;
+int C_Slider::onsetposition_id=0;
+int C_Slider::onpostedposition_id=0;
+int C_Slider::onsetfinalposition_id=0;
+int C_Slider::setposition_id=0;
+int C_Slider::getposition_id=0;
+int C_Slider::lock_id=0;
+int C_Slider::unlock_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_slider.h b/Src/Wasabi/api/script/objects/c_script/c_slider.h
new file mode 100644
index 00000000..a7d96fc0
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_slider.h
@@ -0,0 +1,43 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_SLIDER_H
+#define __C_SLIDER_H
+
+#include "c_guiobject.h"
+
+#define C_SLIDER_PARENT C_GuiObject
+
+class C_Slider : public C_SLIDER_PARENT {
+ public:
+
+ C_Slider(ScriptObject *object);
+ C_Slider();
+ virtual ~C_Slider();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onSetPosition(int newpos);
+ virtual void onPostedPosition(int newpos);
+ virtual void onSetFinalPosition(int pos);
+ virtual void setPosition(int pos);
+ virtual int getPosition();
+ virtual void lock();
+ virtual void unlock();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onsetposition_id;
+ static int onpostedposition_id;
+ static int onsetfinalposition_id;
+ static int setposition_id;
+ static int getposition_id;
+ static int lock_id;
+ static int unlock_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_tabsheet.cpp b/Src/Wasabi/api/script/objects/c_script/c_tabsheet.cpp
new file mode 100644
index 00000000..b7455187
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_tabsheet.cpp
@@ -0,0 +1,59 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+#include <api/api.h>
+#include "c_tabsheet.h"
+#include <api/script/objcontroller.h>
+
+C_TabSheet::C_TabSheet(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_TabSheet::C_TabSheet() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_TabSheet::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, tabSheetGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ getcurpage_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getCurPage", this);
+ setcurpage_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setCurPage", this);
+ }
+ inited = 1;
+}
+
+C_TabSheet::~C_TabSheet() {
+}
+
+ScriptObject *C_TabSheet::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_TABSHEET_PARENT::getScriptObject();
+}
+
+int C_TabSheet::getCurPage() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcurpage_id, NULL));
+}
+
+void C_TabSheet::setCurPage(int a) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(a);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setcurpage_id, params);
+}
+
+int C_TabSheet::loaded=0;
+int C_TabSheet::getcurpage_id=0;
+int C_TabSheet::setcurpage_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_tabsheet.h b/Src/Wasabi/api/script/objects/c_script/c_tabsheet.h
new file mode 100644
index 00000000..5d2323d7
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_tabsheet.h
@@ -0,0 +1,33 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_TABSHEET_H
+#define __C_TABSHEET_H
+
+#include "c_guiobject.h"
+
+#define C_TABSHEET_PARENT C_GuiObject
+
+class C_TabSheet : public C_TABSHEET_PARENT {
+ public:
+
+ C_TabSheet(ScriptObject *object);
+ C_TabSheet();
+ virtual ~C_TabSheet();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual int getCurPage();
+ virtual void setCurPage(int a);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int getcurpage_id;
+ static int setcurpage_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_text.cpp b/Src/Wasabi/api/script/objects/c_script/c_text.cpp
new file mode 100644
index 00000000..0d178d01
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_text.cpp
@@ -0,0 +1,89 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_text.h"
+#include <api/script/objcontroller.h>
+
+C_Text::C_Text(ScriptObject *object) : C_GuiObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_Text::C_Text() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_Text::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, textGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ settext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setText", this);
+ setalternatetext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setAlternateText", this);
+ gettext_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getText", this);
+ gettextwidth_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getTextWidth", this);
+ ontextchanged_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onTextChanged", this);
+ }
+ inited = 1;
+}
+
+C_Text::~C_Text() {
+}
+
+ScriptObject *C_Text::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_TEXT_PARENT::getScriptObject();
+}
+
+void C_Text::setText(const wchar_t *txt)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(txt);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), settext_id, params);
+}
+
+void C_Text::setAlternateText(const wchar_t *txt)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(txt);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setalternatetext_id, params);
+}
+
+const wchar_t *C_Text::getText()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettext_id, NULL));
+}
+
+int C_Text::getTextWidth()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettextwidth_id, NULL));
+}
+
+void C_Text::onTextChanged(const wchar_t *newtxt)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(newtxt);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ontextchanged_id, params);
+}
+
+int C_Text::loaded=0;
+int C_Text::settext_id=0;
+int C_Text::setalternatetext_id=0;
+int C_Text::gettext_id=0;
+int C_Text::gettextwidth_id=0;
+int C_Text::ontextchanged_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_text.h b/Src/Wasabi/api/script/objects/c_script/c_text.h
new file mode 100644
index 00000000..5a997c47
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_text.h
@@ -0,0 +1,40 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_TEXT_H
+#define __C_TEXT_H
+
+#include "c_guiobject.h"
+
+#define C_TEXT_PARENT C_GuiObject
+
+class C_Text : public C_TEXT_PARENT
+{
+ public:
+
+ C_Text(ScriptObject *object);
+ C_Text();
+ virtual ~C_Text();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void setText(const wchar_t *txt);
+ virtual void setAlternateText(const wchar_t *txt);
+ virtual const wchar_t *getText();
+ virtual int getTextWidth();
+ virtual void onTextChanged(const wchar_t *newtxt);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int settext_id;
+ static int setalternatetext_id;
+ static int gettext_id;
+ static int gettextwidth_id;
+ static int ontextchanged_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_togglebutton.cpp b/Src/Wasabi/api/script/objects/c_script/c_togglebutton.cpp
new file mode 100644
index 00000000..93a8e0a0
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_togglebutton.cpp
@@ -0,0 +1,59 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_togglebutton.h"
+#include <api/script/objcontroller.h>
+
+C_ToggleButton::C_ToggleButton(ScriptObject *object) : C_Button(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_ToggleButton::C_ToggleButton() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_ToggleButton::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, toggleButtonGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ ontoggle_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onToggle", this);
+ getcurcfgval_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getCurCfgVal", this);
+ }
+ inited = 1;
+}
+
+C_ToggleButton::~C_ToggleButton() {
+}
+
+ScriptObject *C_ToggleButton::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_TOGGLEBUTTON_PARENT::getScriptObject();
+}
+
+void C_ToggleButton::onToggle(int (null)) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT((null));
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ontoggle_id, params);
+}
+
+int C_ToggleButton::getCurCfgVal() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getcurcfgval_id, NULL));
+}
+
+int C_ToggleButton::loaded=0;
+int C_ToggleButton::ontoggle_id=0;
+int C_ToggleButton::getcurcfgval_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_togglebutton.h b/Src/Wasabi/api/script/objects/c_script/c_togglebutton.h
new file mode 100644
index 00000000..0abcb656
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_togglebutton.h
@@ -0,0 +1,33 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_TOGGLEBUTTON_H
+#define __C_TOGGLEBUTTON_H
+
+#include "c_button.h"
+
+#define C_TOGGLEBUTTON_PARENT C_Button
+
+class C_ToggleButton : public C_TOGGLEBUTTON_PARENT {
+ public:
+
+ C_ToggleButton(ScriptObject *object);
+ C_ToggleButton();
+ virtual ~C_ToggleButton();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual void onToggle(int (null));
+ virtual int getCurCfgVal();
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ontoggle_id;
+ static int getcurcfgval_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/c_treeitem.cpp b/Src/Wasabi/api/script/objects/c_script/c_treeitem.cpp
new file mode 100644
index 00000000..337c441b
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_treeitem.cpp
@@ -0,0 +1,310 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include "c_treeitem.h"
+#include <api/script/objcontroller.h>
+
+C_TreeItem::C_TreeItem(ScriptObject *object) : C_RootObject(object) {
+ inited = 0;
+ obj = NULL;
+ C_hook(object);
+}
+
+C_TreeItem::C_TreeItem() {
+ inited = 0;
+ obj = NULL;
+}
+
+void C_TreeItem::C_hook(ScriptObject *object) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = object->vcpu_getController();
+ obj = controller->cast(object, treeItemGuid);
+ if (obj != object && obj != NULL)
+ controller = obj->vcpu_getController();
+ else
+ obj = NULL;
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = iter;
+ getnumchildren_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNumChildren", this);
+ setlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setLabel", this);
+ getlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getLabel", this);
+ ensurevisible_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"ensureVisible", this);
+ getnthchild_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getNthChild", this);
+ getchild_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getChild", this);
+ getchildsibling_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getChildSibling", this);
+ getsibling_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getSibling", this);
+ getparent_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getParent", this);
+ editlabel_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"editLabel", this);
+ hassubitems_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"hasSubItems", this);
+ setsorted_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setSorted", this);
+ setchildtab_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setChildTab", this);
+ issorted_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isSorted", this);
+ iscollapsed_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isCollapsed", this);
+ isexpanded_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isExpanded", this);
+ invalidate_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"invalidate", this);
+ isselected_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isSelected", this);
+ ishilited_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"isHilited", this);
+ sethilited_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"setHilited", this);
+ collapse_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"collapse", this);
+ expand_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"expand", this);
+ gettree_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"getTree", this);
+ ontreeadd_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onTreeAdd", this);
+ ontreeremove_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onTreeRemove", this);
+ onselect_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onSelect", this);
+ ondeselect_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onDeselect", this);
+ onleftdoubleclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onLeftDoubleClick", this);
+ onrightdoubleclick_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onRightDoubleClick", this);
+ onchar_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onChar", this);
+ onexpand_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onExpand", this);
+ oncollapse_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onCollapse", this);
+ onbeginlabeledit_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onBeginLabelEdit", this);
+ onendlabeledit_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onEndLabelEdit", this);
+ oncontextmenu_id = WASABI_API_MAKI->maki_addDlfRef(controller, L"onContextMenu", this);
+ }
+ inited = 1;
+}
+
+C_TreeItem::~C_TreeItem() {
+}
+
+ScriptObject *C_TreeItem::getScriptObject() {
+ if (obj != NULL) return obj;
+ return C_TREEITEM_PARENT::getScriptObject();
+}
+
+int C_TreeItem::getNumChildren() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnumchildren_id, NULL));
+}
+
+void C_TreeItem::setLabel(const wchar_t *label)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(label);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setlabel_id, params);
+}
+
+const wchar_t *C_TreeItem::getLabel()
+{
+ ASSERT(inited);
+ return GET_SCRIPT_STRING(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getlabel_id, NULL));
+}
+
+void C_TreeItem::ensureVisible() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ensurevisible_id, NULL);
+}
+
+ScriptObject *C_TreeItem::getNthChild(int nth) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(nth);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getnthchild_id, params));
+}
+
+ScriptObject *C_TreeItem::getChild() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getchild_id, NULL));
+}
+
+ScriptObject *C_TreeItem::getChildSibling(ScriptObject *_item) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_OBJECT(_item);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getchildsibling_id, params));
+}
+
+ScriptObject *C_TreeItem::getSibling() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getsibling_id, NULL));
+}
+
+ScriptObject *C_TreeItem::getParent() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), getparent_id, NULL));
+}
+
+void C_TreeItem::editLabel() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), editlabel_id, NULL);
+}
+
+int C_TreeItem::hasSubItems() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), hassubitems_id, NULL));
+}
+
+void C_TreeItem::setSorted(int issorted) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(issorted);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setsorted_id, params);
+}
+
+void C_TreeItem::setChildTab(int haschildtab) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(haschildtab);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), setchildtab_id, params);
+}
+
+int C_TreeItem::isSorted() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), issorted_id, NULL));
+}
+
+int C_TreeItem::isCollapsed() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), iscollapsed_id, NULL));
+}
+
+int C_TreeItem::isExpanded() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isexpanded_id, NULL));
+}
+
+void C_TreeItem::invalidate() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), invalidate_id, NULL);
+}
+
+int C_TreeItem::isSelected() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), isselected_id, NULL));
+}
+
+int C_TreeItem::isHilited() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), ishilited_id, NULL));
+}
+
+void C_TreeItem::setHilited(int ishilited) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(ishilited);
+ scriptVar *params[1] = {&a};
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), sethilited_id, params);
+}
+
+int C_TreeItem::collapse() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), collapse_id, NULL));
+}
+
+int C_TreeItem::expand() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), expand_id, NULL));
+}
+
+ScriptObject *C_TreeItem::getTree() {
+ ASSERT(inited);
+ return GET_SCRIPT_OBJECT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), gettree_id, NULL));
+}
+
+void C_TreeItem::onTreeAdd() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ontreeadd_id, NULL);
+}
+
+void C_TreeItem::onTreeRemove() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ontreeremove_id, NULL);
+}
+
+void C_TreeItem::onSelect() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onselect_id, NULL);
+}
+
+void C_TreeItem::onDeselect() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), ondeselect_id, NULL);
+}
+
+int C_TreeItem::onLeftDoubleClick() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onleftdoubleclick_id, NULL));
+}
+
+int C_TreeItem::onRightDoubleClick() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onrightdoubleclick_id, NULL));
+}
+
+int C_TreeItem::onChar(int key) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(key);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onchar_id, params));
+}
+
+void C_TreeItem::onExpand() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), onexpand_id, NULL);
+}
+
+void C_TreeItem::onCollapse() {
+ ASSERT(inited);
+ WASABI_API_MAKI->maki_callFunction(getScriptObject(), oncollapse_id, NULL);
+}
+
+int C_TreeItem::onBeginLabelEdit() {
+ ASSERT(inited);
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onbeginlabeledit_id, NULL));
+}
+
+int C_TreeItem::onEndLabelEdit(const wchar_t *newlabel)
+{
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_STRING(newlabel);
+ scriptVar *params[1] = {&a};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), onendlabeledit_id, params));
+}
+
+int C_TreeItem::onContextMenu(int x, int y) {
+ ASSERT(inited);
+ scriptVar a = MAKE_SCRIPT_INT(x);
+ scriptVar b = MAKE_SCRIPT_INT(y);
+ scriptVar *params[2] = {&a, &b};
+ return GET_SCRIPT_INT(WASABI_API_MAKI->maki_callFunction(getScriptObject(), oncontextmenu_id, params));
+}
+
+int C_TreeItem::loaded=0;
+int C_TreeItem::getnumchildren_id=0;
+int C_TreeItem::setlabel_id=0;
+int C_TreeItem::getlabel_id=0;
+int C_TreeItem::ensurevisible_id=0;
+int C_TreeItem::getnthchild_id=0;
+int C_TreeItem::getchild_id=0;
+int C_TreeItem::getchildsibling_id=0;
+int C_TreeItem::getsibling_id=0;
+int C_TreeItem::getparent_id=0;
+int C_TreeItem::editlabel_id=0;
+int C_TreeItem::hassubitems_id=0;
+int C_TreeItem::setsorted_id=0;
+int C_TreeItem::setchildtab_id=0;
+int C_TreeItem::issorted_id=0;
+int C_TreeItem::iscollapsed_id=0;
+int C_TreeItem::isexpanded_id=0;
+int C_TreeItem::invalidate_id=0;
+int C_TreeItem::isselected_id=0;
+int C_TreeItem::ishilited_id=0;
+int C_TreeItem::sethilited_id=0;
+int C_TreeItem::collapse_id=0;
+int C_TreeItem::expand_id=0;
+int C_TreeItem::gettree_id=0;
+int C_TreeItem::ontreeadd_id=0;
+int C_TreeItem::ontreeremove_id=0;
+int C_TreeItem::onselect_id=0;
+int C_TreeItem::ondeselect_id=0;
+int C_TreeItem::onleftdoubleclick_id=0;
+int C_TreeItem::onrightdoubleclick_id=0;
+int C_TreeItem::onchar_id=0;
+int C_TreeItem::onexpand_id=0;
+int C_TreeItem::oncollapse_id=0;
+int C_TreeItem::onbeginlabeledit_id=0;
+int C_TreeItem::onendlabeledit_id=0;
+int C_TreeItem::oncontextmenu_id=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/c_treeitem.h b/Src/Wasabi/api/script/objects/c_script/c_treeitem.h
new file mode 100644
index 00000000..7ff3c78d
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/c_treeitem.h
@@ -0,0 +1,99 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __C_TREEITEM_H
+#define __C_TREEITEM_H
+
+#include "c_rootobj.h"
+
+#define C_TREEITEM_PARENT C_RootObject
+
+class C_TreeItem : public C_TREEITEM_PARENT {
+ public:
+
+ C_TreeItem(ScriptObject *object);
+ C_TreeItem();
+ virtual ~C_TreeItem();
+
+ virtual void C_hook(ScriptObject *o);
+
+ ScriptObject *getScriptObject();
+
+ virtual int getNumChildren();
+ virtual void setLabel(const wchar_t *label);
+ virtual const wchar_t *getLabel();
+ virtual void ensureVisible();
+ virtual ScriptObject *getNthChild(int nth);
+ virtual ScriptObject *getChild();
+ virtual ScriptObject *getChildSibling(ScriptObject *_item);
+ virtual ScriptObject *getSibling();
+ virtual ScriptObject *getParent();
+ virtual void editLabel();
+ virtual int hasSubItems();
+ virtual void setSorted(int issorted);
+ virtual void setChildTab(int haschildtab);
+ virtual int isSorted();
+ virtual int isCollapsed();
+ virtual int isExpanded();
+ virtual void invalidate();
+ virtual int isSelected();
+ virtual int isHilited();
+ virtual void setHilited(int ishilited);
+ virtual int collapse();
+ virtual int expand();
+ virtual ScriptObject *getTree();
+ virtual void onTreeAdd();
+ virtual void onTreeRemove();
+ virtual void onSelect();
+ virtual void onDeselect();
+ virtual int onLeftDoubleClick();
+ virtual int onRightDoubleClick();
+ virtual int onChar(int key);
+ virtual void onExpand();
+ virtual void onCollapse();
+ virtual int onBeginLabelEdit();
+ virtual int onEndLabelEdit(const wchar_t *newlabel);
+ virtual int onContextMenu(int x, int y);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int getnumchildren_id;
+ static int setlabel_id;
+ static int getlabel_id;
+ static int ensurevisible_id;
+ static int getnthchild_id;
+ static int getchild_id;
+ static int getchildsibling_id;
+ static int getsibling_id;
+ static int getparent_id;
+ static int editlabel_id;
+ static int hassubitems_id;
+ static int setsorted_id;
+ static int setchildtab_id;
+ static int issorted_id;
+ static int iscollapsed_id;
+ static int isexpanded_id;
+ static int invalidate_id;
+ static int isselected_id;
+ static int ishilited_id;
+ static int sethilited_id;
+ static int collapse_id;
+ static int expand_id;
+ static int gettree_id;
+ static int ontreeadd_id;
+ static int ontreeremove_id;
+ static int onselect_id;
+ static int ondeselect_id;
+ static int onleftdoubleclick_id;
+ static int onrightdoubleclick_id;
+ static int onchar_id;
+ static int onexpand_id;
+ static int oncollapse_id;
+ static int onbeginlabeledit_id;
+ static int onendlabeledit_id;
+ static int oncontextmenu_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/gen.m b/Src/Wasabi/api/script/objects/c_script/gen.m
new file mode 100644
index 00000000..e3f89a27
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/gen.m
@@ -0,0 +1,22 @@
+#include <lib/std.mi>
+
+#export_cclass GuiObject
+#export_cclass Browser
+#export_cclass Button
+#export_cclass Container
+#export_cclass DropDownList
+#export_cclass Edit
+#export_cclass Group
+#export_cclass GuiList
+#export_cclass GuiTree
+#export_cclass Layout
+#export_cclass MenuButton
+#export_cclass Slider
+#export_cclass Text
+#export_cclass ToggleButton
+#export_cclass TreeItem
+#export_cclass CheckBox
+#export_cclass GroupList
+#export_cclass TabSheet
+
+#abort "All done."
diff --git a/Src/Wasabi/api/script/objects/c_script/h_browser.cpp b/Src/Wasabi/api/script/objects/c_script/h_browser.cpp
new file mode 100644
index 00000000..9eb6eaa2
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_browser.cpp
@@ -0,0 +1,85 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_browser.h"
+
+H_Browser::H_Browser(ScriptObject *o) : H_GuiObject(o)
+{
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Browser::H_Browser()
+{
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Browser::H_hook(ScriptObject *o)
+{
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, browserGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &browserGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter)
+ {
+ onbeforenavigate_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onBeforeNavigate", this);
+ ondocumentcomplete_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onDocumentComplete", this);
+ onmedialink_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMediaLink", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Browser::~H_Browser()
+{
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Browser::getHookedObject()
+{
+ if (obj != NULL) return obj;
+ return H_BROWSER_PARENT::getHookedObject();
+}
+
+int H_Browser::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams)
+{
+ if (object != getHookedObject()) return 0;
+ if (H_BROWSER_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+
+ if (dlfid == onbeforenavigate_id)
+ {
+ hook_onBeforeNavigate(GET_SCRIPT_STRING(*params[0]), GET_SCRIPT_INT(*params[1]), GET_SCRIPT_STRING(*params[2]));
+ return 1;
+ }
+ else if (dlfid == ondocumentcomplete_id)
+ {
+ hook_onDocumentComplete(GET_SCRIPT_STRING(*params[0]));
+ return 1;
+ }
+ else if (dlfid == onmedialink_id)
+ {
+
+ hook_onMediaLink(GET_SCRIPT_STRING(*params[0]));
+ return 1;
+ }
+
+ return 0;
+
+}
+
+int H_Browser::onbeforenavigate_id=0;
+int H_Browser::ondocumentcomplete_id=0;
+int H_Browser::onmedialink_id=0;
+int H_Browser::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_browser.h b/Src/Wasabi/api/script/objects/c_script/h_browser.h
new file mode 100644
index 00000000..1c958f10
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_browser.h
@@ -0,0 +1,35 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_BROWSER_H
+#define __HOOK_BROWSER_H
+
+#include "h_guiobject.h"
+
+#define H_BROWSER_PARENT H_GuiObject
+
+class H_Browser : public H_BROWSER_PARENT {
+
+public:
+
+ H_Browser(ScriptObject *o);
+ H_Browser();
+ virtual ~H_Browser();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *targetframename) { }
+ virtual void hook_onDocumentComplete(const wchar_t *url) { }
+ virtual void hook_onMediaLink(const wchar_t *url) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onbeforenavigate_id;
+ static int ondocumentcomplete_id;
+ static int onmedialink_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_button.cpp b/Src/Wasabi/api/script/objects/c_script/h_button.cpp
new file mode 100644
index 00000000..5477e4fa
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_button.cpp
@@ -0,0 +1,62 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_button.h"
+
+H_Button::H_Button(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Button::H_Button() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Button::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, buttonGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &buttonGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onactivate_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onActivate", this);
+ onleftclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeftClick", this);
+ onrightclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onRightClick", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Button::~H_Button() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Button::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_BUTTON_PARENT::getHookedObject();
+}
+
+int H_Button::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_BUTTON_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onactivate_id) { hook_onActivate(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onleftclick_id) { hook_onLeftClick(); return 1; }
+ if (dlfid == onrightclick_id) { hook_onRightClick(); return 1; }
+ return 0;
+}
+
+int H_Button::onactivate_id=0;
+int H_Button::onleftclick_id=0;
+int H_Button::onrightclick_id=0;
+int H_Button::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_button.h b/Src/Wasabi/api/script/objects/c_script/h_button.h
new file mode 100644
index 00000000..32cc15e2
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_button.h
@@ -0,0 +1,35 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_BUTTON_H
+#define __HOOK_BUTTON_H
+
+#include "h_guiobject.h"
+
+#define H_BUTTON_PARENT H_GuiObject
+
+class H_Button : public H_BUTTON_PARENT {
+
+public:
+
+ H_Button(ScriptObject *o);
+ H_Button();
+ virtual ~H_Button();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onActivate(int activated) { }
+ virtual void hook_onLeftClick() { }
+ virtual void hook_onRightClick() { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onactivate_id;
+ static int onleftclick_id;
+ static int onrightclick_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_checkbox.cpp b/Src/Wasabi/api/script/objects/c_script/h_checkbox.cpp
new file mode 100644
index 00000000..4c5a0d97
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_checkbox.cpp
@@ -0,0 +1,56 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_checkbox.h"
+
+H_CheckBox::H_CheckBox(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_CheckBox::H_CheckBox() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_CheckBox::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, checkBoxGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &checkBoxGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ ontoggle_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onToggle", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_CheckBox::~H_CheckBox() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_CheckBox::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_CHECKBOX_PARENT::getHookedObject();
+}
+
+int H_CheckBox::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_CHECKBOX_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == ontoggle_id) { hook_onToggle(GET_SCRIPT_INT(*params[0])); return 1; }
+ return 0;
+}
+
+int H_CheckBox::ontoggle_id=0;
+int H_CheckBox::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_checkbox.h b/Src/Wasabi/api/script/objects/c_script/h_checkbox.h
new file mode 100644
index 00000000..e1725073
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_checkbox.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_CHECKBOX_H
+#define __HOOK_CHECKBOX_H
+
+#include "h_guiobject.h"
+
+#define H_CHECKBOX_PARENT H_GuiObject
+
+class H_CheckBox : public H_CHECKBOX_PARENT {
+
+public:
+
+ H_CheckBox(ScriptObject *o);
+ H_CheckBox();
+ virtual ~H_CheckBox();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onToggle(int newstate) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ontoggle_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_container.cpp b/Src/Wasabi/api/script/objects/c_script/h_container.cpp
new file mode 100644
index 00000000..b665af5c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_container.cpp
@@ -0,0 +1,65 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_container.h"
+
+H_Container::H_Container(ScriptObject *o) : H_RootObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Container::H_Container() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Container::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, containerGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &containerGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onswitchtolayout_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSwitchToLayout", this);
+ onbeforeswitchtolayout_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onBeforeSwitchToLayout", this);
+ onhidelayout_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onHideLayout", this);
+ onshowlayout_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onShowLayout", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Container::~H_Container() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Container::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_CONTAINER_PARENT::getHookedObject();
+}
+
+int H_Container::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_CONTAINER_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onswitchtolayout_id) { hook_onSwitchToLayout(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ if (dlfid == onbeforeswitchtolayout_id) { hook_onBeforeSwitchToLayout(GET_SCRIPT_OBJECT(*params[0]), GET_SCRIPT_OBJECT(*params[1])); return 1; }
+ if (dlfid == onhidelayout_id) { hook_onHideLayout(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ if (dlfid == onshowlayout_id) { hook_onShowLayout(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ return 0;
+}
+
+int H_Container::onswitchtolayout_id=0;
+int H_Container::onbeforeswitchtolayout_id=0;
+int H_Container::onhidelayout_id=0;
+int H_Container::onshowlayout_id=0;
+int H_Container::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_container.h b/Src/Wasabi/api/script/objects/c_script/h_container.h
new file mode 100644
index 00000000..eae5069d
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_container.h
@@ -0,0 +1,37 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_CONTAINER_H
+#define __HOOK_CONTAINER_H
+
+#include "h_rootobj.h"
+
+#define H_CONTAINER_PARENT H_RootObject
+
+class H_Container : public H_CONTAINER_PARENT {
+
+public:
+
+ H_Container(ScriptObject *o);
+ H_Container();
+ virtual ~H_Container();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onSwitchToLayout(ScriptObject *newlayout) { }
+ virtual void hook_onBeforeSwitchToLayout(ScriptObject *oldlayout, ScriptObject *newlayout) { }
+ virtual void hook_onHideLayout(ScriptObject *_layout) { }
+ virtual void hook_onShowLayout(ScriptObject *_layout) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onswitchtolayout_id;
+ static int onbeforeswitchtolayout_id;
+ static int onhidelayout_id;
+ static int onshowlayout_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_dropdownlist.cpp b/Src/Wasabi/api/script/objects/c_script/h_dropdownlist.cpp
new file mode 100644
index 00000000..a6d14f7a
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_dropdownlist.cpp
@@ -0,0 +1,56 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_dropdownlist.h"
+
+H_DropDownList::H_DropDownList(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_DropDownList::H_DropDownList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_DropDownList::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, dropDownListGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &dropDownListGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onselect_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSelect", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_DropDownList::~H_DropDownList() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_DropDownList::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_DROPDOWNLIST_PARENT::getHookedObject();
+}
+
+int H_DropDownList::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_DROPDOWNLIST_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onselect_id) { hook_onSelect(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ return 0;
+}
+
+int H_DropDownList::onselect_id=0;
+int H_DropDownList::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_dropdownlist.h b/Src/Wasabi/api/script/objects/c_script/h_dropdownlist.h
new file mode 100644
index 00000000..a044cf8c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_dropdownlist.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_DROPDOWNLIST_H
+#define __HOOK_DROPDOWNLIST_H
+
+#include "h_guiobject.h"
+
+#define H_DROPDOWNLIST_PARENT H_GuiObject
+
+class H_DropDownList : public H_DROPDOWNLIST_PARENT {
+
+public:
+
+ H_DropDownList(ScriptObject *o);
+ H_DropDownList();
+ virtual ~H_DropDownList();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onSelect(int id, int hover) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onselect_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_edit.cpp b/Src/Wasabi/api/script/objects/c_script/h_edit.cpp
new file mode 100644
index 00000000..2bb72698
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_edit.cpp
@@ -0,0 +1,65 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_edit.h"
+
+H_Edit::H_Edit(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Edit::H_Edit() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Edit::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, editGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &editGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onenter_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onEnter", this);
+ onabort_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onAbort", this);
+ onidleeditupdate_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onIdleEditUpdate", this);
+ oneditupdate_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onEditUpdate", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Edit::~H_Edit() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Edit::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_EDIT_PARENT::getHookedObject();
+}
+
+int H_Edit::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_EDIT_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onenter_id) { hook_onEnter(); return 1; }
+ if (dlfid == onabort_id) { hook_onAbort(); return 1; }
+ if (dlfid == onidleeditupdate_id) { hook_onIdleEditUpdate(); return 1; }
+ if (dlfid == oneditupdate_id) { hook_onEditUpdate(); return 1; }
+ return 0;
+}
+
+int H_Edit::onenter_id=0;
+int H_Edit::onabort_id=0;
+int H_Edit::onidleeditupdate_id=0;
+int H_Edit::oneditupdate_id=0;
+int H_Edit::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_edit.h b/Src/Wasabi/api/script/objects/c_script/h_edit.h
new file mode 100644
index 00000000..d267cd89
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_edit.h
@@ -0,0 +1,37 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_EDIT_H
+#define __HOOK_EDIT_H
+
+#include "h_guiobject.h"
+
+#define H_EDIT_PARENT H_GuiObject
+
+class H_Edit : public H_EDIT_PARENT {
+
+public:
+
+ H_Edit(ScriptObject *o);
+ H_Edit();
+ virtual ~H_Edit();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onEnter() { }
+ virtual void hook_onAbort() { }
+ virtual void hook_onIdleEditUpdate() { }
+ virtual void hook_onEditUpdate() { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onenter_id;
+ static int onabort_id;
+ static int onidleeditupdate_id;
+ static int oneditupdate_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_group.cpp b/Src/Wasabi/api/script/objects/c_script/h_group.cpp
new file mode 100644
index 00000000..36aaadda
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_group.cpp
@@ -0,0 +1,56 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_group.h"
+
+H_Group::H_Group(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Group::H_Group() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Group::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, groupGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &groupGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ oncreateobject_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onCreateObject", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Group::~H_Group() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Group::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_GROUP_PARENT::getHookedObject();
+}
+
+int H_Group::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_GROUP_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == oncreateobject_id) { hook_onCreateObject(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ return 0;
+}
+
+int H_Group::oncreateobject_id=0;
+int H_Group::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_group.h b/Src/Wasabi/api/script/objects/c_script/h_group.h
new file mode 100644
index 00000000..06dbefb0
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_group.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_GROUP_H
+#define __HOOK_GROUP_H
+
+#include "h_guiobject.h"
+
+#define H_GROUP_PARENT H_GuiObject
+
+class H_Group : public H_GROUP_PARENT {
+
+public:
+
+ H_Group(ScriptObject *o);
+ H_Group();
+ virtual ~H_Group();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onCreateObject(ScriptObject *newobj) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int oncreateobject_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_grouplist.cpp b/Src/Wasabi/api/script/objects/c_script/h_grouplist.cpp
new file mode 100644
index 00000000..4a9aecaa
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_grouplist.cpp
@@ -0,0 +1,53 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+#include <api/api.h>
+#include <api/script/objcontroller.h>
+#include "h_grouplist.h"
+
+H_GroupList::H_GroupList(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_GroupList::H_GroupList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_GroupList::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, groupListGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &groupListGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_GroupList::~H_GroupList() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_GroupList::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_GROUPLIST_PARENT::getHookedObject();
+}
+
+int H_GroupList::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_GROUPLIST_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ return 0;
+}
+
+int H_GroupList::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_grouplist.h b/Src/Wasabi/api/script/objects/c_script/h_grouplist.h
new file mode 100644
index 00000000..460b94ab
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_grouplist.h
@@ -0,0 +1,29 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_GROUPLIST_H
+#define __HOOK_GROUPLIST_H
+
+#include "h_guiobject.h"
+
+#define H_GROUPLIST_PARENT H_GuiObject
+
+class H_GroupList : public H_GROUPLIST_PARENT {
+
+public:
+
+ H_GroupList(ScriptObject *o);
+ H_GroupList();
+ virtual ~H_GroupList();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_guilist.cpp b/Src/Wasabi/api/script/objects/c_script/h_guilist.cpp
new file mode 100644
index 00000000..e108c898
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_guilist.cpp
@@ -0,0 +1,83 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_guilist.h"
+
+H_GuiList::H_GuiList(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_GuiList::H_GuiList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_GuiList::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, guiListGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &guiListGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onsetvisible_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSetVisible", this);
+ onselectall_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSelectAll", this);
+ ondelete_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onDelete", this);
+ ondoubleclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onDoubleClick", this);
+ onleftclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeftClick", this);
+ onsecondleftclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSecondLeftClick", this);
+ onrightclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onRightClick", this);
+ oncolumndblclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onColumnDblClick", this);
+ oncolumnlabelclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onColumnLabelClick", this);
+ onitemselection_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onItemSelection", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_GuiList::~H_GuiList() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_GuiList::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_GUILIST_PARENT::getHookedObject();
+}
+
+int H_GuiList::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_GUILIST_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onsetvisible_id) { hook_onSetVisible(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onselectall_id) { hook_onSelectAll(); return 1; }
+ if (dlfid == ondelete_id) { hook_onDelete(); return 1; }
+ if (dlfid == ondoubleclick_id) { hook_onDoubleClick(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onleftclick_id) { hook_onLeftClick(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onsecondleftclick_id) { hook_onSecondLeftClick(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onrightclick_id) { hook_onRightClick(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == oncolumndblclick_id) { hook_onColumnDblClick(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1]), GET_SCRIPT_INT(*params[2])); return 1; }
+ if (dlfid == oncolumnlabelclick_id) { hook_onColumnLabelClick(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1]), GET_SCRIPT_INT(*params[2])); return 1; }
+ if (dlfid == onitemselection_id) { hook_onItemSelection(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ return 0;
+}
+
+int H_GuiList::onsetvisible_id=0;
+int H_GuiList::onselectall_id=0;
+int H_GuiList::ondelete_id=0;
+int H_GuiList::ondoubleclick_id=0;
+int H_GuiList::onleftclick_id=0;
+int H_GuiList::onsecondleftclick_id=0;
+int H_GuiList::onrightclick_id=0;
+int H_GuiList::oncolumndblclick_id=0;
+int H_GuiList::oncolumnlabelclick_id=0;
+int H_GuiList::onitemselection_id=0;
+int H_GuiList::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_guilist.h b/Src/Wasabi/api/script/objects/c_script/h_guilist.h
new file mode 100644
index 00000000..d762abb3
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_guilist.h
@@ -0,0 +1,49 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_GUILIST_H
+#define __HOOK_GUILIST_H
+
+#include "h_guiobject.h"
+
+#define H_GUILIST_PARENT H_GuiObject
+
+class H_GuiList : public H_GUILIST_PARENT {
+
+public:
+
+ H_GuiList(ScriptObject *o);
+ H_GuiList();
+ virtual ~H_GuiList();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onSetVisible(int show) { }
+ virtual void hook_onSelectAll() { }
+ virtual void hook_onDelete() { }
+ virtual void hook_onDoubleClick(int itemnum) { }
+ virtual void hook_onLeftClick(int itemnum) { }
+ virtual void hook_onSecondLeftClick(int itemnum) { }
+ virtual void hook_onRightClick(int itemnum) { }
+ virtual void hook_onColumnDblClick(int col, int x, int y) { }
+ virtual void hook_onColumnLabelClick(int col, int x, int y) { }
+ virtual void hook_onItemSelection(int itemnum, int selected) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onsetvisible_id;
+ static int onselectall_id;
+ static int ondelete_id;
+ static int ondoubleclick_id;
+ static int onleftclick_id;
+ static int onsecondleftclick_id;
+ static int onrightclick_id;
+ static int oncolumndblclick_id;
+ static int oncolumnlabelclick_id;
+ static int onitemselection_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_guiobject.cpp b/Src/Wasabi/api/script/objects/c_script/h_guiobject.cpp
new file mode 100644
index 00000000..b4867dd8
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_guiobject.cpp
@@ -0,0 +1,117 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_guiobject.h"
+#include "../nu/AUtoChar.h"
+
+H_GuiObject::H_GuiObject(ScriptObject *o) : H_RootObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_GuiObject::H_GuiObject() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_GuiObject::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, guiObjectGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &guiObjectGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onsetvisible_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSetVisible", this);
+ onleftbuttonup_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeftButtonUp", this);
+ onleftbuttondown_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeftButtonDown", this);
+ onrightbuttonup_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onRightButtonUp", this);
+ onrightbuttondown_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onRightButtonDown", this);
+ onrightbuttondblclk_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onRightButtonDblClk", this);
+ onleftbuttondblclk_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeftButtonDblClk", this);
+ onmousemove_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMouseMove", this);
+ onenterarea_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onEnterArea", this);
+ onleavearea_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeaveArea", this);
+ onenable_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onEnable", this);
+ onresize_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onResize", this);
+ ontargetreached_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onTargetReached", this);
+ onstartup_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onStartup", this);
+ onchar_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onChar", this);
+ onaccelerator_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onAccelerator", this);
+ onkeydown_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onKeyDown", this);
+ onkeyup_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onKeyUp", this);
+ ongetfocus_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onGetFocus", this);
+ onkillfocus_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onKillFocus", this);
+ onaction_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onAction", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_GuiObject::~H_GuiObject() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_GuiObject::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_GUIOBJECT_PARENT::getHookedObject();
+}
+
+int H_GuiObject::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_GUIOBJECT_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onsetvisible_id) { hook_onSetVisible(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onleftbuttonup_id) { hook_onLeftButtonUp(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onleftbuttondown_id) { hook_onLeftButtonDown(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onrightbuttonup_id) { hook_onRightButtonUp(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onrightbuttondown_id) { hook_onRightButtonDown(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onrightbuttondblclk_id) { hook_onRightButtonDblClk(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onleftbuttondblclk_id) { hook_onLeftButtonDblClk(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onmousemove_id) { hook_onMouseMove(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onenterarea_id) { hook_onEnterArea(); return 1; }
+ if (dlfid == onleavearea_id) { hook_onLeaveArea(); return 1; }
+ if (dlfid == onenable_id) { hook_onEnable(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onresize_id) { hook_onResize(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1]), GET_SCRIPT_INT(*params[2]), GET_SCRIPT_INT(*params[3])); return 1; }
+ if (dlfid == ontargetreached_id) { hook_onTargetReached(); return 1; }
+ if (dlfid == onstartup_id) { hook_onStartup(); return 1; }
+ if (dlfid == onchar_id) { hook_onChar(GET_SCRIPT_STRING(*params[0])); return 1; }
+ if (dlfid == onaccelerator_id) { hook_onAccelerator(GET_SCRIPT_STRING(*params[0])); return 1; }
+ if (dlfid == onkeydown_id) { hook_onKeyDown(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onkeyup_id) { hook_onKeyUp(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == ongetfocus_id) { hook_onGetFocus(); return 1; }
+ if (dlfid == onkillfocus_id) { hook_onKillFocus(); return 1; }
+ if (dlfid == onaction_id) { hook_onAction(GET_SCRIPT_STRING(*params[0]), GET_SCRIPT_STRING(*params[1]), GET_SCRIPT_INT(*params[2]), GET_SCRIPT_INT(*params[3]), GET_SCRIPT_INT(*params[4]), GET_SCRIPT_INT(*params[5]), GET_SCRIPT_OBJECT(*params[6])); return 1; }
+ return 0;
+}
+
+int H_GuiObject::onsetvisible_id=0;
+int H_GuiObject::onleftbuttonup_id=0;
+int H_GuiObject::onleftbuttondown_id=0;
+int H_GuiObject::onrightbuttonup_id=0;
+int H_GuiObject::onrightbuttondown_id=0;
+int H_GuiObject::onrightbuttondblclk_id=0;
+int H_GuiObject::onleftbuttondblclk_id=0;
+int H_GuiObject::onmousemove_id=0;
+int H_GuiObject::onenterarea_id=0;
+int H_GuiObject::onleavearea_id=0;
+int H_GuiObject::onenable_id=0;
+int H_GuiObject::onresize_id=0;
+int H_GuiObject::ontargetreached_id=0;
+int H_GuiObject::onstartup_id=0;
+int H_GuiObject::onchar_id=0;
+int H_GuiObject::onaccelerator_id=0;
+int H_GuiObject::onkeydown_id=0;
+int H_GuiObject::onkeyup_id=0;
+int H_GuiObject::ongetfocus_id=0;
+int H_GuiObject::onkillfocus_id=0;
+int H_GuiObject::onaction_id=0;
+int H_GuiObject::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_guiobject.h b/Src/Wasabi/api/script/objects/c_script/h_guiobject.h
new file mode 100644
index 00000000..d73900bf
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_guiobject.h
@@ -0,0 +1,71 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_GUIOBJECT_H
+#define __HOOK_GUIOBJECT_H
+
+#include "h_rootobj.h"
+
+#define H_GUIOBJECT_PARENT H_RootObject
+
+class H_GuiObject : public H_GUIOBJECT_PARENT {
+
+public:
+
+ H_GuiObject(ScriptObject *o);
+ H_GuiObject();
+ virtual ~H_GuiObject();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onSetVisible(int onoff) { }
+ virtual void hook_onLeftButtonUp(int x, int y) { }
+ virtual void hook_onLeftButtonDown(int x, int y) { }
+ virtual void hook_onRightButtonUp(int x, int y) { }
+ virtual void hook_onRightButtonDown(int x, int y) { }
+ virtual void hook_onRightButtonDblClk(int x, int y) { }
+ virtual void hook_onLeftButtonDblClk(int x, int y) { }
+ virtual void hook_onMouseMove(int x, int y) { }
+ virtual void hook_onEnterArea() { }
+ virtual void hook_onLeaveArea() { }
+ virtual void hook_onEnable(int onoff) { }
+ virtual void hook_onResize(int x, int y, int w, int h) { }
+ virtual void hook_onTargetReached() { }
+ virtual void hook_onStartup() { }
+ virtual void hook_onChar(const wchar_t *c) { }
+ virtual void hook_onAccelerator(const wchar_t *accel) { }
+ virtual void hook_onKeyDown(int vk_code) { }
+ virtual void hook_onKeyUp(int vk_code) { }
+ virtual void hook_onGetFocus() { }
+ virtual void hook_onKillFocus() { }
+ virtual void hook_onAction(const wchar_t *action, const wchar_t *param, int x, int y, int p1, int p2, ScriptObject *source) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onsetvisible_id;
+ static int onleftbuttonup_id;
+ static int onleftbuttondown_id;
+ static int onrightbuttonup_id;
+ static int onrightbuttondown_id;
+ static int onrightbuttondblclk_id;
+ static int onleftbuttondblclk_id;
+ static int onmousemove_id;
+ static int onenterarea_id;
+ static int onleavearea_id;
+ static int onenable_id;
+ static int onresize_id;
+ static int ontargetreached_id;
+ static int onstartup_id;
+ static int onchar_id;
+ static int onaccelerator_id;
+ static int onkeydown_id;
+ static int onkeyup_id;
+ static int ongetfocus_id;
+ static int onkillfocus_id;
+ static int onaction_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_guitree.cpp b/Src/Wasabi/api/script/objects/c_script/h_guitree.cpp
new file mode 100644
index 00000000..28363b06
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_guitree.cpp
@@ -0,0 +1,80 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_guitree.h"
+
+H_GuiTree::H_GuiTree(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_GuiTree::H_GuiTree() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_GuiTree::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, guiTreeGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &guiTreeGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onwantautocontextmenu_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onWantAutoContextMenu", this);
+ onmousewheelup_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMouseWheelUp", this);
+ onmousewheeldown_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMouseWheelDown", this);
+ oncontextmenu_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onContextMenu", this);
+ onchar_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onChar", this);
+ onitemrecvdrop_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onItemRecvDrop", this);
+ onlabelchange_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLabelChange", this);
+ onitemselected_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onItemSelected", this);
+ onitemdeselected_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onItemDeselected", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_GuiTree::~H_GuiTree() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_GuiTree::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_GUITREE_PARENT::getHookedObject();
+}
+
+int H_GuiTree::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_GUITREE_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onwantautocontextmenu_id) { hook_onWantAutoContextMenu(); return 1; }
+ if (dlfid == onmousewheelup_id) { hook_onMouseWheelUp(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onmousewheeldown_id) { hook_onMouseWheelDown(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == oncontextmenu_id) { hook_onContextMenu(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ if (dlfid == onchar_id) { hook_onChar(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onitemrecvdrop_id) { hook_onItemRecvDrop(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ if (dlfid == onlabelchange_id) { hook_onLabelChange(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ if (dlfid == onitemselected_id) { hook_onItemSelected(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ if (dlfid == onitemdeselected_id) { hook_onItemDeselected(GET_SCRIPT_OBJECT(*params[0])); return 1; }
+ return 0;
+}
+
+int H_GuiTree::onwantautocontextmenu_id=0;
+int H_GuiTree::onmousewheelup_id=0;
+int H_GuiTree::onmousewheeldown_id=0;
+int H_GuiTree::oncontextmenu_id=0;
+int H_GuiTree::onchar_id=0;
+int H_GuiTree::onitemrecvdrop_id=0;
+int H_GuiTree::onlabelchange_id=0;
+int H_GuiTree::onitemselected_id=0;
+int H_GuiTree::onitemdeselected_id=0;
+int H_GuiTree::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_guitree.h b/Src/Wasabi/api/script/objects/c_script/h_guitree.h
new file mode 100644
index 00000000..c56c28b7
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_guitree.h
@@ -0,0 +1,47 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_GUITREE_H
+#define __HOOK_GUITREE_H
+
+#include "h_guiobject.h"
+
+#define H_GUITREE_PARENT H_GuiObject
+
+class H_GuiTree : public H_GUITREE_PARENT {
+
+public:
+
+ H_GuiTree(ScriptObject *o);
+ H_GuiTree();
+ virtual ~H_GuiTree();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onWantAutoContextMenu() { }
+ virtual void hook_onMouseWheelUp(int clicked, int lines) { }
+ virtual void hook_onMouseWheelDown(int clicked, int lines) { }
+ virtual void hook_onContextMenu(int x, int y) { }
+ virtual void hook_onChar(wchar_t c) { }
+ virtual void hook_onItemRecvDrop(ScriptObject *item) { }
+ virtual void hook_onLabelChange(ScriptObject *item) { }
+ virtual void hook_onItemSelected(ScriptObject *item) { }
+ virtual void hook_onItemDeselected(ScriptObject *item) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onwantautocontextmenu_id;
+ static int onmousewheelup_id;
+ static int onmousewheeldown_id;
+ static int oncontextmenu_id;
+ static int onchar_id;
+ static int onitemrecvdrop_id;
+ static int onlabelchange_id;
+ static int onitemselected_id;
+ static int onitemdeselected_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_layout.cpp b/Src/Wasabi/api/script/objects/c_script/h_layout.cpp
new file mode 100644
index 00000000..385cc852
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_layout.cpp
@@ -0,0 +1,80 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_layout.h"
+
+H_Layout::H_Layout(ScriptObject *o) : H_Group(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Layout::H_Layout() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Layout::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, layoutGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &layoutGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ ondock_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onDock", this);
+ onundock_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onUndock", this);
+ onscale_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onScale", this);
+ onmove_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMove", this);
+ onendmove_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onEndMove", this);
+ onuserresize_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onUserResize", this);
+ onmouseenterlayout_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMouseEnterLayout", this);
+ onmouseleavelayout_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onMouseLeaveLayout", this);
+ onsnapadjustchanged_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSnapAdjustChanged", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Layout::~H_Layout() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Layout::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_LAYOUT_PARENT::getHookedObject();
+}
+
+int H_Layout::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_LAYOUT_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == ondock_id) { hook_onDock(); return 1; }
+ if (dlfid == onundock_id) { hook_onUndock(); return 1; }
+ if (dlfid == onscale_id) { hook_onScale(GET_SCRIPT_DOUBLE(*params[0])); return 1; }
+ if (dlfid == onmove_id) { hook_onMove(); return 1; }
+ if (dlfid == onendmove_id) { hook_onEndMove(); return 1; }
+ if (dlfid == onuserresize_id) { hook_onUserResize(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1]), GET_SCRIPT_INT(*params[2]), GET_SCRIPT_INT(*params[3])); return 1; }
+ if (dlfid == onmouseenterlayout_id) { hook_onMouseEnterLayout(); return 1; }
+ if (dlfid == onmouseleavelayout_id) { hook_onMouseLeaveLayout(); return 1; }
+ if (dlfid == onsnapadjustchanged_id) { hook_onSnapAdjustChanged(); return 1; }
+ return 0;
+}
+
+int H_Layout::ondock_id=0;
+int H_Layout::onundock_id=0;
+int H_Layout::onscale_id=0;
+int H_Layout::onmove_id=0;
+int H_Layout::onendmove_id=0;
+int H_Layout::onuserresize_id=0;
+int H_Layout::onmouseenterlayout_id=0;
+int H_Layout::onmouseleavelayout_id=0;
+int H_Layout::onsnapadjustchanged_id=0;
+int H_Layout::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_layout.h b/Src/Wasabi/api/script/objects/c_script/h_layout.h
new file mode 100644
index 00000000..1b19c3e7
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_layout.h
@@ -0,0 +1,47 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_LAYOUT_H
+#define __HOOK_LAYOUT_H
+
+#include "h_group.h"
+
+#define H_LAYOUT_PARENT H_Group
+
+class H_Layout : public H_LAYOUT_PARENT {
+
+public:
+
+ H_Layout(ScriptObject *o);
+ H_Layout();
+ virtual ~H_Layout();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onDock() { }
+ virtual void hook_onUndock() { }
+ virtual void hook_onScale(double newscalevalue) { }
+ virtual void hook_onMove() { }
+ virtual void hook_onEndMove() { }
+ virtual void hook_onUserResize(int x, int y, int w, int h) { }
+ virtual void hook_onMouseEnterLayout() { }
+ virtual void hook_onMouseLeaveLayout() { }
+ virtual void hook_onSnapAdjustChanged() { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ondock_id;
+ static int onundock_id;
+ static int onscale_id;
+ static int onmove_id;
+ static int onendmove_id;
+ static int onuserresize_id;
+ static int onmouseenterlayout_id;
+ static int onmouseleavelayout_id;
+ static int onsnapadjustchanged_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_menubutton.cpp b/Src/Wasabi/api/script/objects/c_script/h_menubutton.cpp
new file mode 100644
index 00000000..bce0f405
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_menubutton.cpp
@@ -0,0 +1,62 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_menubutton.h"
+
+H_MenuButton::H_MenuButton(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_MenuButton::H_MenuButton() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_MenuButton::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, menuButtonGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &menuButtonGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onopenmenu_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onOpenMenu", this);
+ onclosemenu_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onCloseMenu", this);
+ onselectitem_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSelectItem", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_MenuButton::~H_MenuButton() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_MenuButton::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_MENUBUTTON_PARENT::getHookedObject();
+}
+
+int H_MenuButton::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_MENUBUTTON_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onopenmenu_id) { hook_onOpenMenu(); return 1; }
+ if (dlfid == onclosemenu_id) { hook_onCloseMenu(); return 1; }
+ if (dlfid == onselectitem_id) { hook_onSelectItem(GET_SCRIPT_STRING(*params[0])); return 1; }
+ return 0;
+}
+
+int H_MenuButton::onopenmenu_id=0;
+int H_MenuButton::onclosemenu_id=0;
+int H_MenuButton::onselectitem_id=0;
+int H_MenuButton::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_menubutton.h b/Src/Wasabi/api/script/objects/c_script/h_menubutton.h
new file mode 100644
index 00000000..c55b4791
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_menubutton.h
@@ -0,0 +1,35 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_MENUBUTTON_H
+#define __HOOK_MENUBUTTON_H
+
+#include "h_guiobject.h"
+
+#define H_MENUBUTTON_PARENT H_GuiObject
+
+class H_MenuButton : public H_MENUBUTTON_PARENT {
+
+public:
+
+ H_MenuButton(ScriptObject *o);
+ H_MenuButton();
+ virtual ~H_MenuButton();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onOpenMenu() { }
+ virtual void hook_onCloseMenu() { }
+ virtual void hook_onSelectItem(const wchar_t *item) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onopenmenu_id;
+ static int onclosemenu_id;
+ static int onselectitem_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_querylist.cpp b/Src/Wasabi/api/script/objects/c_script/h_querylist.cpp
new file mode 100644
index 00000000..061f298e
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_querylist.cpp
@@ -0,0 +1,54 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_querylist.h"
+
+H_QueryList::H_QueryList(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_QueryList::H_QueryList() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_QueryList::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, queryListGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &queryListGuid);
+ if (loaded == 0) {
+ onresetquery_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onResetQuery", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_QueryList::~H_QueryList() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_QueryList::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_QUERYLIST_PARENT::getHookedObject();
+}
+
+int H_QueryList::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_QUERYLIST_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onresetquery_id) { hook_onResetQuery(); return 1; }
+ return 0;
+}
+
+int H_QueryList::onresetquery_id=0;
+int H_QueryList::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_querylist.h b/Src/Wasabi/api/script/objects/c_script/h_querylist.h
new file mode 100644
index 00000000..e95b3015
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_querylist.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_QUERYLIST_H
+#define __HOOK_QUERYLIST_H
+
+#include "h_guiobject.h"
+
+#define H_QUERYLIST_PARENT H_GuiObject
+
+class H_QueryList : public H_QUERYLIST_PARENT {
+
+public:
+
+ H_QueryList(ScriptObject *o);
+ H_QueryList();
+ virtual ~H_QueryList();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onResetQuery() { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onresetquery_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_rootobj.cpp b/Src/Wasabi/api/script/objects/c_script/h_rootobj.cpp
new file mode 100644
index 00000000..72ccc990
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_rootobj.cpp
@@ -0,0 +1,41 @@
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_rootobj.h"
+
+H_RootObject::H_RootObject(ScriptObject *o) {
+ inited = 0;
+ me = NULL;
+ H_hook(o);
+}
+
+H_RootObject::H_RootObject() {
+ inited = 0;
+ me = NULL;
+}
+
+void H_RootObject::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ me = o;
+ addMonitorObject(o, &rootObjectGuid);
+ if (count++ == 0) {
+ onnotify_id = WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onNotify", this);
+ }
+ inited=1;
+}
+
+H_RootObject::~H_RootObject() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+ //count--;
+}
+
+int H_RootObject::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (dlfid == onnotify_id) { hook_onNotify(GET_SCRIPT_STRING(*params[0]), GET_SCRIPT_STRING(*params[1]), GET_SCRIPT_INT(*params[2]), GET_SCRIPT_INT(*params[3])); return 1; }
+ return 0;
+}
+
+int H_RootObject::onnotify_id=0;
+int H_RootObject::inited=0;
+int H_RootObject::count=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_rootobj.h b/Src/Wasabi/api/script/objects/c_script/h_rootobj.h
new file mode 100644
index 00000000..8488f7c7
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_rootobj.h
@@ -0,0 +1,30 @@
+#ifndef __HOOK_SCRIPTOBJECT_H
+#define __HOOK_SCRIPTOBJECT_H
+
+#include <api/script/objects/c_script/scripthook.h>
+
+class H_RootObject : public ScriptHookI {
+
+ public:
+
+ H_RootObject(ScriptObject *o);
+ H_RootObject();
+ virtual ~H_RootObject();
+
+ virtual void H_hook(ScriptObject *o);
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+
+ virtual void hook_onNotify(const wchar_t *s, const wchar_t *t, int u, int v) {}
+
+ virtual ScriptObject *getHookedObject() { return me; }
+
+ private:
+
+ ScriptObject *me;
+ static int onnotify_id;
+ static int inited;
+ static int count;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/c_script/h_slider.cpp b/Src/Wasabi/api/script/objects/c_script/h_slider.cpp
new file mode 100644
index 00000000..bca6dc96
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_slider.cpp
@@ -0,0 +1,62 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_slider.h"
+
+H_Slider::H_Slider(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Slider::H_Slider() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Slider::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, sliderGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &sliderGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ onsetposition_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSetPosition", this);
+ onpostedposition_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onPostedPosition", this);
+ onsetfinalposition_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSetFinalPosition", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Slider::~H_Slider() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Slider::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_SLIDER_PARENT::getHookedObject();
+}
+
+int H_Slider::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_SLIDER_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == onsetposition_id) { hook_onSetPosition(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onpostedposition_id) { hook_onPostedPosition(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onsetfinalposition_id) { hook_onSetFinalPosition(GET_SCRIPT_INT(*params[0])); return 1; }
+ return 0;
+}
+
+int H_Slider::onsetposition_id=0;
+int H_Slider::onpostedposition_id=0;
+int H_Slider::onsetfinalposition_id=0;
+int H_Slider::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_slider.h b/Src/Wasabi/api/script/objects/c_script/h_slider.h
new file mode 100644
index 00000000..c7539746
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_slider.h
@@ -0,0 +1,35 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_SLIDER_H
+#define __HOOK_SLIDER_H
+
+#include "h_guiobject.h"
+
+#define H_SLIDER_PARENT H_GuiObject
+
+class H_Slider : public H_SLIDER_PARENT {
+
+public:
+
+ H_Slider(ScriptObject *o);
+ H_Slider();
+ virtual ~H_Slider();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onSetPosition(int newpos) { }
+ virtual void hook_onPostedPosition(int newpos) { }
+ virtual void hook_onSetFinalPosition(int pos) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int onsetposition_id;
+ static int onpostedposition_id;
+ static int onsetfinalposition_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_tabsheet.cpp b/Src/Wasabi/api/script/objects/c_script/h_tabsheet.cpp
new file mode 100644
index 00000000..7c66f043
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_tabsheet.cpp
@@ -0,0 +1,53 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+#include <api/api.h>
+#include <api/script/objcontroller.h>
+#include "h_tabsheet.h"
+
+H_TabSheet::H_TabSheet(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_TabSheet::H_TabSheet() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_TabSheet::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, tabSheetGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &tabSheetGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_TabSheet::~H_TabSheet() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_TabSheet::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_TABSHEET_PARENT::getHookedObject();
+}
+
+int H_TabSheet::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_TABSHEET_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ return 0;
+}
+
+int H_TabSheet::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_tabsheet.h b/Src/Wasabi/api/script/objects/c_script/h_tabsheet.h
new file mode 100644
index 00000000..d68714d5
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_tabsheet.h
@@ -0,0 +1,29 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_TABSHEET_H
+#define __HOOK_TABSHEET_H
+
+#include "h_guiobject.h"
+
+#define H_TABSHEET_PARENT H_GuiObject
+
+class H_TabSheet : public H_TABSHEET_PARENT {
+
+public:
+
+ H_TabSheet(ScriptObject *o);
+ H_TabSheet();
+ virtual ~H_TabSheet();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_text.cpp b/Src/Wasabi/api/script/objects/c_script/h_text.cpp
new file mode 100644
index 00000000..37afc9bf
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_text.cpp
@@ -0,0 +1,56 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_text.h"
+
+H_Text::H_Text(ScriptObject *o) : H_GuiObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_Text::H_Text() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_Text::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, textGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &textGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ ontextchanged_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onTextChanged", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_Text::~H_Text() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_Text::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_TEXT_PARENT::getHookedObject();
+}
+
+int H_Text::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_TEXT_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == ontextchanged_id) { hook_onTextChanged(GET_SCRIPT_STRING(*params[0])); return 1; }
+ return 0;
+}
+
+int H_Text::ontextchanged_id=0;
+int H_Text::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_text.h b/Src/Wasabi/api/script/objects/c_script/h_text.h
new file mode 100644
index 00000000..f91285eb
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_text.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_TEXT_H
+#define __HOOK_TEXT_H
+
+#include "h_guiobject.h"
+
+#define H_TEXT_PARENT H_GuiObject
+
+class H_Text : public H_TEXT_PARENT {
+
+public:
+
+ H_Text(ScriptObject *o);
+ H_Text();
+ virtual ~H_Text();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onTextChanged(const wchar_t *newtxt) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ontextchanged_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_togglebutton.cpp b/Src/Wasabi/api/script/objects/c_script/h_togglebutton.cpp
new file mode 100644
index 00000000..a3e64678
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_togglebutton.cpp
@@ -0,0 +1,56 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_togglebutton.h"
+
+H_ToggleButton::H_ToggleButton(ScriptObject *o) : H_Button(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_ToggleButton::H_ToggleButton() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_ToggleButton::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, toggleButtonGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &toggleButtonGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ ontoggle_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onToggle", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_ToggleButton::~H_ToggleButton() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_ToggleButton::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_TOGGLEBUTTON_PARENT::getHookedObject();
+}
+
+int H_ToggleButton::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_TOGGLEBUTTON_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == ontoggle_id) { hook_onToggle(GET_SCRIPT_INT(*params[0])); return 1; }
+ return 0;
+}
+
+int H_ToggleButton::ontoggle_id=0;
+int H_ToggleButton::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_togglebutton.h b/Src/Wasabi/api/script/objects/c_script/h_togglebutton.h
new file mode 100644
index 00000000..ce76fa35
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_togglebutton.h
@@ -0,0 +1,31 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_TOGGLEBUTTON_H
+#define __HOOK_TOGGLEBUTTON_H
+
+#include "h_button.h"
+
+#define H_TOGGLEBUTTON_PARENT H_Button
+
+class H_ToggleButton : public H_TOGGLEBUTTON_PARENT {
+
+public:
+
+ H_ToggleButton(ScriptObject *o);
+ H_ToggleButton();
+ virtual ~H_ToggleButton();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onToggle(int (null)) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ontoggle_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/h_treeitem.cpp b/Src/Wasabi/api/script/objects/c_script/h_treeitem.cpp
new file mode 100644
index 00000000..1191d0bf
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_treeitem.cpp
@@ -0,0 +1,89 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#include <precomp.h>
+
+#include <api/script/objcontroller.h>
+#include "h_treeitem.h"
+
+H_TreeItem::H_TreeItem(ScriptObject *o) : H_RootObject(o) {
+ inited = 0;
+ obj = NULL;
+ H_hook(o);
+}
+
+H_TreeItem::H_TreeItem() {
+ inited = 0;
+ obj = NULL;
+}
+
+void H_TreeItem::H_hook(ScriptObject *o) {
+ ASSERT(!inited);
+ ScriptObjectController *controller = o->vcpu_getController();
+ obj = controller->cast(o, treeItemGuid);
+ if (obj != o && obj != NULL)
+ o = obj;
+ else
+ obj = NULL;
+
+ addMonitorObject(o, &treeItemGuid);
+
+ int iter = WASABI_API_APP->app_getInitCount();
+ if (!loaded || loaded != iter) {
+ ontreeadd_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onTreeAdd", this);
+ ontreeremove_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onTreeRemove", this);
+ onselect_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onSelect", this);
+ ondeselect_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onDeselect", this);
+ onleftdoubleclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onLeftDoubleClick", this);
+ onrightdoubleclick_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onRightDoubleClick", this);
+ onchar_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onChar", this);
+ onexpand_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onExpand", this);
+ oncollapse_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onCollapse", this);
+ onbeginlabeledit_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onBeginLabelEdit", this);
+ onendlabeledit_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onEndLabelEdit", this);
+ oncontextmenu_id= WASABI_API_MAKI->maki_addDlfRef(o->vcpu_getController(), L"onContextMenu", this);
+ loaded = 1;
+ }
+ inited=1;
+}
+
+H_TreeItem::~H_TreeItem() {
+ if (!inited) return;
+ WASABI_API_MAKI->maki_remDlfRef(this);
+}
+
+ScriptObject *H_TreeItem::getHookedObject() {
+ if (obj != NULL) return obj;
+ return H_TREEITEM_PARENT::getHookedObject();
+}
+
+int H_TreeItem::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ if (object != getHookedObject()) return 0;
+ if (H_TREEITEM_PARENT::eventCallback(object, dlfid, params, nparams)) return 1;
+ if (dlfid == ontreeadd_id) { hook_onTreeAdd(); return 1; }
+ if (dlfid == ontreeremove_id) { hook_onTreeRemove(); return 1; }
+ if (dlfid == onselect_id) { hook_onSelect(); return 1; }
+ if (dlfid == ondeselect_id) { hook_onDeselect(); return 1; }
+ if (dlfid == onleftdoubleclick_id) { hook_onLeftDoubleClick(); return 1; }
+ if (dlfid == onrightdoubleclick_id) { hook_onRightDoubleClick(); return 1; }
+ if (dlfid == onchar_id) { hook_onChar(GET_SCRIPT_INT(*params[0])); return 1; }
+ if (dlfid == onexpand_id) { hook_onExpand(); return 1; }
+ if (dlfid == oncollapse_id) { hook_onCollapse(); return 1; }
+ if (dlfid == onbeginlabeledit_id) { hook_onBeginLabelEdit(); return 1; }
+ if (dlfid == onendlabeledit_id) { hook_onEndLabelEdit(GET_SCRIPT_STRING(*params[0])); return 1; }
+ if (dlfid == oncontextmenu_id) { hook_onContextMenu(GET_SCRIPT_INT(*params[0]), GET_SCRIPT_INT(*params[1])); return 1; }
+ return 0;
+}
+
+int H_TreeItem::ontreeadd_id=0;
+int H_TreeItem::ontreeremove_id=0;
+int H_TreeItem::onselect_id=0;
+int H_TreeItem::ondeselect_id=0;
+int H_TreeItem::onleftdoubleclick_id=0;
+int H_TreeItem::onrightdoubleclick_id=0;
+int H_TreeItem::onchar_id=0;
+int H_TreeItem::onexpand_id=0;
+int H_TreeItem::oncollapse_id=0;
+int H_TreeItem::onbeginlabeledit_id=0;
+int H_TreeItem::onendlabeledit_id=0;
+int H_TreeItem::oncontextmenu_id=0;
+int H_TreeItem::loaded=0;
diff --git a/Src/Wasabi/api/script/objects/c_script/h_treeitem.h b/Src/Wasabi/api/script/objects/c_script/h_treeitem.h
new file mode 100644
index 00000000..173ce1a0
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/h_treeitem.h
@@ -0,0 +1,53 @@
+/* This file was generated by Maki Compiler, do not edit manually */
+
+#ifndef __HOOK_TREEITEM_H
+#define __HOOK_TREEITEM_H
+
+#include "h_rootobj.h"
+
+#define H_TREEITEM_PARENT H_RootObject
+
+class H_TreeItem : public H_TREEITEM_PARENT {
+
+public:
+
+ H_TreeItem(ScriptObject *o);
+ H_TreeItem();
+ virtual ~H_TreeItem();
+ virtual void H_hook(ScriptObject *o);
+ ScriptObject *getHookedObject();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+ virtual void hook_onTreeAdd() { }
+ virtual void hook_onTreeRemove() { }
+ virtual void hook_onSelect() { }
+ virtual void hook_onDeselect() { }
+ virtual void hook_onLeftDoubleClick() { }
+ virtual void hook_onRightDoubleClick() { }
+ virtual void hook_onChar(wchar_t key) { }
+ virtual void hook_onExpand() { }
+ virtual void hook_onCollapse() { }
+ virtual void hook_onBeginLabelEdit() { }
+ virtual void hook_onEndLabelEdit(const wchar_t *newlabel) { }
+ virtual void hook_onContextMenu(int x, int y) { }
+
+ private:
+
+ ScriptObject *obj;
+ int inited;
+ static int loaded;
+ static int ontreeadd_id;
+ static int ontreeremove_id;
+ static int onselect_id;
+ static int ondeselect_id;
+ static int onleftdoubleclick_id;
+ static int onrightdoubleclick_id;
+ static int onchar_id;
+ static int onexpand_id;
+ static int oncollapse_id;
+ static int onbeginlabeledit_id;
+ static int onendlabeledit_id;
+ static int oncontextmenu_id;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/c_script/scripthook.cpp b/Src/Wasabi/api/script/objects/c_script/scripthook.cpp
new file mode 100644
index 00000000..a57ced19
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/scripthook.cpp
@@ -0,0 +1,47 @@
+#include <precomp.h>
+
+#include <api/script/scriptobj.h>
+#include <api/script/objcontroller.h>
+#include "scripthook.h"
+
+#define CBCLASS ScriptHookI
+START_DISPATCH;
+ CB(EVENTCALLBACK, eventCallback);
+END_DISPATCH;
+
+ScriptHookI::ScriptHookI() {
+}
+
+ScriptHookI::~ScriptHookI() {
+ WASABI_API_MAKI->maki_remDlfRef(this);
+ foreach(controllers)
+ controllers.getfor()->removeHooks(this);
+ endfor
+
+}
+
+
+void ScriptHookI::addMonitorObject(ScriptObject *o, const GUID *hookedclass) {
+ WASABI_API_MAKI->maki_addDlfClassRef(o->vcpu_getController(), this);
+ ScriptObjectController *cont = o->vcpu_getController();
+ if (hookedclass == NULL) {
+ cont->addObjectHook(this, o);
+ } else {
+ while (cont) {
+ if (cont->getClassGuid() == *hookedclass) {
+ cont->addObjectHook(this, o);
+ break;
+ }
+ cont = cont->getAncestorController();
+ }
+ }
+ if (cont == NULL) // guid not found
+ return;
+ controllers.addItem(cont);
+}
+
+void ScriptHookI::addMonitorClass(ScriptObject *o) {
+ WASABI_API_MAKI->maki_addDlfClassRef(o->vcpu_getController(), this);
+ o->vcpu_getController()->addClassHook(this);
+ controllers.addItem(o->vcpu_getController());
+}
diff --git a/Src/Wasabi/api/script/objects/c_script/scripthook.h b/Src/Wasabi/api/script/objects/c_script/scripthook.h
new file mode 100644
index 00000000..f529ee6f
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/c_script/scripthook.h
@@ -0,0 +1,49 @@
+#ifndef __SCRIPTHOOK_H
+#define __SCRIPTHOOK_H
+
+#include <api/script/vcputypes.h>
+#include <bfc/dispatch.h>
+#include <bfc/ptrlist.h>
+
+
+class ScriptObject;
+class ScriptObjectController;
+
+// ----------------------------------------------------------------------------------------------------------
+
+class ScriptHook : public Dispatchable {
+ protected:
+ ScriptHook() {};
+
+ public:
+ int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams);
+
+ enum {
+ EVENTCALLBACK = 100,
+ };
+
+};
+
+inline int ScriptHook::eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams) {
+ return _call(EVENTCALLBACK, 0, object, dlfid, params, nparams);
+}
+
+class ScriptHookI : public ScriptHook {
+
+public:
+
+ ScriptHookI();
+ virtual ~ScriptHookI();
+
+ virtual int eventCallback(ScriptObject *object, int dlfid, scriptVar **params, int nparams)=0;
+
+ void addMonitorObject(ScriptObject *o, const GUID *hookedclass=NULL); // NULL = all classes of object o
+ void addMonitorClass(ScriptObject *o);
+
+protected:
+ RECVS_DISPATCH;
+
+ PtrList<ScriptObjectController> controllers;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/compoobj.cpp b/Src/Wasabi/api/script/objects/compoobj.cpp
new file mode 100644
index 00000000..7b7ba8bb
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/compoobj.cpp
@@ -0,0 +1,361 @@
+#include "precomp.h"
+#ifndef _NOSTUDIO
+
+#include "../../common/std.h"
+#include "script.h"
+#include "scriptmgr.h"
+#include "../../common/script/scriptobj.h"
+#include "compoobj.h"
+#include "../api.h"
+#include "vcpu.h"
+#include "../smap.h"
+#include "sregion.h"
+#include "../skinparse.h"
+#include "../compon.h"
+#include "../compwnd.h"
+#include "../cbmgr.h"
+#include "../smap.h"
+#include "../../common/wndcb.h"
+
+#else
+#include "compoobj.h"
+#endif
+
+CompoObjScriptController _compoController;
+CompoObjScriptController *compoController=&_compoController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct CompoObjScriptController::exportedFunction[] = {
+ {"getGUID", 1, (void*)ComponentObject::script_vcpu_getGUID },
+ {"getWac", 0, (void*)ComponentObject::script_vcpu_getWac },
+ {"setRegionFromMap", 3, (void*)ComponentObject::script_vcpu_setRegionFromMap },
+ {"setRegion", 1, (void*)ComponentObject::script_vcpu_setRegion },
+ {"onGetWac", 1, (void*)ComponentObject::script_vcpu_onGetWac },
+ {"onGiveUpWac", 1, (void*)ComponentObject::script_vcpu_onGiveUpWac },
+ {"setAcceptWac", 1, (void*)ComponentObject::script_vcpu_setAcceptWac },
+};
+// --------------------------------------------------------
+
+const char *CompoObjScriptController::getClassName() {
+ return "Component";
+}
+
+const wchar_t *CompoObjScriptController::getAncestorClassName() {
+ return "GuiObject";
+}
+
+int CompoObjScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *CompoObjScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID CompoObjScriptController::getClassGuid() {
+ return componentObjectGuid;
+}
+
+ScriptObject *CompoObjScriptController::instantiate() {
+ ComponentObject *obj = new ComponentObject();
+ return obj->getScriptObject();
+}
+
+void CompoObjScriptController::destroy(ScriptObject *o) {
+ ComponentObject *obj = static_cast<ComponentObject *>(o->vcpu_getInterface(componentObjectGuid));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *CompoObjScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for componentobject yet
+}
+
+void CompoObjScriptController::deencapsulate(void *) {
+}
+
+
+ComponentObject::ComponentObject() {
+ getScriptObject()->vcpu_setInterface(componentObjectGuid, (void *)static_cast<ComponentObject *>(this));
+ getScriptObject()->vcpu_setClassName("Component");
+ getScriptObject()->vcpu_setController(compoController);
+ deleting = 0;
+ compwnd = NULL;
+ noshowcmdbar = 0;
+ noshowbtnbar = 0;
+ MEMCPY(&myGUID, &INVALID_GUID, sizeof(GUID));
+ MEMCPY(&myCompGuid, &INVALID_GUID, sizeof(GUID));
+ my_region_clone = NULL;
+ ComponentManager::registerComponentObject(this);
+ autoopen = 0;
+ autoclose = 0;
+ accept = 1;
+ denyDesktopAlpha = 0;
+ denyTransparency = 0;
+ noanimrects = 0;
+}
+
+int ComponentObject::setXmlParam(const char *name, const char *value) {
+ if (COMPONENTOBJECT_PARENT::setXmlParam(name, value)) return 1;
+ else if (STRCASEEQL(name, "param")) {
+ GUID *g;
+ g = SkinParser::getComponentGuid(value);
+ if (g)
+ setGUID(*g);
+ } else if (STRCASEEQL(name, "noshowcmdbar")) {
+ noshowcmdbar = WTOI(value);
+ } else if (STRCASEEQL(name, "autoopen")) {
+ autoopen = WTOI(value);
+ } else if (STRCASEEQL(name, "autoclose")) {
+ autoclose = WTOI(value);
+ } else if (STRCASEEQL(name, "disableanimatedrects")) {
+ noanimrects = WTOI(value);
+ } else return 0;
+ return 1;
+}
+
+ComponentObject::~ComponentObject() {
+ deleting = 1;
+ ComponentManager::unregisterComponentObject(this, 1);
+ delete my_region_clone;
+}
+
+int ComponentObject::onResize() {
+ COMPONENTOBJECT_PARENT::onResize();
+ RECT r = clientRect();
+ if (compwnd) {
+ compwnd->resize(&r);
+ }
+ return 1;
+}
+
+int ComponentObject::handleRatio() {
+ return compwnd ? compwnd->handleRatio() : 0;
+}
+
+void ComponentObject::setGUID(GUID g) {
+ myGUID = g;
+}
+
+void ComponentObject::setCompGUID(GUID g) {
+ myCompGuid = g;
+}
+
+GUID ComponentObject::getGUID(void) {
+ if (!MEMCMP(&myCompGuid, &INVALID_GUID, sizeof(GUID)))
+ return myGUID;
+ else
+ return myCompGuid;
+}
+
+void ComponentObject::script_resetRegion() {
+ HWND h = ComponentManager::getComponentHWnd(myGUID);
+ if (h) SetWindowRgn(h, NULL, TRUE);
+ delete my_region_clone;
+ my_region_clone = NULL;
+}
+
+void ComponentObject::script_setRegionFromMap(SMap *map, int byte, int inv) {
+ RECT r={map->getBitmap()->getX(), map->getBitmap()->getY(), map->getBitmap()->getWidth(), map->getBitmap()->getHeight()};
+ api_region *reg = new api_region(map->getBitmap(), &r, 0, 0, FALSE, 1, (unsigned char)byte, inv);
+ if (!reg) { script_resetRegion(); return; }
+ delete my_region_clone;
+ my_region_clone = new api_region();
+ my_region_clone->add(reg);
+ delete reg;
+ HWND h = ComponentManager::getComponentHWnd(myGUID);
+ if (h) {
+ api_region *clone = my_region_clone->clone();
+ clone->scale(getRenderRatio());
+ SetWindowRgn(h, clone->makeWindowRegion(), TRUE);
+ my_region_clone->disposeClone(clone);
+ }
+}
+
+void ComponentObject::script_setRegion(SRegion *r) {
+ api_region *reg = r->getRegion();
+ if (!reg) { script_resetRegion(); return; }
+ delete my_region_clone;
+ my_region_clone = new api_region();
+ my_region_clone->add(reg);
+ HWND h = ComponentManager::getComponentHWnd(myGUID);
+ if (h) {
+ api_region *clone = my_region_clone->clone();
+ clone->scale(getRenderRatio());
+ SetWindowRgn(h, clone->makeWindowRegion(), TRUE);
+ my_region_clone->disposeClone(clone);
+ }
+}
+
+void ComponentObject::onSetVisible(int s) {
+ COMPONENTOBJECT_PARENT::onSetVisible(s);
+ if (compwnd) {
+ compwnd->setVisible(s);
+ onResize();
+ } else {
+ if (s && autoopen && myGUID != INVALID_GUID && myGUID != GENERIC_GUID)
+ api->setComponentVisible(myGUID, 1);
+ }
+}
+
+void ComponentObject::deniedComponentCompWnd(CompWnd *c, GUID g) {
+ if (!deleting) {
+ Container *_c = getGuiObject()->guiobject_getParentGroup()->getParentContainer();
+ if (_c) _c->resetGUID();
+ }
+ compwnd = c;
+ compwnd->suppressStatusBar(noshowcmdbar);
+
+ CallbackManager::issueCallback(SysCallback::WINDOW, WndCallback::HIDEWINDOW, reinterpret_cast<int>((int *)&g));
+
+ onReleaseComponent();
+ compwnd = NULL;
+ denyDesktopAlpha = 0;
+ denyTransparency = 0;
+ if (!deleting) getGuiObject()->guiobject_getParentLayout()->onGuiObjectSetVisible(getGuiObject(), 0);
+}
+
+void ComponentObject::grantedComponentCompWnd(CompWnd *c, GUID g) {
+ Container *_c = getGuiObject()->guiobject_getParentGroup()->getParentContainer();
+ if (_c) _c->setGUID(g); // tells the container to change its script_id to id:{guid}
+ compwnd = c;
+ compwnd->suppressStatusBar(noshowcmdbar);
+
+ onResize();
+
+ if (isVisible())
+ c->setVisible(1);
+
+ CallbackManager::issueCallback(SysCallback::WINDOW, WndCallback::SHOWWINDOW, reinterpret_cast<int>((int *)&g));
+
+ onGetComponent(g);
+}
+
+void ComponentObject::onReleaseComponent() {
+ HWND h = ComponentManager::getComponentHWnd(myGUID);
+ SetWindowRgn(h, NULL, FALSE);
+}
+
+void ComponentObject::onGetComponent(GUID g) {
+ HWND h = ComponentManager::getComponentHWnd(myGUID);
+ if (h) {
+ if (my_region_clone) {
+ api_region *clone = my_region_clone->clone();
+ clone->scale(getRenderRatio());
+ SetWindowRgn(h, clone->makeWindowRegion(), TRUE);
+ my_region_clone->disposeClone(clone);
+ } else
+ SetWindowRgn(h, NULL, FALSE);
+ }
+}
+
+int ComponentObject::wantGUID(GUID *g) {
+ if (!accept || !getGuiObject()->guiobject_getParentGroup()) return 0;
+ Container *_c = getGuiObject()->guiobject_getParentGroup()->getParentContainer();
+ if (_c && _c->isDynamic() && compwnd) return 0;
+ if (!MEMCMP(&myGUID, &GENERIC_GUID, sizeof(GUID))) return 1;
+ return !MEMCMP(&myGUID, g, sizeof(GUID));
+}
+
+void ComponentObject::onBeforeGetWac(GUID g, CompWnd *c) {
+// if (!Std::isXPOrGreater())
+ if (!c->handleDesktopAlpha())
+ denyDesktopAlpha = 1;
+ if (!c->handleTransparency())
+ denyTransparency = 1;
+ getGuiObject()->guiobject_getParentLayout()->onGuiObjectSetVisible(getGuiObject(), 1);
+ WACObject *wo = SOM::getWACObject(g);
+ script_vcpu_onGetWac(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(wo ? wo->getScriptObject() : NULL));
+}
+
+void ComponentObject::onBeforeGiveUpWac(GUID g, CompWnd *c) {
+ WACObject *wo = SOM::getWACObject(g);
+ script_vcpu_onGiveUpWac(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(wo ? wo->getScriptObject() : NULL));
+}
+
+int ComponentObject::getAutoClose() {
+ return autoclose;
+}
+
+void ComponentObject::setAcceptWac(int a) {
+ accept = a;
+}
+
+int ComponentObject::handleDesktopAlpha() {
+ if (denyDesktopAlpha) return 0;
+ if (!compwnd) return 1;
+ return 0;
+}
+
+int ComponentObject::handleTransparency() {
+ if (denyTransparency) return 0;
+ if (!compwnd) return 1;
+ return compwnd->handleTransparency();
+}
+
+int ComponentObject::getPreferences(int what) {
+ if (compwnd) return compwnd->getPreferences(what);
+ return COMPONENTOBJECT_PARENT::getPreferences(what);
+}
+
+scriptVar ComponentObject::script_vcpu_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+
+ OLECHAR oguid[256] = {0}; // NONPORTABLE
+ ComponentObject *co = static_cast<ComponentObject *>(o->vcpu_getInterface(componentObjectGuid));
+ if (co) {
+ static char guid[256];
+ StringFromGUID2(((ComponentObject *)o)->myGUID, oguid, 256);
+ wsprintf(guid, "%$", oguid);
+ return MAKE_SCRIPT_STRING(guid);
+ }
+ return MAKE_SCRIPT_STRING("");
+}
+
+scriptVar ComponentObject::script_vcpu_getWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT; ;
+ ComponentObject *co = static_cast<ComponentObject *>(o->vcpu_getInterface(componentObjectGuid));
+ return MAKE_SCRIPT_OBJECT(co ? SOM::getWACObject(co->getGUID())->getScriptObject() : NULL);
+}
+
+scriptVar ComponentObject::script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv) {
+ SCRIPT_FUNCTION_INIT; ;
+ ASSERT(SOM::isNumeric(&byte));
+ ASSERT(SOM::isNumeric(&inv));
+ ComponentObject *co = static_cast<ComponentObject *>(o->vcpu_getInterface(componentObjectGuid));
+ SMap *sm = static_cast<SMap *>(GET_SCRIPT_OBJECT_AS(map, mapGuid));
+ co->script_setRegionFromMap(sm, SOM::makeInt(&byte), SOM::makeBoolean(&inv));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ComponentObject::script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r) {
+ SCRIPT_FUNCTION_INIT; ;
+ ComponentObject *co = static_cast<ComponentObject *>(o->vcpu_getInterface(componentObjectGuid));
+ SRegion *reg = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(r, regionGuid));
+ if (co) co->script_setRegion(reg);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ComponentObject::script_vcpu_onGetWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar wac) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, compoController, wac);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, wac);
+}
+
+scriptVar ComponentObject::script_vcpu_onGiveUpWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar wac) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, compoController, wac);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, wac);
+}
+
+scriptVar ComponentObject::script_vcpu_setAcceptWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar on) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&on));
+ ComponentObject *co = static_cast<ComponentObject *>(o->vcpu_getInterface(componentObjectGuid));
+ if (co) co->setAcceptWac(GET_SCRIPT_BOOLEAN(on));
+ RETURN_SCRIPT_VOID;
+}
+
+
diff --git a/Src/Wasabi/api/script/objects/compoobj.h b/Src/Wasabi/api/script/objects/compoobj.h
new file mode 100644
index 00000000..6e18f84b
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/compoobj.h
@@ -0,0 +1,119 @@
+#ifndef _COMPONENTOBJ_H
+#define _COMPONENTOBJ_H
+
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objects/guiobj.h>
+
+class SMap;
+class SRegion;
+class Container;
+class Layout;
+class CompWnd;
+
+// {403ABCC0-6F22-4bd6-8BA4-10C829932547}
+static const GUID componentObjectGuid =
+{ 0x403abcc0, 0x6f22, 0x4bd6, { 0x8b, 0xa4, 0x10, 0xc8, 0x29, 0x93, 0x25, 0x47 } };
+
+#define COMPONENTOBJECT_PARENT GuiObjectWnd
+
+class CompoObjScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern CompoObjScriptController *compoController;
+
+
+#ifndef _NOSTUDIO
+
+#include <api/wnd/virtualwnd.h>
+
+class ComponentObject : public COMPONENTOBJECT_PARENT {
+public:
+ ComponentObject();
+ virtual ~ComponentObject();
+
+ virtual int setXmlParam(const wchar_t *name, const wchar_t *value);
+
+ virtual int onResize();
+ virtual void onSetVisible(int s);
+ virtual int handleRatio();
+
+ void deniedComponentCompWnd(CompWnd *c, GUID g);
+ void grantedComponentCompWnd(CompWnd *c, GUID g);
+ int wantGUID(GUID *g);
+
+ void onReleaseComponent();
+ void onGetComponent(GUID g);
+
+ void onBeforeGetWac(GUID g, CompWnd *c);
+ void onBeforeGiveUpWac(GUID g, CompWnd *c);
+
+ void setGUID(GUID g);
+ void setCompGUID(GUID g);
+ GUID getGUID(void);
+ int getAutoClose();
+ void setAcceptWac(int a);
+ int getAnimatedRects() { return !noanimrects; }
+ virtual int getPreferences(int what);
+
+ virtual void script_resetRegion();
+ virtual void script_setRegionFromMap(SMap *map, int byte, int inv);
+ virtual void script_setRegion(SRegion *r);
+ virtual int handleDesktopAlpha();
+ virtual int handleTransparency();
+
+ // VCPU
+ static scriptVar script_vcpu_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onShow(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onHide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onGetWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar wac);
+ static scriptVar script_vcpu_onGiveUpWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar wac);
+ static scriptVar script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv);
+ static scriptVar script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar script_vcpu_setAcceptWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar on);
+ // End VCPU
+
+private:
+ GUID myGUID;
+ GUID myCompGuid;
+
+ int deleting;
+
+ CompWnd *compwnd;
+ int noshowcmdbar;
+ int noshowbtnbar;
+
+ api_region *my_region_clone;
+ int autoopen, autoclose;
+ int accept;
+ int denyDesktopAlpha;
+ int denyTransparency;
+ int noanimrects;
+
+#else
+class ComponentObject : public COMPONENTOBJECT_SCRIPTPARENT {
+#endif
+
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/core/coreadminobj.cpp b/Src/Wasabi/api/script/objects/core/coreadminobj.cpp
new file mode 100644
index 00000000..505fa2e8
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/core/coreadminobj.cpp
@@ -0,0 +1,184 @@
+#include <precomp.h>
+
+#include <api/service/svcs/svc_coreadmin.h>
+#include <api/script/objects/core/coreadminobj.h>
+#include <api/script/objects/core/coreobj.h>
+
+static CoreAdminScriptObjectController _coreAdminController;
+ScriptObjectController *coreAdminController = &_coreAdminController;
+
+// Table of exported functions and events
+// "function name", n. params, function_pointer
+function_descriptor_struct CoreAdminScriptObjectController::exportedFunction[] = {
+ {L"getNamedCore", 1, (void*)coreadmin_getNamedCore},
+ {L"newNamedCore", 1, (void*)coreadmin_newNamedCore},
+ {L"freeCore", 1, (void*)coreadmin_freeCore},
+ {L"freeCoreByName", 1, (void*)coreadmin_freeCoreByName},
+};
+
+int CoreAdminScriptObjectController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+ScriptObject *CoreAdminScriptObjectController::instantiate() {
+ ScriptCoreAdminObject *scao = new ScriptCoreAdminObject;
+ ASSERT(scao != NULL);
+ return scao->getScriptObject();
+}
+
+void CoreAdminScriptObjectController::destroy(ScriptObject *o) {
+ ScriptCoreAdminObject *scao = static_cast<ScriptCoreAdminObject *>(o->vcpu_getInterface(COREADMIN_SCRIPTOBJECT_GUID));
+ ASSERT(scao != NULL);
+ delete scao;
+}
+
+void *CoreAdminScriptObjectController::encapsulate(ScriptObject *o) {
+ return NULL;
+}
+
+void CoreAdminScriptObjectController::deencapsulate(void *o) {
+}
+
+scriptVar CoreAdminScriptObjectController::coreadmin_getNamedCore(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreAdminObject *scao = static_cast<ScriptCoreAdminObject *>(o->vcpu_getInterface(COREADMIN_SCRIPTOBJECT_GUID));
+ if (scao) {
+ const wchar_t *cname = GET_SCRIPT_STRING(name);
+ if (cname) {
+#ifndef FAKE_SCRIPTCORE
+ // Get the token for the requested core.
+ CoreToken core = scao->getNamedCore(cname);
+ if (core == -1) {
+ RETURN_SCRIPT_VOID;
+ }
+#endif
+ // Make a new Core scriptobj to point to the requested core.
+ CoreScriptObjectController *controller = static_cast<CoreScriptObjectController *>(coreController);
+#ifndef FAKE_SCRIPTCORE
+ ScriptObject *coreobj = controller->instantiate(core);
+#else
+ ScriptObject *coreobj = controller->instantiate(NULL);
+#endif
+ return MAKE_SCRIPT_OBJECT(coreobj);
+ }
+ }
+ RETURN_SCRIPT_NULL;
+}
+
+scriptVar CoreAdminScriptObjectController::coreadmin_newNamedCore(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreAdminObject *scao = static_cast<ScriptCoreAdminObject *>(o->vcpu_getInterface(COREADMIN_SCRIPTOBJECT_GUID));
+ if (scao) {
+ const wchar_t *cname = GET_SCRIPT_STRING(name);
+ if (cname) {
+ // Get the token for the created core.
+ /*CoreToken core = */scao->newNamedCore(cname);
+ // Make a new Core scriptobj to point to the created core.
+ CoreScriptObjectController *controller = static_cast<CoreScriptObjectController *>(coreController);
+#ifndef FAKE_SCRIPTCORE
+ ScriptObject *coreobj = controller->instantiate(core);
+ // Then get the object back and bind a sequencer and stuff to it. Like we just said "new Core"
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(coreobj->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ sco->initAsCreated();
+ }
+#else
+ ScriptObject *coreobj = controller->instantiate(NULL);
+#endif
+ return MAKE_SCRIPT_OBJECT(coreobj);
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar CoreAdminScriptObjectController::coreadmin_freeCore(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar core) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreAdminObject *scao = static_cast<ScriptCoreAdminObject *>(o->vcpu_getInterface(COREADMIN_SCRIPTOBJECT_GUID));
+ if (scao) {
+ // Pull the ScriptCoreObject from the scriptVar
+ ScriptObject *coreobj = GET_SCRIPT_OBJECT(core);
+ if (coreobj) {
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(coreobj->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+#ifndef FAKE_SCRIPTCORE
+ scao->freeCore(sco->core_handle);
+#endif
+ return MAKE_SCRIPT_INT(1);
+ }
+ }
+ }
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar CoreAdminScriptObjectController::coreadmin_freeCoreByName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreAdminObject *scao = static_cast<ScriptCoreAdminObject *>(o->vcpu_getInterface(COREADMIN_SCRIPTOBJECT_GUID));
+ if (scao) {
+ const wchar_t *cname = GET_SCRIPT_STRING(name);
+ if (cname) {
+ // Try to remove it.
+ int retval = scao->freeCoreByName(cname);
+ return MAKE_SCRIPT_INT(retval);
+ }
+ }
+ return MAKE_SCRIPT_INT(0);
+}
+
+
+// -----------------------------------------------------------------------------------------------------
+
+ScriptCoreAdminObject::ScriptCoreAdminObject() {
+ getScriptObject()->vcpu_setClassName(L"CoreAdmin");
+ getScriptObject()->vcpu_setController(coreAdminController);
+ getScriptObject()->vcpu_setInterface(COREADMIN_SCRIPTOBJECT_GUID, static_cast<ScriptCoreAdminObject *>(this));
+
+#ifndef FAKE_SCRIPTCORE
+ waServiceFactory *s = api->service_enumService(WaSvc::COREADMIN,0);
+ ASSERTPR(s,"Core Admin must be present to use ScriptCore!");
+ admin = castService<svc_coreAdmin>(s);
+#endif
+}
+
+ScriptCoreAdminObject::~ScriptCoreAdminObject() {
+#ifndef FAKE_SCRIPTCORE
+ api->service_release(admin);
+ admin = NULL;
+#endif
+}
+
+CoreToken ScriptCoreAdminObject::getNamedCore(const wchar_t *name) {
+#ifndef FAKE_SCRIPTCORE
+ return admin->nameToToken(name);
+#else
+ return 0;
+#endif
+}
+
+CoreToken ScriptCoreAdminObject::newNamedCore(const wchar_t *name) {
+#ifndef FAKE_SCRIPTCORE
+ return admin->createCore(name);
+#else
+ return 0;
+#endif
+}
+
+int ScriptCoreAdminObject::freeCore(CoreToken core) {
+#ifndef FAKE_SCRIPTCORE
+ if (core == 0) return 0; // don't touch the main core.
+ return admin->freeCoreByToken(core);
+#else
+ return 0;
+#endif
+}
+
+int ScriptCoreAdminObject::freeCoreByName(const wchar_t *name) {
+#ifndef FAKE_SCRIPTCORE
+ CoreToken core = admin->nameToToken(name);
+ if (core == 0) return 0; // don't touch the main core.
+ return admin->freeCoreByToken(core);
+#else
+ return 0;
+#endif
+}
+
diff --git a/Src/Wasabi/api/script/objects/core/coreadminobj.h b/Src/Wasabi/api/script/objects/core/coreadminobj.h
new file mode 100644
index 00000000..c0322edf
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/core/coreadminobj.h
@@ -0,0 +1,67 @@
+#ifndef __COREADMINOBJ_H
+#define __COREADMINOBJ_H
+
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/core/sequence.h>
+#include <api/syscb/callbacks/corecbi.h>
+
+#ifdef GEN_FF
+#ifndef FAKE_SCRIPTCORE
+#define FAKE_SCRIPTCORE
+#endif
+#endif
+
+class svc_coreAdmin;
+
+// {F857BECA-8E19-41f1-973E-097E39649F03}
+static const GUID COREADMIN_SCRIPTOBJECT_GUID =
+ { 0xf857beca, 0x8e19, 0x41f1, { 0x97, 0x3e, 0x9, 0x7e, 0x39, 0x64, 0x9f, 0x3 } };
+
+extern ScriptObjectController *coreAdminController;
+
+// -----------------------------------------------------------------------------------------------------
+class ScriptCoreAdminObject : public RootObjectInstance
+{
+public:
+ ScriptCoreAdminObject();
+ virtual ~ScriptCoreAdminObject();
+
+ CoreToken getNamedCore(const wchar_t *name);
+ CoreToken newNamedCore(const wchar_t *name);
+ int freeCore(CoreToken core);
+ int freeCoreByName(const wchar_t *name);
+
+private:
+#ifndef FAKE_SCRIPTCORE
+ svc_coreAdmin *admin;
+#endif
+};
+
+// -----------------------------------------------------------------------------------------------------
+class CoreAdminScriptObjectController : public ScriptObjectControllerI
+{
+public:
+ virtual const wchar_t *getClassName() { return L"CoreAdmin"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(rootObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return COREADMIN_SCRIPTOBJECT_GUID; }
+ virtual int getInstantiable() { return 0; }
+ virtual int getReferenceable() { return 0; }
+ virtual ScriptObject *instantiate();
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void destroy(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ static scriptVar coreadmin_getNamedCore(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar coreadmin_newNamedCore(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar coreadmin_freeCore(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar core);
+ static scriptVar coreadmin_freeCoreByName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+
+private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/core/coreobj.cpp b/Src/Wasabi/api/script/objects/core/coreobj.cpp
new file mode 100644
index 00000000..a3b47bc6
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/core/coreobj.cpp
@@ -0,0 +1,1151 @@
+#include <precomp.h>
+
+#include <api/script/objects/core/coreobj.h>
+#include <api/core/buttons.h>
+#include <api/service/svcs/svc_coreadmin.h>
+
+static CoreScriptObjectController _coreController;
+ScriptObjectController *coreController = &_coreController;
+
+#define TRICK_VOLUME 0
+
+// Table of exported functions and events
+// "function name", n. params, function_pointer
+function_descriptor_struct CoreScriptObjectController::exportedFunction[] = {
+ {L"playFile", 1, (void*)ScriptCoreObject::maki_playFile},
+ {L"stop", 0, (void*)ScriptCoreObject::maki_stop},
+ {L"setVolume", 1, (void*)ScriptCoreObject::maki_setVolume},
+// {L"onStop", 0, (void*)ScriptCoreObject::maki_onStop},
+ {L"getStatus", 0, (void*)ScriptCoreObject::maki_getStatus},
+// {L"getStuff", 0, (void*)ScriptCoreObject::maki_getStuff},
+
+ // Here come the new ones
+ {L"onStarted", 0, (void*)ScriptCoreObject::maki_onStarted}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onStopped", 0, (void*)ScriptCoreObject::maki_onStopped}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onPaused", 0, (void*)ScriptCoreObject::maki_onPaused}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onUnpaused", 0, (void*)ScriptCoreObject::maki_onUnpaused}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onSeeked", 1, (void*)ScriptCoreObject::maki_onSeeked}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newpos);
+ {L"onVolumeChange", 1, (void*)ScriptCoreObject::maki_onVolumeChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newvol);
+ {L"onPanChange", 1, (void*)ScriptCoreObject::maki_onPanChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newpan);
+ {L"onEQStatusChange", 1, (void*)ScriptCoreObject::maki_onEQStatusChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ {L"onEQPreampChange", 1, (void*)ScriptCoreObject::maki_onEQPreampChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ {L"onEQBandChange", 2, (void*)ScriptCoreObject::maki_onEQBandChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band, scriptVar /*int*/ newval);
+ {L"onEQFreqChange", 1, (void*)ScriptCoreObject::maki_onEQFreqChange},
+ {L"onEQAutoChange", 1, (void*)ScriptCoreObject::maki_onEQAutoChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ {L"onCoreStatusMsg", 1, (void*)ScriptCoreObject::maki_onStatusMsg}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ {L"onWarningMsg", 1, (void*)ScriptCoreObject::maki_onWarningMsg}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ {L"onErrorMsg", 1, (void*)ScriptCoreObject::maki_onErrorMsg}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ {L"onTitleChange", 1, (void*)ScriptCoreObject::maki_onTitleChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ title);
+ {L"onTitle2Change", 1, (void*)ScriptCoreObject::maki_onTitle2Change}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ title2);
+ {L"onInfoChange", 1, (void*)ScriptCoreObject::maki_onInfoChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ info);
+ {L"onUrlChange", 1, (void*)ScriptCoreObject::maki_onUrlChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ url);
+ {L"onLengthChange", 1, (void*)ScriptCoreObject::maki_onLengthChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newlength);
+ {L"onNextFile", 0, (void*)ScriptCoreObject::maki_onNextFile}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onNeedNextFile", 1, (void*)ScriptCoreObject::maki_onNeedNextFile}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ fileid);
+ {L"onSetNextFile", 1, (void*)ScriptCoreObject::maki_onSetNextFile}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstring);
+ {L"onErrorOccured", 2, (void*)ScriptCoreObject::maki_onErrorOccured}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ severity, scriptVar /*String*/ text);
+ {L"onAbortCurrentSong", 0, (void*)ScriptCoreObject::maki_onAbortCurrentSong}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onEndOfDecode", 0, (void*)ScriptCoreObject::maki_onEndOfDecode}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onFileComplete", 1, (void*)ScriptCoreObject::maki_onFileComplete}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstring);
+ {L"onConvertersChainRebuilt", 0, (void*)ScriptCoreObject::maki_onConvertersChainRebuilt}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ {L"onMediaFamilyChange", 1, (void*)ScriptCoreObject::maki_onMediaFamilyChange}, // (SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ newfamily);
+
+ {L"setNextFile", 1, (void*)ScriptCoreObject::maki_setNextFile}, // (scriptVar /*String*/ playstr);
+// {L"getStatus", 0, (void*)ScriptCoreObject::maki_getStatus}, // ();
+ {L"getCurrent", 0, (void*)ScriptCoreObject::maki_getCurrent}, // ();
+ {L"getCurPlaybackNumber", 0, (void*)ScriptCoreObject::maki_getCurPlaybackNumber}, // ();
+ {L"getNumTracks", 0, (void*)ScriptCoreObject::maki_getNumTracks}, // ();
+ {L"getPosition", 0, (void*)ScriptCoreObject::maki_getPosition}, // ();
+ {L"getWritePosition", 0, (void*)ScriptCoreObject::maki_getWritePosition}, // ();
+ {L"setPosition", 1, (void*)ScriptCoreObject::maki_setPosition}, // (scriptVar /*int*/ ms);
+ {L"getLength", 0, (void*)ScriptCoreObject::maki_getLength}, // ();
+ {L"getVolume", 0, (void*)ScriptCoreObject::maki_getVolume}, // ();
+// {L"setVolume", 1, (void*)ScriptCoreObject::maki_setVolume}, // (scriptVar /*int*/ vol);
+ {L"getPan", 0, (void*)ScriptCoreObject::maki_getPan}, // ();
+ {L"setPan", 1, (void*)ScriptCoreObject::maki_setPan}, // (scriptVar /*int*/ bal);
+ {L"setMute", 1, (void*)ScriptCoreObject::maki_setMute}, // (scriptVar /*int*/ mute);
+ {L"getMute", 0, (void*)ScriptCoreObject::maki_getMute}, // ();
+ {L"getLeftVuMeter", 0, (void*)ScriptCoreObject::maki_getLeftVuMeter}, // ();
+ {L"getRightVuMeter", 0, (void*)ScriptCoreObject::maki_getRightVuMeter}, // ();
+ {L"userButton", 1, (void*)ScriptCoreObject::maki_userButton}, // (scriptVar /*int*/ button);
+ {L"getEqStatus", 0, (void*)ScriptCoreObject::maki_getEqStatus}, // ();
+ {L"setEqStatus", 1, (void*)ScriptCoreObject::maki_setEqStatus}, // (scriptVar /*int*/ enable);
+ {L"getEqPreamp", 0, (void*)ScriptCoreObject::maki_getEqPreamp}, // ();
+ {L"setEqPreamp", 1, (void*)ScriptCoreObject::maki_setEqPreamp}, // (scriptVar /*int*/ pre);
+ {L"getEqBand", 1, (void*)ScriptCoreObject::maki_getEqBand}, // (scriptVar /*int*/ band);
+ {L"setEqBand", 2, (void*)ScriptCoreObject::maki_setEqBand}, // (scriptVar /*int*/ band, scriptVar /*int*/ val);
+ {L"getEqAuto", 0, (void*)ScriptCoreObject::maki_getEqAuto}, // ();
+ {L"setEqAuto", 1, (void*)ScriptCoreObject::maki_setEqAuto}, // (scriptVar /*int*/ enable);
+ {L"setCustomMsg", 1, (void*)ScriptCoreObject::maki_setCustomMsg}, // (scriptVar /*String*/ text);
+ {L"setPriority", 1, (void*)ScriptCoreObject::maki_setPriority}, // (scriptVar /*int*/ priority);
+ {L"getPriority", 0, (void*)ScriptCoreObject::maki_getPriority}, // ();
+ {L"rebuildConvertersChain", 0, (void*)ScriptCoreObject::maki_rebuildConvertersChain}, // ();
+
+};
+
+int CoreScriptObjectController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+// Only called by us and our friend the admin.
+ScriptObject *CoreScriptObjectController::instantiate(CoreToken token) {
+ ScriptCoreObject *gvo = new ScriptCoreObject(token);
+ ASSERT(gvo != NULL);
+ ScriptCoreObject::objects.addItem(gvo);
+ return gvo->getScriptObject();
+}
+
+ScriptObject *CoreScriptObjectController::instantiate() {
+ // magic value to make a new one.
+ return instantiate(0x80000000);
+}
+
+void CoreScriptObjectController::destroy(ScriptObject *o) {
+ ScriptCoreObject *gvo = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ ASSERT(gvo != NULL);
+ ScriptCoreObject::objects.removeItem(gvo);
+ delete gvo;
+}
+
+void *CoreScriptObjectController::encapsulate(ScriptObject *o) {
+ return NULL;
+}
+
+void CoreScriptObjectController::deencapsulate(void *o) {
+}
+
+// -----------------------------------------------------------------------------------------------------
+
+ScriptCoreObject::ScriptCoreObject(CoreToken token) {
+ getScriptObject()->vcpu_setClassName(L"Core");
+ getScriptObject()->vcpu_setController(coreController);
+ getScriptObject()->vcpu_setInterface(CORE_SCRIPTOBJECT_GUID, static_cast<ScriptCoreObject *>(this));
+#ifndef FAKE_SCRIPTCORE
+ curvol = -1;
+ if (token == 0x80000000) {
+ // If we create it new for the script, bind a sequencer and set the volume
+ core_handle = api->core_create();
+ initAsCreated();
+ } else {
+ // If the ScriptCoreAdminObject caused this object to be created,
+ // it will worry about calling initAsCreated() -- otherwise we don't
+ // bind ourselves as a sequencer to the core.
+ core_handle = token;
+ registered_sequencer = 0;
+ }
+
+ waServiceFactory *s = api->service_enumService(WaSvc::COREADMIN,0);
+ ASSERTPR(s,"Core Admin must be present to use ScriptCore!");
+ svc = castService<svc_coreAdmin>(s);
+ if (svc) {
+ svc->addCallback(core_handle, this);
+ }
+#endif
+}
+
+ScriptCoreObject::~ScriptCoreObject() {
+#ifndef FAKE_SCRIPTCORE
+ if (registered_sequencer) {
+ // don't remove a sequencer if we didn't add one
+ api->core_deregisterSequencer(core_handle, this);
+ }
+ api->core_delCallback(0, this);
+#endif
+}
+
+#ifndef FAKE_SCRIPTCORE
+void ScriptCoreObject::initAsCreated() {
+ api->core_registerSequencer(core_handle, this);
+#if TRICK_VOLUME
+ api->core_setVolume(core_handle, api->core_getVolume(0));
+ setVolume(255);
+#endif
+ registered_sequencer = 1;
+}
+#endif
+
+/*int ScriptCoreObject::corecb_onStopped() {
+ maki_onStop(SCRIPT_CALL, getScriptObject());
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEndOfDecode() {
+ maki_onStop(SCRIPT_CALL, getScriptObject());
+ return 0;
+}*/
+
+int ScriptCoreObject::getStatus() {
+#ifndef FAKE_SCRIPTCORE
+ return api->core_getStatus(core_handle);
+#else
+ return 0;
+#endif
+}
+
+void ScriptCoreObject::playFile(const wchar_t *file) {
+#ifndef FAKE_SCRIPTCORE
+ if (registered_sequencer) {
+ filetoplay = file;
+ } else {
+ String playstring = "FILE:";
+ playstring += file;
+ api->core_setNextFile(core_handle, playstring);
+ }
+ api->core_userButton(core_handle, UserButton::PLAY);
+#endif
+}
+
+#ifndef FAKE_SCRIPTCORE
+const char *ScriptCoreObject::enumItem(int pos) {
+ return filetoplay;
+}
+#endif
+
+void ScriptCoreObject::stop() {
+#ifndef FAKE_SCRIPTCORE
+ filetoplay = "";
+ api->core_userButton(core_handle, UserButton::STOP);
+#endif
+}
+
+void ScriptCoreObject::setVolume(int v) {
+#ifndef FAKE_SCRIPTCORE
+#if TRICK_VOLUME
+ // if we're not the main core....
+ if (core_handle) {
+ // set this core's volume as a percentage of the main core volume.
+ if (v == -1) v = curvol;
+ curvol = v;
+ int mainvolume = api->core_getVolume(0);
+ v = (int)( ((float)mainvolume * (float)v) / 256.0 );
+ if ((unsigned)v == api->core_getVolume(core_handle)) return;
+ api->core_setVolume(core_handle, MIN(MAX(0, v), 255));
+ } else {
+ // if we are the main core, don't cause recursion.
+ if ((v > 0) && (v != curvol)) {
+ curvol = v;
+ api->core_setVolume(core_handle, v);
+ }
+ }
+#else
+ api->core_setVolume(core_handle, v);
+#endif
+#endif
+}
+
+/*
+ Moved to be with all his friends.
+
+int ScriptCoreObject::corecb_onVolumeChange(int newvol) {
+ foreach(objects)
+ objects.getfor()->setVolume(-1);
+ endfor;
+ return 0;
+}
+*/
+
+/*scriptVar ScriptCoreObject::maki_onStop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}*/
+
+scriptVar ScriptCoreObject::maki_playFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreObject *gvo = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (gvo)
+ gvo->playFile(GET_SCRIPT_STRING(f));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptCoreObject::maki_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreObject *gvo = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (gvo)
+ gvo->stop();
+ RETURN_SCRIPT_VOID;
+}
+
+/*
+scriptVar ScriptCoreObject::maki_setVolume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreObject *gvo = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (gvo) gvo->setVolume(GET_SCRIPT_INT(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptCoreObject::maki_getStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCoreObject *gvo = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (gvo) return MAKE_SCRIPT_INT(gvo->getStatus());
+ RETURN_SCRIPT_ZERO;
+}
+*/
+
+PtrList<ScriptCoreObject> ScriptCoreObject::objects;
+
+
+int ScriptCoreObject::corecb_onStarted() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onStarted(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onStopped() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onStopped(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onPaused() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onPaused(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onUnpaused() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onUnpaused(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onSeeked(int newpos) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onSeeked(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newpos));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onVolumeChange(int newvol) {
+#ifndef FAKE_SCRIPTCORE
+#if TRICK_VOLUME
+ foreach(objects)
+ objects.getfor()->setVolume(-1);
+ endfor;
+#endif
+ scriptVar svInt = maki_onVolumeChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newvol));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onPanChange(int newpan) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onPanChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newpan));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEQStatusChange(int newval) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onEQStatusChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newval));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEQPreampChange(int newval) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onEQPreampChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newval));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEQBandChange(int band, int newval) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onEQBandChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(band), MAKE_SCRIPT_INT(newval));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEQFreqChange(int newval) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onEQFreqChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newval));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEQAutoChange(int newval) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onEQAutoChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newval));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onStatusMsg(const wchar_t *text)
+{
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onStatusMsg(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(text));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onWarningMsg(const wchar_t *text) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onWarningMsg(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(text));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onErrorMsg(const wchar_t *text) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onErrorMsg(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(text));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onTitleChange(const wchar_t *title) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onTitleChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(title));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onTitle2Change(const wchar_t *title2) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onTitle2Change(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(title2));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onInfoChange(const wchar_t *info) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onInfoChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(info));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onUrlChange(const wchar_t *url) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onUrlChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onLengthChange(int newlength) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onLengthChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(newlength));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onNextFile() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onNextFile(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onNeedNextFile(int fileid) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onNeedNextFile(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(fileid));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onSetNextFile(const wchar_t *playstring) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onSetNextFile(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(playstring));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onErrorOccured(int severity, const wchar_t *text) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onErrorOccured(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(severity), MAKE_SCRIPT_STRING(text));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onAbortCurrentSong() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onAbortCurrentSong(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onEndOfDecode() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onEndOfDecode(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onFileComplete(const wchar_t *playstring) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onFileComplete(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(playstring));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onConvertersChainRebuilt() {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onConvertersChainRebuilt(SCRIPT_CALL, getScriptObject());
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+int ScriptCoreObject::corecb_onMediaFamilyChange(const wchar_t *newfamily) {
+#ifndef FAKE_SCRIPTCORE
+ scriptVar svInt = maki_onMediaFamilyChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(newfamily));
+ if ((svInt.type != SCRIPT_VOID) && (svInt.type != SCRIPT_OBJECT) && (svInt.type != SCRIPT_STRING)) {
+ return GET_SCRIPT_INT(svInt);
+ }
+#endif
+ return 0;
+}
+
+
+scriptVar /*int*/ ScriptCoreObject::maki_onStarted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onStopped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onPaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onUnpaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onSeeked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newpos) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newpos);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newpos);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onVolumeChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newvol) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newvol);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newvol);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onPanChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newpan) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newpan);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newpan);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onEQStatusChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newval);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newval);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onEQPreampChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newval);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newval);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onEQBandChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band, scriptVar /*int*/ newval) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, coreController, band, newval);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, band, newval);
+}
+
+
+scriptVar /*int*/ ScriptCoreObject::maki_onEQFreqChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newval);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newval);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onEQAutoChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newval);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newval);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onStatusMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, text);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, text);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onWarningMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, text);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, text);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onErrorMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, text);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, text);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onTitleChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ title) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, title);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, title);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onTitle2Change(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ title2) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, title2);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, title2);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onInfoChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ info) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, info);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, info);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onUrlChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ url) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, url);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, url);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onLengthChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newlength) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newlength);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newlength);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onNeedNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ fileid) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, fileid);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, fileid);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onSetNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstring) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, playstring);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, playstring);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onErrorOccured(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ severity, scriptVar /*String*/ text) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, coreController, severity, text);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, severity, text);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onAbortCurrentSong(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onEndOfDecode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onFileComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstring) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, playstring);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, playstring);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onConvertersChainRebuilt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, coreController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_onMediaFamilyChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ newfamily) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, coreController, newfamily);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newfamily);
+}
+
+
+scriptVar /*int*/ ScriptCoreObject::maki_setNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstr) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->setNextFile(sco->core_handle, GET_SCRIPT_STRING(playstr)));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getStatus(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*String*/ ScriptCoreObject::maki_getCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_STRING(sco->svc->getCurrent(sco->core_handle));
+ }
+#endif
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getCurPlaybackNumber(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getCurPlaybackNumber(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getNumTracks(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getNumTracks(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getPosition(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getWritePosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getWritePosition(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ ms) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->setPosition(sco->core_handle, GET_SCRIPT_INT(ms)));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getLength(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getVolume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getVolume(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setVolume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ vol) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setVolume(sco->core_handle, GET_SCRIPT_INT(vol));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getPan(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getPan(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setPan(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ bal) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setPan(sco->core_handle, GET_SCRIPT_INT(bal));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setMute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ mute) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setMute(sco->core_handle, GET_SCRIPT_INT(mute));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getMute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getMute(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getLeftVuMeter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getLeftVuMeter(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getRightVuMeter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getRightVuMeter(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_userButton(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ button) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->userButton(sco->core_handle, GET_SCRIPT_INT(button));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getEqStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getEqStatus(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setEqStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ enable) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setEqStatus(sco->core_handle, GET_SCRIPT_INT(enable));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getEqPreamp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getEqPreamp(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setEqPreamp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ pre) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setEqPreamp(sco->core_handle, GET_SCRIPT_INT(pre));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getEqBand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getEqBand(sco->core_handle, GET_SCRIPT_INT(band)));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setEqBand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band, scriptVar /*int*/ val) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setEqBand(sco->core_handle, GET_SCRIPT_INT(band), GET_SCRIPT_INT(val));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getEqAuto(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getEqAuto(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setEqAuto(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ enable) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setEqAuto(sco->core_handle, GET_SCRIPT_INT(enable));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setCustomMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setCustomMsg(sco->core_handle, GET_SCRIPT_STRING(text));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_setPriority(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ priority) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->setPriority(sco->core_handle, GET_SCRIPT_INT(priority));
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*int*/ ScriptCoreObject::maki_getPriority(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ return MAKE_SCRIPT_INT(sco->svc->getPriority(sco->core_handle));
+ }
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void*/ ScriptCoreObject::maki_rebuildConvertersChain(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+#ifndef FAKE_SCRIPTCORE
+ ScriptCoreObject *sco = static_cast<ScriptCoreObject *>(o->vcpu_getInterface(CORE_SCRIPTOBJECT_GUID));
+ if (sco) {
+ ASSERT(sco->svc != NULL);
+ sco->svc->rebuildConvertersChain(sco->core_handle);
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/script/objects/core/coreobj.h b/Src/Wasabi/api/script/objects/core/coreobj.h
new file mode 100644
index 00000000..75b77346
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/core/coreobj.h
@@ -0,0 +1,192 @@
+#ifndef __CONOBJ_H
+#define __CONOBJ_H
+
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/core/sequence.h>
+#include <api/syscb/callbacks/corecbi.h>
+#include <api/core/corehandle.h>
+#ifdef GEN_FF
+#ifndef FAKE_SCRIPTCORE
+#define FAKE_SCRIPTCORE
+#endif
+#endif
+
+// {2825A91B-D488-4245-AAF1-7059CF88437B}
+static const GUID CORE_SCRIPTOBJECT_GUID =
+{ 0x2825a91b, 0xd488, 0x4245, { 0xaa, 0xf1, 0x70, 0x59, 0xcf, 0x88, 0x43, 0x7b } };
+
+extern ScriptObjectController *coreController;
+class PlayItem;
+class CoreAdminScriptObjectController;
+class svc_coreAdmin;
+
+// -----------------------------------------------------------------------------------------------------
+class ScriptCoreObject : public RootObjectInstance
+#ifndef FAKE_SCRIPTCORE
+, public ListSequencer, public CoreCallbackI/*, public CoreCallbackI*/
+#endif
+{
+ friend class CoreAdminScriptObjectController;
+ public:
+
+ ScriptCoreObject(CoreToken token = 0x80000000);
+ virtual ~ScriptCoreObject();
+
+ void playFile(const wchar_t *file);
+ void stop();
+ void setVolume(int v);
+ int getStatus();
+
+/* virtual int corecb_onStopped();
+ virtual int corecb_onEndOfDecode();*/
+
+ static scriptVar maki_playFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar file);
+ static scriptVar maki_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+// static scriptVar maki_onStop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+// static scriptVar maki_setVolume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+// static scriptVar maki_getStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ // Callback Methods in Maki.
+ static scriptVar /*int*/ maki_onStarted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onStopped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onPaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onUnpaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onSeeked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newpos);
+ static scriptVar /*int*/ maki_onVolumeChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newvol);
+ static scriptVar /*int*/ maki_onPanChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newpan);
+ static scriptVar /*int*/ maki_onEQStatusChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ static scriptVar /*int*/ maki_onEQPreampChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ static scriptVar /*int*/ maki_onEQBandChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band, scriptVar /*int*/ newval);
+ static scriptVar /*int*/ maki_onEQFreqChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ static scriptVar /*int*/ maki_onEQAutoChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newval);
+ static scriptVar /*int*/ maki_onStatusMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ static scriptVar /*int*/ maki_onWarningMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ static scriptVar /*int*/ maki_onErrorMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ static scriptVar /*int*/ maki_onTitleChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ title);
+ static scriptVar /*int*/ maki_onTitle2Change(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ title2);
+ static scriptVar /*int*/ maki_onInfoChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ info);
+ static scriptVar /*int*/ maki_onUrlChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ url);
+ static scriptVar /*int*/ maki_onLengthChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ newlength);
+ static scriptVar /*int*/ maki_onNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onNeedNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ fileid);
+ static scriptVar /*int*/ maki_onSetNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstring);
+ static scriptVar /*int*/ maki_onErrorOccured(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ severity, scriptVar /*String*/ text);
+ static scriptVar /*int*/ maki_onAbortCurrentSong(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onEndOfDecode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onFileComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstring);
+ static scriptVar /*int*/ maki_onConvertersChainRebuilt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_onMediaFamilyChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ newfamily);
+
+ static scriptVar /*int*/ maki_setNextFile(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ playstr);
+ static scriptVar /*int*/ maki_getStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*String*/ maki_getCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getCurPlaybackNumber(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getNumTracks(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getWritePosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ ms);
+ static scriptVar /*int*/ maki_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getVolume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_setVolume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ vol);
+ static scriptVar /*int*/ maki_getPan(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_setPan(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ bal);
+ static scriptVar /*void*/ maki_setMute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ mute);
+ static scriptVar /*int*/ maki_getMute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getLeftVuMeter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*int*/ maki_getRightVuMeter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_userButton(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ button);
+ static scriptVar /*int*/ maki_getEqStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_setEqStatus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ enable);
+ static scriptVar /*int*/ maki_getEqPreamp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_setEqPreamp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ pre);
+ static scriptVar /*int*/ maki_getEqBand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band);
+ static scriptVar /*void*/ maki_setEqBand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ band, scriptVar /*int*/ val);
+ static scriptVar /*int*/ maki_getEqAuto(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_setEqAuto(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ enable);
+ static scriptVar /*void*/ maki_setCustomMsg(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*String*/ text);
+ static scriptVar /*void*/ maki_setPriority(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ priority);
+ static scriptVar /*int*/ maki_getPriority(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*void*/ maki_rebuildConvertersChain(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static PtrList<ScriptCoreObject> objects;
+
+ protected:
+#ifndef FAKE_SCRIPTCORE
+ virtual int getNumEntries() { return 1; }
+ virtual const char *enumItem(int pos);
+ virtual int getCurrent() { return 0; }
+ virtual int setCurrent(int cur) { return 0; }
+#endif
+
+ // Callback Methods forwarded to Maki.
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+ virtual int corecb_onPaused();
+ virtual int corecb_onUnpaused();
+ virtual int corecb_onSeeked(int newpos);
+ virtual int corecb_onVolumeChange(int newvol);
+ virtual int corecb_onPanChange(int newpan);
+ virtual int corecb_onEQStatusChange(int newval);
+ virtual int corecb_onEQPreampChange(int newval);
+ virtual int corecb_onEQBandChange(int band, int newval);
+ virtual int corecb_onEQFreqChange(int newval);
+ virtual int corecb_onEQAutoChange(int newval);
+ virtual int corecb_onStatusMsg(const wchar_t *text);
+ virtual int corecb_onWarningMsg(const wchar_t *text);
+ virtual int corecb_onErrorMsg(const wchar_t *text);
+ virtual int corecb_onTitleChange(const wchar_t *title);
+ virtual int corecb_onTitle2Change(const wchar_t *title2);
+ virtual int corecb_onInfoChange(const wchar_t *info);
+ virtual int corecb_onUrlChange(const wchar_t *url);
+ virtual int corecb_onLengthChange(int newlength);
+ virtual int corecb_onNextFile();
+ virtual int corecb_onNeedNextFile(int fileid);
+ virtual int corecb_onSetNextFile(const wchar_t *playstring);
+ virtual int corecb_onErrorOccured(int severity, const wchar_t *text);
+ virtual int corecb_onAbortCurrentSong();
+ virtual int corecb_onEndOfDecode();
+ virtual int corecb_onFileComplete(const wchar_t *playstring);
+ virtual int corecb_onConvertersChainRebuilt();
+ virtual int corecb_onMediaFamilyChange(const wchar_t *newfamily);
+
+ private:
+ // Only called by us and our friend the admin.
+#ifndef FAKE_SCRIPTCORE
+ virtual void initAsCreated();
+
+ svc_coreAdmin *svc;
+ CoreToken core_handle;
+ String filetoplay;
+ int curvol;
+ int registered_sequencer;
+#endif
+};
+
+// -----------------------------------------------------------------------------------------------------
+class CoreScriptObjectController : public ScriptObjectControllerI {
+ friend CoreAdminScriptObjectController;
+ public:
+ virtual const wchar_t *getClassName() { return L"Core"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(rootObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; }
+ virtual GUID getClassGuid() { return CORE_SCRIPTOBJECT_GUID; }
+ virtual int getInstantiable() { return 1; }
+ virtual int getReferenceable() { return 1; }
+ virtual ScriptObject *instantiate();
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void destroy(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+
+ // Only called by us and our friend the admin.
+ virtual ScriptObject *instantiate(CoreToken token = 0x80000000);
+};
+
+// -----------------------------------------------------------------------
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/core/svc_scriptcore.cpp b/Src/Wasabi/api/script/objects/core/svc_scriptcore.cpp
new file mode 100644
index 00000000..a4c3ed1c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/core/svc_scriptcore.cpp
@@ -0,0 +1,38 @@
+#include <precomp.h>
+#include "svc_scriptcore.h"
+#include <api/script/objects/core/coreobj.h>
+#include <api/script/objects/core/coreadminobj.h>
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(ScriptCore_Svc);
+DECLARE_SERVICETSINGLE(svc_scriptObject, CoreScriptObjectSvc);
+END_SERVICES(ScriptCore_Svc, _ScriptCore_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_ScriptCore_Svc; }
+#else
+extern "C" { int __link_ScriptCore_Svc; }
+#endif
+
+#endif
+
+// -----------------------------------------------------------------------------------------------------
+// Service
+
+ScriptObjectController *CoreScriptObjectSvc::getController(int n) {
+ switch (n) {
+ case 0:
+ return coreController;
+ }
+ return NULL;
+}
+
+ScriptObjectController *CoreAdminScriptObjectSvc::getController(int n) {
+ switch (n) {
+ case 0:
+ return coreAdminController;
+ }
+ return NULL;
+}
+
diff --git a/Src/Wasabi/api/script/objects/core/svc_scriptcore.h b/Src/Wasabi/api/script/objects/core/svc_scriptcore.h
new file mode 100644
index 00000000..c6530aa5
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/core/svc_scriptcore.h
@@ -0,0 +1,27 @@
+#ifndef __GUIVIDEOSVC_H
+#define __GUIVIDEOSVC_H
+
+#include <api/service/svcs/svc_scriptobji.h>
+
+class CoreScriptObjectSvc : public svc_scriptObjectI {
+
+public:
+ CoreScriptObjectSvc() {};
+ virtual ~CoreScriptObjectSvc() {};
+
+ static const char *getServiceName() { return "MediaCore maki object"; }
+ virtual ScriptObjectController *getController(int n);
+};
+
+class CoreAdminScriptObjectSvc : public svc_scriptObjectI {
+
+public:
+ CoreAdminScriptObjectSvc() {};
+ virtual ~CoreAdminScriptObjectSvc() {};
+
+ static const char *getServiceName() { return "MediaCoreAdmin maki object"; }
+ virtual ScriptObjectController *getController(int n);
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/script/objects/guiobj.cpp b/Src/Wasabi/api/script/objects/guiobj.cpp
new file mode 100644
index 00000000..dd7b5903
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/guiobj.cpp
@@ -0,0 +1,2880 @@
+#include <precomp.h>
+#include <bfc/wasabi_std.h>
+#include <api/wnd/notifmsg.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/script.h>
+#include <api/script/objects/guiobj.h>
+#include <api/script/vcpu.h>
+#include <api/skin/widgets/group.h>
+//#include <api/wac/main.h>
+#include <math.h>
+#include <api/skin/skinparse.h>
+#include <api/wndmgr/layout.h>
+#include <api/script/objecttable.h>
+#include <api/wnd/cwndtrack.h>
+#include <api/wnd/popup.h>
+#include <bfc/parse/paramparser.h>
+#include <api/wnd/cursor.h>
+#include <api/wnd/wndtrack.h>
+#include <bfc/string/stringdict.h>
+#include <api/config/items/cfgitem.h>
+#include <api/config/items/attrbool.h>
+#ifndef PI
+#define PI 3.1415926536F
+#endif
+
+#include <api/script/objects/guiobject.h>
+
+const wchar_t guiobjectXuiStr[] = L"GuiObject"; // This is the xml tag
+char guiobjectXuiSvcName[] = "GuiObject xui object"; // this is the name of the xuiservice
+
+#ifdef USEAPPBAR
+extern _bool cfg_options_appbarondrag;
+#endif
+
+static wchar_t txt[4096];
+
+GuiObjectI::GuiObjectI(ScriptObject *o) {
+ translate = 1;
+ my_script_object = o;
+ my_root_wnd = NULL;
+
+ redock.l = NULL;
+ MEMSET(&redock.original_rect, 0, sizeof(RECT));
+ targetstatus = TARGET_FROZEN;
+ targetspeed = 4;
+ start_time = 0;
+ reversetarget = 0;
+ dodragcheck = 0;
+ gui_rx = 0;
+ gui_ry = 0;
+ gui_rw = 0;
+ gui_rh = 0;
+ gui_x = 0;
+ gui_y = 0;
+ gui_w = AUTOWH;
+ gui_h = AUTOWH;
+ p_group = NULL;
+ targetx = AUTOWH;
+ targety = AUTOWH;
+ targetw = AUTOWH;
+ targeth = AUTOWH;
+ targeta = AUTOWH;
+ in_area = 0;
+ clickthrough = 0;
+ autosysmetricsx = 0;
+ autosysmetricsy = 0;
+ autosysmetricsw = 0;
+ autosysmetricsh = 0;
+ xuisvc = NULL;
+ xuifac = NULL;
+ mover = 0;
+ moving = 0;
+ droptarget = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ cfgitem = NULL;
+#endif
+ timer.setGuiObjectI(this);
+ wantfocus = 0;
+ anchorage = ANCHOR_NONE;
+ anchor_x1 = anchor_x2 = anchor_y1 = anchor_y2 = 0;
+ anchorage_invalidated = 0;
+ anchorage = ANCHOR_LEFT|ANCHOR_TOP;
+ cursor = NULL;
+#ifdef USEAPPBAR
+ m_dock_side = APPBAR_NOTDOCKED;
+#endif
+ m_lastnondocked_x = -0xFFFF;
+ m_lastnondocked_y = -0xFFFF;
+}
+
+GuiObjectI::~GuiObjectI() {
+ notifylist.deleteAll();
+ delete cursor;
+ if (guiobject_getParentGroup())
+ guiobject_getParentGroup()->removeObject(this);
+ if (targetstatus == TARGET_RUNNING)
+ stopTargetTimer();
+#ifdef WASABI_COMPILE_CONFIG
+ if (cfgitem) viewer_delViewItem(cfgitem);
+#endif
+}
+
+ScriptObject *GuiObjectI::guiobject_getScriptObject()
+{
+ return my_script_object;
+}
+
+// Used by us when parsing xml to assign the object's ID, shouldn't be used elsewhere
+void GuiObjectI::guiobject_setId(const wchar_t *id)
+{
+ guiobject_id = id;
+}
+
+const wchar_t *GuiObjectI::guiobject_getId()
+{
+ if (guiobject_id.isempty()) return L"";
+ return guiobject_id; //FG> avoid returning NULL
+}
+
+int GuiObjectI::guiobject_setXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ int r = 0;
+ //ifc_window *w = guiobject_getRootWnd();
+ XmlObject *xo = static_cast<XmlObject *>(guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ if (xo != NULL) {
+ r = xo->setXmlParam(paramname, strvalue);
+ }
+ return r;
+}
+
+const wchar_t *GuiObjectI::guiobject_getXmlParam(const wchar_t *paramname) {
+ const wchar_t *rt = NULL;
+ //ifc_window *w = guiobject_getRootWnd();
+ XmlObject *xo = static_cast<XmlObject *>(guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ if (xo != NULL) {
+ int r = xo->getXmlParam(paramname);
+ rt = xo->getXmlParamValue(r);
+ }
+ return rt;
+}
+
+int GuiObjectI::guiobject_setXmlParamById(int id, const wchar_t *strvalue)
+{
+ int a;
+ switch (id) {
+ case GuiObjectWnd::GUIOBJECT_ID:
+ guiobject_setId(strvalue);
+ break;
+ case GuiObjectWnd::GUIOBJECT_ALPHA:
+ if (wcschr(strvalue, ',')) // erroneous value, this is probably a color, or something
+ guiobject_setAlpha(255);
+ else
+ guiobject_setAlpha(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_ACTIVEALPHA:
+ if (wcschr(strvalue, ',')) // erroneous value, this is probably a color, or something
+ guiobject_setActiveAlpha(255);
+ else
+ guiobject_setActiveAlpha(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_INACTIVEALPHA:
+ if (wcschr(strvalue, ',')) // erroneous value, this is probably a color, or something
+ guiobject_setInactiveAlpha(255);
+ else
+ guiobject_setInactiveAlpha(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SYSREGION:
+ guiobject_setRegionOp(WASABI_API_SKIN->parse(strvalue, L"regionop"));
+ break;
+ case GuiObjectWnd::GUIOBJECT_RECTRGN:
+ guiobject_setRectRgn(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_TOOLTIP:
+ guiobject_getRootWnd()->setTip(strvalue);
+ break;
+ case GuiObjectWnd::GUIOBJECT_SYSMETRICSX:
+ guiobject_setAutoSysMetricsX(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SYSMETRICSY:
+ guiobject_setAutoSysMetricsY(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SYSMETRICSW:
+ guiobject_setAutoSysMetricsW(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SYSMETRICSH:
+ guiobject_setAutoSysMetricsH(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_MOVE:
+ guiobject_setMover(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_RENDERBASETEXTURE:
+ guiobject_getRootWnd()->setRenderBaseTexture(WTOI(strvalue));
+ break;
+#ifdef WASABI_COMPILE_CONFIG
+ case GuiObjectWnd::GUIOBJECT_CFGATTR:
+ setCfgAttr(strvalue);
+ break;
+#endif
+ case GuiObjectWnd::GUIOBJECT_TABORDER:
+ guiobject_setTabOrder(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_X: {
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(&a, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_Y: {
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, &a, NULL, NULL, NULL, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_W: {
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, NULL, &a, NULL, NULL, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_H: {
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, NULL, NULL, &a, NULL, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_FITTOPARENT: {
+ int v = WTOI(strvalue);
+ if (v) {
+ int one = 1;
+ int x = 0, y = 0, w = 0, h = 0;
+ if (v < 0) {
+ v = -v;
+ x += v;
+ y += v;
+ w -= v * 2;
+ h -= v * 2;
+ }
+ guiobject_setGuiPosition(&x, &y, &w, &h, NULL, NULL, &one, &one);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ }
+ break; }
+ case GuiObjectWnd::GUIOBJECT_WANTFOCUS:
+ wantfocus = WTOI(strvalue);
+ if (guiobject_getRootWnd()->isPostOnInit()) {
+ if (wantfocus) {
+ if (guiobject_getRootWnd()->getTabOrder() == -1)
+ guiobject_getRootWnd()->setAutoTabOrder();
+ } else {
+ if (guiobject_getRootWnd()->getTabOrder() != -1)
+ guiobject_getRootWnd()->setTabOrder(-1);
+ }
+ }
+ break;
+ case GuiObjectWnd::GUIOBJECT_VISIBLE: {
+ a = WTOI(strvalue);
+ ifc_window *w = guiobject_getRootWnd();
+ if (w->isPostOnInit())
+ w->setVisible(a);
+ else
+ w->setStartHidden(!a);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_RELATX: {
+ if (strvalue && *strvalue == '%')
+ a = 2;
+ else
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, NULL, NULL, NULL, &a, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_RELATY: {
+ if (strvalue && *strvalue == '%')
+ a = 2;
+ else
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, NULL, NULL, NULL, NULL, &a, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_RELATW: {
+ if (strvalue && *strvalue == '%')
+ a = 2;
+ else
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, NULL, NULL, NULL, NULL, NULL, &a, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_RELATH: {
+ if (strvalue && *strvalue == '%')
+ a = 2;
+ else
+ a = WTOI(strvalue);
+ guiobject_setGuiPosition(NULL, NULL, NULL, NULL, NULL, NULL, NULL, &a);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break; }
+ case GuiObjectWnd::GUIOBJECT_DROPTARGET:
+ guiobject_setDropTarget(strvalue);
+ break;
+ case GuiObjectWnd::GUIOBJECT_GHOST:
+ guiobject_setClickThrough(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETNODBLCLICK:
+ guiobject_setNoDoubleClick(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETNOLEFTCLICK:
+ guiobject_setNoLeftClick(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETNORIGHTCLICK:
+ guiobject_setNoRightClick(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETNOMOUSEMOVE:
+ guiobject_setNoMouseMove(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETNOCONTEXTMENU:
+ guiobject_setNoContextMenu(WTOI(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETX1: {
+ a = WTOI(strvalue);
+ guiobject_setAnchoragePosition(&a, NULL, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break;
+ }
+ case GuiObjectWnd::GUIOBJECT_SETY1:{
+ a = WTOI(strvalue);
+ guiobject_setAnchoragePosition(NULL, &a, NULL, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break;
+ }
+ case GuiObjectWnd::GUIOBJECT_SETX2:{
+ a = WTOI(strvalue);
+ guiobject_setAnchoragePosition(NULL, NULL, &a, NULL, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break;
+ }
+ case GuiObjectWnd::GUIOBJECT_SETY2:{
+ a = WTOI(strvalue);
+ guiobject_setAnchoragePosition(NULL, NULL, NULL, &a, NULL);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ break;
+ }
+ case GuiObjectWnd::GUIOBJECT_SETANCHOR: {
+ int anchorage=ANCHOR_NONE;
+ ParamParser pp(strvalue, L"|");
+ for (int m=0;m<pp.getNumItems();m++)
+ {
+ const wchar_t *s = pp.enumItem(m);
+ if (!WCSICMP(s, L"left")) anchorage |= ANCHOR_LEFT;
+ else if (!WCSICMP(s, L"top")) anchorage |= ANCHOR_TOP;
+ else if (!WCSICMP(s, L"right")) anchorage |= ANCHOR_RIGHT;
+ else if (!WCSICMP(s, L"bottom")) anchorage |= ANCHOR_BOTTOM;
+ }
+ guiobject_setAnchoragePosition(NULL, NULL, NULL, NULL, &anchorage);
+ Group *g = guiobject_getParentGroup();
+ if (g != NULL && guiobject_getRootWnd()->isPostOnInit())
+ g->updatePos(this);
+ }
+ break;
+ case GuiObjectWnd::GUIOBJECT_SETCURSOR:
+ guiobject_setCursor(strvalue);
+ break;
+ case GuiObjectWnd::GUIOBJECT_NOTIFY:
+ notifylist.addItem(new StringW(strvalue));
+ break;
+ case GuiObjectWnd::GUIOBJECT_USERDATA:
+ // nothing to do, param goes in xmlobject
+ break;
+#ifdef USEAPPBAR
+ case GuiObjectWnd::GUIOBJECT_APPBAR:
+ setAppBar(strvalue);
+ break;
+#endif
+ case GuiObjectWnd::GUIOBJECT_TRANSLATE:
+ translate = WTOI(strvalue);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void GuiObjectI::guiobject_getGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh) {
+ if (x) *x = gui_x;
+ if (y) *y = gui_y;
+ if (w) *w = gui_w;
+ if (h) *h = gui_h;
+ if (rx) *rx = gui_rx;
+ if (ry) *ry = gui_ry;
+ if (rw) *rw = gui_rw;
+ if (rh) *rh = gui_rh;
+}
+
+void GuiObjectI::guiobject_setGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh) {
+ if (x && *x != NOCHANGE && *x != AUTOWH) gui_x = *x;
+ if (y && *y != NOCHANGE && *y != AUTOWH) gui_y = *y;
+ if (w && *w != NOCHANGE && *w != AUTOWH) gui_w = *w;
+ if (h && *h != NOCHANGE && *h != AUTOWH) gui_h = *h;
+ if (rx && *rx != NOCHANGE && *rx != AUTOWH) gui_rx = *rx;
+ if (ry && *ry != NOCHANGE && *ry != AUTOWH) gui_ry = *ry;
+ if (rw && *rw != NOCHANGE && *rw != AUTOWH) gui_rw = *rw;
+ if (rh && *rh != NOCHANGE && *rh != AUTOWH) gui_rh = *rh;
+ if (guiobject_getRootWnd()->isInited() && guiobject_getParentGroup())
+ guiobject_getParentGroup()->updatePos(this);
+ else {
+ if (!guiobject_getRootWnd()->isVirtual())
+ guiobject_getRootWnd()->resize(gui_x, gui_y, gui_w, gui_h);
+ }
+}
+
+int GuiObjectI::guiobject_getAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor) {
+ if (x1) *x1 = anchor_x1;
+ if (y1) *y1 = anchor_y1;
+ if (x2) *x2 = anchor_x2;
+ if (y2) *y2 = anchor_y2;
+ if (anchor) *anchor = anchorage;
+ return anchorage_invalidated;
+}
+
+void GuiObjectI::guiobject_setAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor) {
+ anchorage_invalidated = 1;
+ if (x1) anchor_x1 = *x1;
+ if (x2) anchor_x2 = *x2;
+ if (y1) anchor_y1 = *y1;
+ if (y2) anchor_y2 = *y2;
+ if (anchor) anchorage = *anchor;
+ if (guiobject_getRootWnd()->isInited() && guiobject_getParentGroup()) {
+ guiobject_getParentGroup()->updatePos(this);
+ }
+}
+
+void GuiObjectI::guiobject_validateAnchorage() {
+ anchorage_invalidated = 0;
+}
+
+void GuiObjectI::guiobject_setClickThrough(int c) {
+ guiobject_getRootWnd()->setClickThrough(c);
+}
+
+void GuiObjectI::guiobject_setRegionOp(int op) {
+ guiobject_getRootWnd()->setRegionOp(op);
+}
+
+int GuiObjectI::guiobject_getRegionOp() {
+ return guiobject_getRootWnd()->getRegionOp();
+}
+
+void GuiObjectI::guiobject_setRectRgn(int rrgn) {
+ guiobject_getRootWnd()->setRectRgn(rrgn);
+}
+
+void GuiObjectI::guiobject_setMover(int n) {
+ mover = n;
+}
+
+int GuiObjectI::guiobject_getMover() {
+ return mover;
+}
+
+FOURCC GuiObjectI::guiobject_getDropTarget() {
+ return droptarget;
+}
+
+void GuiObjectI::guiobject_setDropTarget(const wchar_t *strval)
+{
+ if (strval == NULL)
+ droptarget = 0;
+ else
+ {
+ uint8_t *temp = (uint8_t *)&droptarget;
+ temp[3]=(uint8_t)strval[0];
+ temp[2]=(uint8_t)strval[1];
+ temp[1]=(uint8_t)strval[2];
+ temp[0]=(uint8_t)strval[3];
+ }
+}
+
+int GuiObjectI::guiobject_isRectRgn() {
+ return guiobject_getRootWnd()->isRectRgn();
+}
+
+int GuiObjectI::guiobject_isClickThrough() {
+ return guiobject_getRootWnd()->isClickThrough();
+}
+
+void GuiObjectI::guiobject_setParentGroup(Group *l) {
+ if (!l) { p_group = NULL; return; }
+ p_group = l;
+}
+
+Group *GuiObjectI::guiobject_getParentGroup() {
+ if (!p_group) return NULL;
+ return p_group;
+}
+
+GuiObject *GuiObjectI::guiobject_getParent() {
+ ifc_window *grw = guiobject_getRootWnd();
+ if (!grw) return NULL;
+ ifc_window *w = grw->getParent();
+ if (!w) return NULL;
+ return static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+Layout *GuiObjectI::guiobject_getParentLayout() {
+ Group *m = p_group;
+ Layout *l = NULL;
+ while (m) {
+ if (m->isLayout()) {
+ l = static_cast<Layout *>(m);
+ break;
+ }
+ m = m->getGuiObject()->guiobject_getParentGroup();
+ }
+ if (!l) {
+ ifc_window *w = guiobject_getRootWnd()->getDesktopParent();
+ if (w)
+ l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ }
+ if (l && l->isDeleting()) return NULL;
+ return l;
+}
+#endif
+
+GuiObject *GuiObjectI::guiobject_getTopParent() {
+ ifc_window *m = guiobject_getRootWnd();
+ GuiObject *top = this;
+
+ while (m != NULL) {
+ m = m->getParent();
+ if (m != NULL) {
+ GuiObject *g = m->getGuiObject();
+ if (g != NULL)
+ top = g;
+ }
+ }
+
+ return top;
+}
+
+/*void GuiObjectI::parseNotify(const char *s) {
+ scriptNotify(s, "", 0, 0);
+}*/
+
+void GuiObjectI::guiobject_bringToFront() {
+ ifc_window *b = guiobject_getRootWnd();
+ if (b) {
+ if (b->getParent())
+ b->getParent()->bringVirtualToFront(b);
+ }
+}
+
+void GuiObjectI::guiobject_bringToBack() {
+ ifc_window *b = guiobject_getRootWnd();
+ if (b) {
+ if (b->getParent())
+ b->getParent()->bringVirtualToBack(b);
+ }
+}
+
+void GuiObjectI::guiobject_bringAbove(GuiObject *o) {
+ ASSERT(o != NULL);
+ ifc_window *b = guiobject_getRootWnd();
+ ifc_window *c = o->guiobject_getRootWnd();
+ if (b && c) {
+ if (b->getParent())
+ b->getParent()->bringVirtualAbove(b, c);
+ }
+}
+
+void GuiObjectI::guiobject_bringBelow(GuiObject *o) {
+ ASSERT(o != NULL);
+ ifc_window *b = guiobject_getRootWnd();
+ ifc_window *c = o->guiobject_getRootWnd();
+ if (b && c) {
+ if (b->getParent())
+ b->getParent()->bringVirtualBelow(b, c);
+ }
+}
+
+void GuiObjectI::guiobject_setTargetSpeed(float s) { // s == n of seconds
+ if (targetspeed == (int)(s * 4.0)) return;
+ targetspeed = (int)(s * 4.0); // units of 250ms
+ if (targetstatus == TARGET_RUNNING) {
+ stopTargetTimer();
+ startTargetTimer();
+ }
+}
+
+void GuiObjectTimer::timerclient_timerCallback(int id) {
+ if (id == TARGETTIMER_ID && obj)
+ obj->onTargetTimer();
+}
+
+void GuiObjectI::guiobject_setTargetX(int x) {
+ targetx = x;
+}
+
+void GuiObjectI::guiobject_setTargetY(int y) {
+ targety = y;
+}
+
+void GuiObjectI::guiobject_setTargetW(int w) {
+ targetw = w;
+}
+
+void GuiObjectI::guiobject_setTargetH(int h) {
+ targeth = h;
+}
+
+void GuiObjectI::guiobject_setTargetA(int a) {
+ targeta = a;
+}
+
+void GuiObjectI::guiobject_gotoTarget() {
+ if (!guiobject_getRootWnd()) return;
+ start_time=0;
+ guiobject_getGuiPosition(&startx, &starty, &startw, &starth, NULL, NULL, NULL, NULL);
+ starta = guiobject_getAlpha();
+ if (targetx == AUTOWH || targetx == NOCHANGE)
+ targetx = startx;
+ if (targety == AUTOWH || targety == NOCHANGE)
+ targety = starty;
+ if (targetw == AUTOWH || targetw == NOCHANGE)
+ targetw = startw;
+ if (targeth == AUTOWH || targeth == NOCHANGE)
+ targeth = starth;
+ if (targeta == AUTOWH || targeta == NOCHANGE)
+ targeta = starta;
+ startTargetTimer();
+ Layout *l = static_cast<Layout *>(guiobject_getScriptObject()->vcpu_getInterface(layoutGuid));
+ if (targetx != startx ||
+ targety != starty ||
+ targetw != startw ||
+ targeth != starth) {
+ if (l) windowTracker->beforeRedock(l, &redock);
+ }
+}
+
+void GuiObjectI::startTargetTimer() {
+ timer.timerclient_setTimer(TARGETTIMER_ID, 20);
+ targetstatus = TARGET_RUNNING;
+}
+
+void GuiObjectI::stopTargetTimer() {
+ timer.timerclient_killTimer(TARGETTIMER_ID);
+ targetstatus = TARGET_FROZEN;
+}
+
+void GuiObjectI::onTargetTimer() {
+
+ if (targetstatus != TARGET_RUNNING) return;
+ if (!guiobject_getRootWnd()) return;
+
+ RECT r;
+ guiobject_getRootWnd()->getClientRect(&r);
+ RECT wr;
+ guiobject_getRootWnd()->getWindowRect(&wr);
+
+ int ttime=250*targetspeed;
+ if (ttime < 0) ttime = 0;
+
+ int n;
+ if (!start_time)
+ {
+ n=0;
+ start_time = Wasabi::Std::getTickCount();
+ }
+ else
+ {
+ n=MulDiv(Wasabi::Std::getTickCount()-start_time,256,ttime);
+ }
+
+ if (ttime == 0) n = 255;
+
+ if (n >= 255) n=255;
+
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5); // used for smoothing transitions
+
+ float nw = ((float)(targetw - startw) * sintrans) + startw;
+ float nh = ((float)(targeth - starth) * sintrans) + starth;
+ float na = ((float)(targeta - starta) * sintrans) + starta;
+
+ Layout *l = static_cast<Layout *>(guiobject_getScriptObject()->vcpu_getInterface(layoutGuid));
+ int islayout = l != NULL && static_cast<ifc_window*>(l) == guiobject_getRootWnd();
+
+ float rat = 1.0f;
+ if (islayout) rat = (float)l->getRenderRatio();
+
+ float nx;
+ float ny;
+ if (!reversetarget) {
+ nx = ((float)(targetx - startx) * sintrans) + startx;
+ ny = ((float)(targety - starty) * sintrans) + starty;
+ } else {
+ nx = startx - ((float)(targetw - startw) * sintrans) * rat;
+ ny = starty - ((float)(targeth - starth) * sintrans) * rat;
+ }
+
+ int zx=(int)nx;
+ int zy=(int)ny;
+ int zw=(int)nw;
+ int zh=(int)nh;
+
+ if (reversetarget) {
+ while (zy + zh * rat < wr.bottom) zy++;
+ while (zx + zw * rat < wr.right) zx++;
+ }
+
+ int oldredraw = -1;
+ if (reversetarget && islayout) {
+ oldredraw = l->wantRedrawOnResize();
+ l->setWantRedrawOnResize(0);
+
+ int paddtop = wr.top - (int)ny;
+ int paddleft = wr.left - (int)nx;
+
+#ifdef _WIN32
+ if (paddtop > 0 || paddleft > 0) {
+ RegionI r;
+ GetWindowRgn(l->gethWnd(), r.getOSHandle());
+ r.offset(MAX(0, paddleft), MAX(0, paddtop));
+ SetWindowRgn(l->gethWnd(), r.makeWindowRegion(), FALSE);
+ }
+#else
+#warning port me
+#endif
+ }
+ guiobject_setGuiPosition(&zx, &zy, &zw, &zh, NULL, NULL, NULL, NULL);
+ guiobject_getRootWnd()->cascadeRepaint(0);
+ guiobject_setAlpha((int)na);
+ if (n==255) {
+ stopTargetTimer();
+ guiobject_onTargetReached();
+ }
+ if (l != NULL) l->savePosition();
+ if (oldredraw != -1 && l) {
+ l->setWantRedrawOnResize(oldredraw);
+ }
+}
+
+void GuiObjectI::guiobject_cancelTarget() {
+ stopTargetTimer();
+ Layout *l = static_cast<Layout *>(guiobject_getScriptObject()->vcpu_getInterface(layoutGuid));
+ if (l && redock.l) windowTracker->afterRedock(l, &redock);
+}
+
+void GuiObjectI::guiobject_reverseTarget(int reverse) {
+ reversetarget = reverse;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void GuiObjectI::guiobject_popParentLayout() {
+ Layout *l = guiobject_getParentLayout();
+ if (l && l->getParentContainer()) {
+ SkinParser::showContainer(l->getParentContainer()->getId(), TRUE);
+#ifdef WIN32
+ SetForegroundWindow(l->gethWnd());
+#else
+ l->bringToFront();
+#endif
+ }
+}
+#endif
+
+int GuiObjectI::guiobject_movingToTarget() {
+ return targetstatus == TARGET_RUNNING;
+}
+
+void GuiObjectI::guiobject_onLeftButtonDown(int x, int y) {
+ if (!VCPU::getComplete()) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ GuiObject_ScriptMethods::onLeftButtonDown(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+ if (mover && !VCPU::getComplete()) {
+ #ifdef WASABI_COMPILE_WNDMGR
+ Layout *l = guiobject_getParentLayout();
+ if (l) {
+ // Martin> (9/9/8) added l->getGuiObject()->guiobject_getMover() so setting move="0" to layouts will disable moving it around
+ if (!l->isLocked() && l->getGuiObject()->guiobject_getMover()) {
+#ifdef USEAPPBAR
+ if (cfg_options_appbarondrag) {
+ m_initial_dock_side = m_dock_side = l->appbar_getSide();
+ if (m_dock_side != APPBAR_NOTDOCKED) {
+ dodragcheck = 1;
+ goto skipit;
+ }
+ }
+#endif
+ l->maximize(0);
+ skipit:
+ l->beginMove();
+ if (l->getParentContainer() && l->getParentContainer()->isMainContainer() || Std::keyModifier(STDKEY_ALT))
+ WASABI_API_WNDMGR->wndTrackStartCooperative(l);
+ moving = 1;
+ anchor.x = (int)((float)x * guiobject_getRootWnd()->getRenderRatio());
+ anchor.y = (int)((float)y * guiobject_getRootWnd()->getRenderRatio());
+ }
+ }
+ #endif //WASABI_COMPILE_WNDMGR
+ }
+ }
+}
+
+void GuiObjectI::guiobject_onLeftButtonUp(int x, int y) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ GuiObject_ScriptMethods::onLeftButtonUp(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+ if (moving) {
+ int sendendmove = 0;
+#ifdef WASABI_COMPILE_WNDMGR
+ Group *l = guiobject_getParentLayout();
+ if (l) {
+ if (WASABI_API_WNDMGR->wndTrackWasCooperative())
+ WASABI_API_WNDMGR->wndTrackEndCooperative();
+ moving = 0;
+ sendendmove = 1;
+ }
+#ifdef USEAPPBAR
+ if (cfg_options_appbarondrag) {
+ if (m_dock_side != m_initial_dock_side) {
+ ifc_window *dw = guiobject_getRootWnd()->getDesktopParent();
+ if (dw) {
+ AppBar *ab = reinterpret_cast<AppBar *>(dw->getInterface(appBarGuid));
+ if (ab) {
+ if (m_dock_side == APPBAR_NOTDOCKED) ab->appbar_setNoRestore(1);
+ ab->appbar_dock(m_dock_side);
+ if (m_dock_side == APPBAR_NOTDOCKED) ab->appbar_setNoRestore(0);
+ }
+ }
+ }
+ if (m_dock_side == APPBAR_NOTDOCKED) {
+ ifc_window *dp = guiobject_getRootWnd()->getDesktopParent();
+ if (dp) dp->restore(0);
+ }
+ } else {
+ ifc_window *dp = guiobject_getRootWnd()->getDesktopParent();
+ if (dp) dp->restore(0);
+ }
+#else
+ ifc_window *dp = guiobject_getRootWnd()->getDesktopParent();
+ if (dp) dp->restore(0);
+#endif // USEAPPBAR
+ if (sendendmove && l) l->endMove();
+#endif //WASABI_COMPILE_WNDMGR
+ }
+}
+
+void GuiObjectI::guiobject_onRightButtonDown(int x, int y) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ GuiObject_ScriptMethods::onRightButtonDown(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+}
+
+#ifdef WASABI_CUSTOM_CONTEXTMENUS
+extern void appContextMenu(ifc_window *wnd);
+extern void appControlMenu(ifc_window *wnd);
+#endif
+
+void GuiObjectI::guiobject_onRightButtonUp(int x, int y) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ GuiObject_ScriptMethods::onRightButtonUp(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+ ifc_window *w = guiobject_getRootWnd();
+ if (Std::keyModifier(STDKEY_CONTROL) &&
+ Std::keyModifier(STDKEY_SHIFT)) {
+ GuiObjectI::infoMenu(this, x, y);
+ } else {
+ if (w && w->wantAutoContextMenu() && !VCPU::getComplete() && WASABI_API_WNDMGR->getModalWnd() == NULL) {
+ ifc_window *par = w->getParent();
+ if (par && guiobject_getParentLayout()) {
+ if (!Std::keyModifier(STDKEY_CONTROL)) {
+#if defined(WA3COMPATIBILITY)
+ Main::appContextMenu(par, TRUE, guiobject_getParentLayout()->isTransparencySafe());
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ appContextMenu(par);
+#endif
+ } else {
+ Layout *l = guiobject_getParentLayout();
+ if (l->getParent() == NULL) {
+#if defined(WA3COMPATIBILITY)
+ l->controlMenu();
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ appControlMenu(l);
+#endif
+ }
+ }
+ } else {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l != NULL) {
+ if (!Std::keyModifier(STDKEY_CONTROL)) {
+#if defined(WA3COMPATIBILITY)
+ Main::appContextMenu(w, TRUE, l->isTransparencySafe());
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ appContextMenu(w);
+#endif
+ } else {
+#if defined(WA3COMPATIBILITY)
+ l->controlMenu();
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ appControlMenu(l);
+#endif
+ }
+ }
+ }
+ }
+ }
+}
+
+void GuiObjectI::guiobject_onRightButtonDblClk(int x, int y) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ GuiObject_ScriptMethods::onRightButtonDblClk(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+}
+
+void GuiObjectI::guiobject_onLeftButtonDblClk(int x, int y) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x/* - wr.left*/);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y/* - wr.top*/);
+ GuiObject_ScriptMethods::onLeftButtonDblClk(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+}
+
+int GuiObjectI::guiobject_onMouseWheelUp(int clicked, int lines)
+{
+ scriptVar retval;
+ retval = GuiObject_ScriptMethods::onMouseWheelUp(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_INT(clicked), MAKE_SCRIPT_INT(lines) );
+ int retv;
+
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ retv = 0;
+ else
+ retv = GET_SCRIPT_INT(retval);
+
+ return retv;
+}
+
+int GuiObjectI::guiobject_onMouseWheelDown(int clicked, int lines)
+{
+ scriptVar retval;
+ retval = GuiObject_ScriptMethods::onMouseWheelDown(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_INT(clicked), MAKE_SCRIPT_INT(lines) );
+ int retv;
+
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ retv = 0;
+ else
+ retv = GET_SCRIPT_INT(retval);
+
+ return retv;
+}
+
+void GuiObjectI::guiobject_onMouseMove(int x, int y) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ GuiObject_ScriptMethods::onMouseMove(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y);
+ POINT pos={x,y};
+ guiobject_getRootWnd()->clientToScreen((int *)&pos.x, (int *)&pos.y);
+#ifdef WASABI_COMPILE_WNDMGR
+ if (moving) {
+#ifdef _WIN32
+ if (!Std::keyDown(MK_LBUTTON)) {
+#else
+#warning port me
+ if (0) {
+#endif
+ moving = 0;
+ } else {
+#ifdef WIN32
+ int drag_x = GetSystemMetrics(SM_CXDRAG);
+ int drag_y = GetSystemMetrics(SM_CYDRAG);
+#else
+#warning port me
+ int drag_x = 5;
+ int drag_y = 5;
+#endif
+ POINT relatpos;
+ relatpos.x = (int)((float)x*guiobject_getRootWnd()->getRenderRatio()) - anchor.x;
+ relatpos.y = (int)((float)y*guiobject_getRootWnd()->getRenderRatio()) - anchor.y;
+ if (!dodragcheck || (ABS(relatpos.x) >= drag_x || ABS(relatpos.y) >= drag_y)) {
+ dodragcheck = 0;
+ ifc_window *p = guiobject_getRootWnd()->getDesktopParent();
+ if (p) {
+ RECT r, cr;
+ p->getWindowRect(&r);
+ p->getClientRect(&cr);
+ RECT nr=r;
+ int w,h;
+
+ #ifdef USEAPPBAR
+ int side = APPBAR_NOTDOCKED;
+ if (cfg_options_appbarondrag) {
+ AppBar *ab = reinterpret_cast<AppBar *>(p->getInterface(appBarGuid));
+ if (ab) {
+ int _x=x, _y=y;
+ p->clientToScreen(&_x, &_y);
+ side = ab->appbar_testDock(_x, _y, &nr);
+ if (ABS(p->getRenderRatio() - 1.0) > 0.01f) {
+ int _w = nr.right-nr.left;
+ int _h = nr.bottom-nr.top;
+ double rr = p->getRenderRatio();
+ _w = (int)((double)(_w) / rr + 0.5);
+ _h = (int)((double)(_h) / rr + 0.5);
+ nr.right = nr.left + _w;
+ nr.bottom = nr.top + _h;
+ }
+ }
+ }
+ #endif
+ w = cr.right-cr.left;
+ h = cr.bottom-cr.top;
+ int resize=0;
+#ifdef USEAPPBAR
+ if (cfg_options_appbarondrag) {
+ if (side != m_dock_side) {
+ if (side != APPBAR_NOTDOCKED) {
+ m_lastnondocked_x = r.left;
+ m_lastnondocked_y = r.top;
+ resize=1;
+ } else {
+ RECT rr;
+ p->getRestoredRect(&rr);
+ w = (rr.right-rr.left);
+ h = (rr.bottom-rr.top);
+ if (m_lastnondocked_x != -0xFFFF) {
+ r.left = m_lastnondocked_x;
+ r.top = m_lastnondocked_y;
+ }
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+ snapAdjust(p, &r, -1);
+ nr=r;
+ resize=1;
+ }
+ }
+ }
+#endif
+
+ // use the scaling to adjust the overall size so docking will be correct
+ double rr = p->getRenderRatio();
+ r.left += relatpos.x;
+ r.top += relatpos.y;
+ r.right = r.left + (int)((double)w * rr);
+ r.bottom = r.top + (int)((double)h * rr);
+
+#ifdef USEAPPBAR
+
+ if (side == APPBAR_NOTDOCKED && m_dock_side == APPBAR_NOTDOCKED)
+ WASABI_API_WNDMGR->wndTrackDock(p, &r, &nr, LEFT|TOP|RIGHT|BOTTOM|KEEPSIZE);
+
+ if (side != APPBAR_NOTDOCKED || resize) {
+ Layout *l = (Layout *)p->getInterface(layoutGuid);
+ if (l) l->pushForceUnlink();
+ {
+ RECT adj = nr;
+ snapAdjust(p, &adj, 1);
+ int _w = adj.right-adj.left;
+ int _h = adj.bottom-adj.top;
+ if (ABS(p->getRenderRatio() - 1.0) > 0.01f) {
+ double rr = p->getRenderRatio();
+ if ((int)((double)(_w) * rr) == (int)((double)(w) * rr)) _w = w;
+ if ((int)((double)(_h) * rr) == (int)((double)(h) * rr)) _h = h;
+ }
+ p->resize(adj.left, adj.top, _w, _h);
+ }
+ if (l) l->popForceUnlink();
+ } else {
+ p->move(r.left, r.top);
+ }
+
+ m_dock_side = side;
+ guiobject_getParentLayout()->onMove();
+ if (GetCapture() != guiobject_getRootWnd()->getRootParent()->gethWnd()) {
+ DebugStringW(L"not mine anymore :(\n");
+ }
+#endif
+ }
+ }
+ }
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------
+void GuiObjectI::snapAdjust(ifc_window *rw, RECT *r, int way) {
+ RECT s;
+ Layout *l = static_cast<Layout*>(rw->getInterface(layoutGuid));
+ if (!l) return;
+ l->getSnapAdjust(&s);
+ int h = r->bottom - r->top;
+ int w = r->right - r->left;
+ if (way == 1) {
+ h += s.top + s.bottom;
+ w += s.left + s.right;
+ r->left -= s.left;
+ r->top -= s.top;
+ r->bottom = r->top + h;
+ r->right = r->left + w;
+ } else if (way == -1) {
+ h -= s.top + s.bottom;
+ w -= s.left + s.right;
+ r->left += s.left;
+ r->top += s.top;
+ r->bottom = r->top + h;
+ r->right = r->left + w;
+ }
+}
+
+#ifdef USEAPPBAR
+int GuiObjectI::guiobject_getAppBar() {
+ AppBar *ab = reinterpret_cast<AppBar *>(guiobject_getRootWnd()->getInterface(appBarGuid));
+ if (ab) return ab->appbar_getEnabledSides();
+ return 0;
+}
+
+BEGIN_STRINGDICTIONARY(_appbarvalues)
+SDI(L"top", APPBAR_TOP_ENABLED);
+SDI(L"left", APPBAR_LEFT_ENABLED);
+SDI(L"right", APPBAR_RIGHT_ENABLED);
+SDI(L"bottom", APPBAR_BOTTOM_ENABLED);
+END_STRINGDICTIONARY(_appbarvalues, appbarvalues)
+
+void GuiObjectI::guiobject_setAppBar(int en) {
+ AppBar *ab = reinterpret_cast<AppBar *>(guiobject_getRootWnd()->getInterface(appBarGuid));
+ if (ab) ab->appbar_setEnabledSides(en);
+}
+
+void GuiObjectI::setAppBar(const wchar_t *en)
+{
+ AppBar *ab = reinterpret_cast<AppBar *>(guiobject_getRootWnd()->getInterface(appBarGuid));
+ if (ab) {
+ int e = 0;
+ ParamParser pp(en, L"|;");
+ for (int i=0;i<pp.getNumItems();i++)
+ {
+ const wchar_t *s = pp.enumItem(i);
+ if (!_wcsicmp(s, L"left")) e |= APPBAR_LEFT_ENABLED;
+ else if (!_wcsicmp(s, L"top")) e |= APPBAR_TOP_ENABLED;
+ else if (!_wcsicmp(s, L"right")) e |= APPBAR_RIGHT_ENABLED;
+ else if (!_wcsicmp(s, L"bottom")) e |= APPBAR_BOTTOM_ENABLED;
+ }
+ ab->appbar_setEnabledSides(e);
+ }
+}
+#endif
+
+const wchar_t *GuiObjectI::guiobject_getName()
+{
+ const wchar_t *ret = NULL;
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL)
+ ret = w->getRootWndName();
+ return ret;
+}
+
+void GuiObjectI::guiobject_onEnable(int en) {
+ scriptVar _is = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_is, en);
+ GuiObject_ScriptMethods::onEnable(SCRIPT_CALL, guiobject_getScriptObject(), _is);
+}
+
+void GuiObjectI::guiobject_onStartup() {
+ GuiObject_ScriptMethods::onStartup(SCRIPT_CALL, guiobject_getScriptObject());
+ if (guiobject_getRootObject()) {
+ foreach (notifylist)
+ guiobject_getRootObject()->rootobject_notify(notifylist.getfor()->getValue(), L"", 0, 0);
+ endfor;
+ }
+}
+
+void GuiObjectI::guiobject_onEnterArea() {
+ if (in_area) return;
+ GuiObject_ScriptMethods::onEnterArea(SCRIPT_CALL, guiobject_getScriptObject());
+ in_area = 1;
+}
+
+void GuiObjectI::guiobject_onLeaveArea() {
+ if (!in_area) return;
+ GuiObject_ScriptMethods::onLeaveArea(SCRIPT_CALL, guiobject_getScriptObject());
+ in_area = 0;
+}
+
+void GuiObjectI::guiobject_onCancelCapture() {
+ moving = 0;
+}
+
+ifc_window *GuiObjectI::guiobject_getRootWnd(void) {
+ return my_root_wnd;
+}
+
+void GuiObjectI::guiobject_setRootWnd(ifc_window *r) {
+ my_root_wnd = r;
+}
+
+RootObject *GuiObjectI::guiobject_getRootObject() {
+ ScriptObject *o = guiobject_getScriptObject();
+ if (!o) return NULL;
+ return static_cast<RootObject *>(o->vcpu_getInterface(rootObjectGuid));
+}
+
+void GuiObjectI::guiobject_onResize(int x, int y, int w, int h) {
+ scriptVar _x = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_x, x);
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, y);
+ scriptVar _w = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_w, w);
+ scriptVar _h = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_h, h);
+ GuiObject_ScriptMethods::onResize(SCRIPT_CALL, guiobject_getScriptObject(), _x, _y, _w, _h);
+}
+
+void GuiObjectI::guiobject_onSetVisible(int v) {
+#ifdef WASABI_COMPILE_WNDMGR
+ if (guiobject_getParentLayout())
+ guiobject_getParentLayout()->onGuiObjectSetVisible(this, v);
+#endif
+ scriptVar _v = SOM::makeVar(SCRIPT_BOOLEAN);
+ SOM::assign(&_v, v);
+ GuiObject_ScriptMethods::onSetVisible(SCRIPT_CALL, guiobject_getScriptObject(), _v);
+#ifdef WASABI_COMPILE_WNDMGR
+ if (moving) {
+ if (WASABI_API_WNDMGR->wndTrackWasCooperative())
+ WASABI_API_WNDMGR->wndTrackEndCooperative();
+ moving = 0;
+ ifc_window *dp = guiobject_getRootWnd()->getDesktopParent();
+ if (dp) dp->restore(0);
+ guiobject_getParentGroup()->endMove();
+ }
+#endif //WASABI_COMPILE_WNDMGR
+}
+
+void GuiObjectI::guiobject_setAlpha(int a) {
+ if (!my_root_wnd) return;
+ Layout *l = static_cast<Layout*>(my_root_wnd->getInterface(layoutGuid));
+ if (l) l->setAlpha(a);
+ else my_root_wnd->setAlpha(a);
+}
+
+int GuiObjectI::guiobject_getAlpha() {
+ if (!my_root_wnd) return 255;
+ Layout *l = static_cast<Layout*>(my_root_wnd->getInterface(layoutGuid));
+ if (l) return l->getAlpha();
+ return my_root_wnd->getPaintingAlpha();
+}
+
+void GuiObjectI::guiobject_setActiveAlpha(int a) {
+ if (my_root_wnd) {
+ int i;
+ my_root_wnd->getAlpha(NULL, &i);
+ my_root_wnd->setAlpha(a, i);
+ }
+}
+
+int GuiObjectI::guiobject_getActiveAlpha() {
+ int a = 255;
+ if (my_root_wnd) my_root_wnd->getAlpha(&a);
+ return a;
+}
+
+void GuiObjectI::guiobject_setInactiveAlpha(int a) {
+ if (my_root_wnd) {
+ int _a;
+ my_root_wnd->getAlpha(&_a);
+ my_root_wnd->setAlpha(_a, a);
+ }
+}
+
+int GuiObjectI::guiobject_getInactiveAlpha() {
+ if (my_root_wnd) {
+ int i;
+ my_root_wnd->getAlpha(NULL, &i);
+ return i;
+ }
+ return 255;
+}
+
+void GuiObjectI::guiobject_onTargetReached() {
+ GuiObject_ScriptMethods::onTargetReached(SCRIPT_CALL, guiobject_getScriptObject());
+ Layout *l = static_cast<Layout *>(guiobject_getScriptObject()->vcpu_getInterface(layoutGuid));
+ if (l && redock.l) windowTracker->afterRedock(l, &redock);
+}
+
+void GuiObjectI::guiobject_setAutoSysMetricsX(int a) {
+ if (a == autosysmetricsx) return;
+ autosysmetricsx = a;
+ if (guiobject_getRootWnd() && guiobject_getRootWnd()->isInited())
+ if (guiobject_getParentGroup()) guiobject_getParentGroup()->updatePos(this);
+}
+
+void GuiObjectI::guiobject_setAutoSysMetricsY(int a) {
+ if (a == autosysmetricsy) return;
+ autosysmetricsy = a;
+ if (guiobject_getRootWnd() && guiobject_getRootWnd()->isInited())
+ if (guiobject_getParentGroup()) guiobject_getParentGroup()->updatePos(this);
+}
+
+void GuiObjectI::guiobject_setAutoSysMetricsW(int a) {
+ if (a == autosysmetricsw) return;
+ autosysmetricsw = a;
+ if (guiobject_getRootWnd() && guiobject_getRootWnd()->isInited())
+ if (guiobject_getParentGroup()) guiobject_getParentGroup()->updatePos(this);
+}
+
+void GuiObjectI::guiobject_setAutoSysMetricsH(int a) {
+ if (a == autosysmetricsh) return;
+ autosysmetricsh = a;
+ if (guiobject_getRootWnd() && guiobject_getRootWnd()->isInited())
+ if (guiobject_getParentGroup()) guiobject_getParentGroup()->updatePos(this);
+}
+
+int GuiObjectI::guiobject_getAutoSysMetricsX() {
+ return autosysmetricsx;
+}
+
+int GuiObjectI::guiobject_getAutoSysMetricsY() {
+ return autosysmetricsy;
+}
+
+int GuiObjectI::guiobject_getAutoSysMetricsW() {
+ return autosysmetricsw;
+}
+
+int GuiObjectI::guiobject_getAutoSysMetricsH() {
+ return autosysmetricsh;
+}
+
+int GuiObjectI::guiobject_getAutoWidth() {
+ if (!guiobject_getRootWnd()) return AUTOWH;
+ return guiobject_getRootWnd()->getPreferences(SUGGESTED_W);
+}
+
+int GuiObjectI::guiobject_getAutoHeight() {
+ if (!guiobject_getRootWnd()) return AUTOWH;
+ return guiobject_getRootWnd()->getPreferences(SUGGESTED_H);
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+int GuiObjectI::guiobject_runModal() {
+ if (!guiobject_getRootWnd()) return 0;
+ ifc_window *w = guiobject_getRootWnd()->getDesktopParent();
+ #ifdef WASABI_MODAL_PUSH
+ WASABI_MODAL_PUSH
+ #endif
+ int r = w->runModal();
+ #ifdef WASABI_MODAL_POP
+ WASABI_MODAL_POP
+ #endif
+ return r;
+}
+
+void GuiObjectI::guiobject_endModal(int retcode) {
+ if (!guiobject_getRootWnd()) return;
+ ifc_window *w = guiobject_getRootWnd()->getDesktopParent();
+ w->endModal(retcode);
+}
+#endif
+
+int GuiObjectI::guiobject_isActive() {
+ if (!guiobject_getRootWnd()) return 0;
+ return guiobject_getRootWnd()->isActive();
+}
+
+svc_xuiObject *GuiObjectI::guiobject_getXuiService() {
+ return xuisvc;
+}
+
+void GuiObjectI::guiobject_setXuiService(svc_xuiObject *svc) {
+ xuisvc = svc;
+}
+
+waServiceFactory *GuiObjectI::guiobject_getXuiServiceFactory() {
+ return xuifac;
+}
+void GuiObjectI::guiobject_setXuiServiceFactory(waServiceFactory *fac) {
+ xuifac = fac;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void GuiObjectI::guiobject_setStatusText(const wchar_t *text, int overlay)
+{
+ Layout *l = guiobject_getParentLayout();
+ if (l)
+ l->setStatusText(text, overlay);
+}
+
+void GuiObjectI::guiobject_registerStatusCB(GuiStatusCallback *cb) {
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->registerStatusCallback(cb);
+}
+
+void GuiObjectI::guiobject_addAppCmds(AppCmds *commands){
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->addAppCmds(commands);
+}
+
+void GuiObjectI::guiobject_removeAppCmds(AppCmds *commands){
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->removeAppCmds(commands);
+}
+
+void GuiObjectI::guiobject_pushCompleted(int max) {
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->pushCompleted(max);
+}
+void GuiObjectI::guiobject_incCompleted(int add) {
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->incCompleted(add);
+}
+void GuiObjectI::guiobject_setCompleted(int pos) {
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->setCompleted(pos);
+}
+void GuiObjectI::guiobject_popCompleted() {
+ Layout *l = guiobject_getParentLayout();
+ if (l) l->popCompleted();
+}
+#endif //WASABI_COMPILE_WNDMGR
+
+void GuiObjectI::infoMenu(GuiObject *o, int x, int y)
+{
+ PopupMenu pop;
+ pop.addCommand(StringPrintfW(L"Class : %s", o->guiobject_getScriptObject()->vcpu_getClassName()), 0, 0, 1);
+ pop.addCommand(StringPrintfW(L"Id : %s", o->guiobject_getId()), 0, 0, 1);
+ RECT r;
+ guiobject_getRootWnd()->getNonClientRect(&r);
+ pop.addCommand(StringPrintfW(L"Coordinates : %d,%d (%d x %d)", r.left, r.top, r.right-r.left, r.bottom-r.top), 0, 0, 1);
+ int _x, _y, _w, _h, _rx, _ry, _rw, _rh;
+ guiobject_getGuiPosition(&_x, &_y, &_w, &_h, &_rx, &_ry, &_rw, &_rh);
+ pop.addCommand(StringPrintfW(L"GuiPos : x=%d relatx=%d, y=%d relaty=%d, w=%d relatw=%d, h=%d relath=%d", _x, _rx, _y, _ry, _w, _rw, _h, _rh), 0, 0, 1);
+
+ if (guiobject_wantTranslation() == 2)
+ {
+ if (!_wcsicmp(o->guiobject_getScriptObject()->vcpu_getClassName(), L"Text"))
+ {
+ pop.addCommand(StringPrintfW(L"StringEntry : %s", guiobject_getXmlParam(L"text")), 0, 0, 1);
+ }
+ else if (!_wcsicmp(o->guiobject_getScriptObject()->vcpu_getClassName(), L"TitleBar"))
+ {
+ pop.addCommand(StringPrintfW(L"StringEntry : %s", guiobject_getXmlParam(L"title")), 0, 0, 1);
+ }
+ }
+ guiobject_getRootWnd()->clientToScreen(&x, &y);
+ pop.popAtXY(x, y, 1);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+
+void GuiObjectI::guiobject_setCfgAttrib(CfgItem *item, const wchar_t *name)
+{
+ if (cfgitem) viewer_delViewItem(cfgitem);
+ cfgitem = item;
+ cfgattrname = name;
+ if (cfgitem) {
+ viewer_addViewItem(cfgitem);
+ }
+ ifc_window *mw = guiobject_getRootWnd();
+ if (mw != NULL) {
+ if (mw->isPostOnInit())
+ dataChanged();
+ }
+}
+
+int GuiObjectI::viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen) {
+ if (item == cfgitem)
+ dataChanged();
+ return 1;
+}
+
+void GuiObjectI::dataChanged() {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL) {
+ w->onAction(L"reload_config", NULL, -1, -1, 0, 0, NULL, 0, w);
+ }
+ GuiObject_ScriptMethods::onCfgChanged(SCRIPT_CALL, guiobject_getScriptObject());
+}
+
+
+CfgItem *GuiObjectI::guiobject_getCfgItem() {
+ return cfgitem;
+}
+
+const wchar_t *GuiObjectI::guiobject_getCfgAttrib()
+{
+ return cfgattrname;
+}
+#endif //WASABI_COMPILE_CONFIG
+
+void GuiObjectI::guiobject_onChar(wchar_t c)
+{
+ wchar_t _c[2]=L"X";
+ _c[0]=c;
+ GuiObject_ScriptMethods::onChar(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_STRING(_c));
+}
+
+void GuiObjectI::guiobject_onKeyDown(int vkcode) {
+ GuiObject_ScriptMethods::onKeyDown(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_INT(vkcode));
+}
+
+void GuiObjectI::guiobject_onKeyUp(int vkcode) {
+ GuiObject_ScriptMethods::onKeyUp(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_INT(vkcode));
+}
+
+void GuiObjectI::guiobject_setCursor(const wchar_t *c)
+{
+ ifc_window *w = guiobject_getRootWnd();
+#ifdef _WIN32
+ if (w != NULL) {
+ delete cursor;
+ cursor = new SkinCursor(c);
+ w->setDefaultCursor(cursor);
+ }
+#else
+#warning port me
+#endif
+}
+
+void GuiObjectI::guiobject_setEnabled(int en) {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL) w->setEnabled(en);
+}
+
+int GuiObjectI::guiobject_wantTranslation()
+{
+ return translate;
+}
+int GuiObjectI::guiobject_dragEnter(ifc_window *sourceWnd)
+{
+ GuiObject_ScriptMethods::onDragEnter(SCRIPT_CALL, guiobject_getScriptObject());
+ return 1;
+}
+
+int GuiObjectI::guiobject_dragOver(int x, int y, ifc_window *sourceWnd)
+{
+ GuiObject_ScriptMethods::onDragOver(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ return 1;
+}
+
+int GuiObjectI::guiobject_dragLeave(ifc_window *sourceWnd)
+{
+ GuiObject_ScriptMethods::onDragLeave(SCRIPT_CALL, guiobject_getScriptObject());
+ return 1;
+}
+
+GuiObjectScriptController _guiController;
+GuiObjectScriptController *guiController = &_guiController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GuiObjectScriptController::exportedFunction[] = {
+ {L"getId", 0, (void*)GuiObject_ScriptMethods::getId },
+ {L"show", 0, (void*)GuiObject_ScriptMethods::show },
+ {L"hide", 0, (void*)GuiObject_ScriptMethods::hide },
+ {L"onSetVisible", 1, (void*)GuiObject_ScriptMethods::onSetVisible},
+ {L"isVisible", 0, (void*)GuiObject_ScriptMethods::isvisible },
+ {L"setAlpha", 1, (void*)GuiObject_ScriptMethods::setAlpha },
+ {L"getAlpha", 0, (void*)GuiObject_ScriptMethods::getAlpha },
+ {L"setActiveAlpha", 1, (void*)GuiObject_ScriptMethods::setActiveAlpha },
+ {L"getActiveAlpha", 0, (void*)GuiObject_ScriptMethods::getActiveAlpha },
+ {L"setInactiveAlpha", 1, (void*)GuiObject_ScriptMethods::setInactiveAlpha },
+ {L"getInactiveAlpha", 0, (void*)GuiObject_ScriptMethods::getInactiveAlpha },
+ {L"onLeftButtonDown", 2, (void*)GuiObject_ScriptMethods::onLeftButtonDown },
+ {L"onLeftButtonUp", 2, (void*)GuiObject_ScriptMethods::onLeftButtonUp },
+ {L"onRightButtonDown", 2, (void*)GuiObject_ScriptMethods::onRightButtonDown },
+ {L"onRightButtonUp", 2, (void*)GuiObject_ScriptMethods::onRightButtonUp },
+ {L"onRightButtonDblClk", 2, (void*)GuiObject_ScriptMethods::onRightButtonDblClk },
+ {L"onLeftButtonDblClk", 2, (void*)GuiObject_ScriptMethods::onLeftButtonDblClk },
+ {L"onMouseWheelUp", 2, (void*)GuiObject_ScriptMethods::onMouseWheelUp },
+ {L"onMouseWheelDown", 2, (void*)GuiObject_ScriptMethods::onMouseWheelDown },
+ {L"onMouseMove", 2, (void*)GuiObject_ScriptMethods::onMouseMove },
+ {L"onEnterArea", 0, (void*)GuiObject_ScriptMethods::onEnterArea },
+ {L"onLeaveArea", 0, (void*)GuiObject_ScriptMethods::onLeaveArea },
+ {L"isMouseOverRect", 0, (void*)GuiObject_ScriptMethods::isMouseOverRect},
+ {L"onStartup", 0, (void*)GuiObject_ScriptMethods::onStartup },
+ {L"onChar", 1, (void*)GuiObject_ScriptMethods::onChar },
+ {L"onKeyDown", 1, (void*)GuiObject_ScriptMethods::onKeyDown},
+ {L"onKeyUp", 1, (void*)GuiObject_ScriptMethods::onKeyUp},
+ {L"setEnabled", 1, (void*)GuiObject_ScriptMethods::setEnabled },
+ {L"getEnabled", 0, (void*)GuiObject_ScriptMethods::getEnabled },
+ {L"onEnable", 1, (void*)GuiObject_ScriptMethods::onEnable },
+ {L"resize", 4, (void*)GuiObject_ScriptMethods::resize },
+ {L"onResize", 4, (void*)GuiObject_ScriptMethods::onResize },
+ {L"isMouseOver", 2, (void*)GuiObject_ScriptMethods::isMouseOver },
+ {L"getLeft", 0, (void*)GuiObject_ScriptMethods::getLeft },
+ {L"getTop", 0, (void*)GuiObject_ScriptMethods::getTop },
+ {L"getWidth", 0, (void*)GuiObject_ScriptMethods::getWidth },
+ {L"getHeight", 0, (void*)GuiObject_ScriptMethods::getHeight },
+ {L"getGuiX", 0, (void*)GuiObject_ScriptMethods::getGuiX },
+ {L"getGuiY", 0, (void*)GuiObject_ScriptMethods::getGuiY },
+ {L"getGuiW", 0, (void*)GuiObject_ScriptMethods::getGuiW },
+ {L"getGuiH", 0, (void*)GuiObject_ScriptMethods::getGuiH },
+ {L"getGuiRelatX", 0, (void*)GuiObject_ScriptMethods::getGuiRelatX },
+ {L"getGuiRelatY", 0, (void*)GuiObject_ScriptMethods::getGuiRelatX },
+ {L"getGuiRelatW", 0, (void*)GuiObject_ScriptMethods::getGuiRelatX },
+ {L"getGuiRelatH", 0, (void*)GuiObject_ScriptMethods::getGuiRelatX },
+ {L"clientToScreenX", 1, (void*)GuiObject_ScriptMethods::clientToScreenX },
+ {L"clientToScreenY", 1, (void*)GuiObject_ScriptMethods::clientToScreenY },
+ {L"clientToScreenW", 1, (void*)GuiObject_ScriptMethods::clientToScreenW },
+ {L"clientToScreenH", 1, (void*)GuiObject_ScriptMethods::clientToScreenH },
+ {L"screenToClientX", 1, (void*)GuiObject_ScriptMethods::screenToClientX },
+ {L"screenToClientY", 1, (void*)GuiObject_ScriptMethods::screenToClientY },
+ {L"screenToClientW", 1, (void*)GuiObject_ScriptMethods::screenToClientW },
+ {L"screenToClientH", 1, (void*)GuiObject_ScriptMethods::screenToClientH },
+ {L"setTargetX", 1, (void*)GuiObject_ScriptMethods::setTargetX },
+ {L"setTargetY", 1, (void*)GuiObject_ScriptMethods::setTargetY },
+ {L"setTargetW", 1, (void*)GuiObject_ScriptMethods::setTargetW },
+ {L"setTargetH", 1, (void*)GuiObject_ScriptMethods::setTargetH },
+ {L"setTargetA", 1, (void*)GuiObject_ScriptMethods::setTargetA },
+ {L"setTargetSpeed", 1, (void*)GuiObject_ScriptMethods::setTargetSpeed },
+ {L"gotoTarget", 0, (void*)GuiObject_ScriptMethods::gotoTarget },
+ {L"onTargetReached", 0, (void*)GuiObject_ScriptMethods::onTargetReached },
+ {L"cancelTarget", 0, (void*)GuiObject_ScriptMethods::cancelTarget },
+ {L"reverseTarget", 1, (void*)GuiObject_ScriptMethods::reverseTarget },
+ {L"isGoingToTarget", 0, (void*)GuiObject_ScriptMethods::movingToTarget },
+ {L"setXmlParam", 2, (void*)GuiObject_ScriptMethods::setXmlParam },
+ {L"getXmlParam", 1, (void*)GuiObject_ScriptMethods::getXmlParam },
+ {L"init", 1, (void*)GuiObject_ScriptMethods::init },
+ {L"bringToFront", 0, (void*)GuiObject_ScriptMethods::bringToFront },
+ {L"bringToBack", 0, (void*)GuiObject_ScriptMethods::bringToBack },
+ {L"bringAbove", 1, (void*)GuiObject_ScriptMethods::bringAbove },
+ {L"bringBelow", 1, (void*)GuiObject_ScriptMethods::bringBelow },
+ {L"isActive", 0, (void*)GuiObject_ScriptMethods::isActive},
+ {L"getParent", 0, (void*)GuiObject_ScriptMethods::getParent},
+ {L"getTopParent", 0, (void*)GuiObject_ScriptMethods::getTopParent},
+ {L"getInterface", 1, (void*)GuiObject_ScriptMethods::getInterface},
+ {L"onAction", 7, (void*)GuiObject_ScriptMethods::onAction},
+#ifdef WASABI_COMPILE_WNDMGR
+ {L"getParentLayout", 0, (void*)GuiObject_ScriptMethods::getParentLayout},
+ {L"runModal", 0, (void*)GuiObject_ScriptMethods::runModal},
+ {L"endModal", 1, (void*)GuiObject_ScriptMethods::endModal},
+ {L"popParentLayout", 0, (void*)GuiObject_ScriptMethods::popParentLayout},
+ {L"setStatusText", 2, (void*)GuiObject_ScriptMethods::setStatusText},
+#endif
+ {L"findObject", 1, (void*)GuiObject_ScriptMethods::findObject},
+ {L"findObjectXY", 2, (void*)GuiObject_ScriptMethods::findObjectXY},
+ {L"getName", 0, (void*)GuiObject_ScriptMethods::getName},
+ {L"getAutoWidth", 0, (void*)GuiObject_ScriptMethods::getAutoWidth },
+ {L"getAutoHeight", 0, (void*)GuiObject_ScriptMethods::getAutoHeight },
+ {L"setFocus", 0, (void*)GuiObject_ScriptMethods::setFocus},
+ {L"onGetFocus", 0, (void*)GuiObject_ScriptMethods::onGetFocus},
+ {L"onKillFocus", 0, (void*)GuiObject_ScriptMethods::onKillFocus},
+ {L"sendAction", 6, (void*)GuiObject_ScriptMethods::sendAction},
+ {L"onAccelerator", 1, (void*)GuiObject_ScriptMethods::onAccelerator},
+#ifdef WASABI_COMPILE_CONFIG
+ {L"cfg_getInt", 0, (void*)GuiObject_ScriptMethods::cfgGetInt },
+ {L"cfg_setInt", 1, (void*)GuiObject_ScriptMethods::cfgSetInt },
+ {L"cfg_getFloat", 0, (void*)GuiObject_ScriptMethods::cfgGetFloat },
+ {L"cfg_setFloat", 1, (void*)GuiObject_ScriptMethods::cfgSetFloat },
+ {L"cfg_getString", 0, (void*)GuiObject_ScriptMethods::cfgGetString },
+ {L"cfg_setString", 1, (void*)GuiObject_ScriptMethods::cfgSetString },
+ {L"cfg_onDataChanged", 0, (void*)GuiObject_ScriptMethods::onCfgChanged },
+ {L"cfg_getItemGuid", 0, (void*)GuiObject_ScriptMethods::cfgGetGuid},
+ {L"cfg_getAttributeName", 0, (void*)GuiObject_ScriptMethods::cfgGetAttributeName},
+#endif
+ {L"onDragEnter", 0, (void*)GuiObject_ScriptMethods::onDragEnter },
+ {L"onDragOver", 2, (void*)GuiObject_ScriptMethods::onDragOver},
+ {L"onDragLeave", 0, (void*)GuiObject_ScriptMethods::onDragLeave},
+};
+
+const wchar_t *GuiObjectScriptController::getClassName() {
+ return L"GuiObject";
+}
+
+const wchar_t *GuiObjectScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *GuiObjectScriptController::getAncestorController() {
+ return rootScriptObjectController;}
+
+int GuiObjectScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GuiObjectScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID GuiObjectScriptController::getClassGuid() {
+ return guiObjectGuid;
+}
+
+int GuiObjectScriptController::getInstantiable() {
+ return 1;
+}
+
+ScriptObject *GuiObjectScriptController::instantiate() {
+ GuiObjectWnd *w = new GuiObjectWnd;
+ ASSERT(w != NULL);
+ return w->getScriptObject();
+}
+
+void GuiObjectScriptController::destroy(ScriptObject *o) {
+ GuiObjectWnd *w = static_cast<GuiObjectWnd *>(o->vcpu_getInterface(guiObjectWndGuid));
+ ASSERT(w != NULL);
+ delete w;
+}
+
+void *GuiObjectScriptController::encapsulate(ScriptObject *o) {
+ return static_cast<void *>(new GuiObjectI(o));
+}
+
+void GuiObjectScriptController::deencapsulate(void *o) {
+ delete static_cast<GuiObjectI *>(o);
+}
+
+// ----------------------------------------------------------------------------------------------------------------------------------
+
+// returns a new ScriptString object containing the xml id of this object
+scriptVar GuiObject_ScriptMethods::getId(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+
+ if (g)
+ return MAKE_SCRIPT_STRING(g->guiobject_getId());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar GuiObject_ScriptMethods::hide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w)
+ w->setVisible(0);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::show(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w)
+ w->setVisible(1);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::isvisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w) return MAKE_SCRIPT_BOOLEAN(w->isVisible());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar GuiObject_ScriptMethods::getAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) return MAKE_SCRIPT_INT(g->guiobject_getAlpha());
+ return MAKE_SCRIPT_INT(255);
+}
+
+scriptVar GuiObject_ScriptMethods::setAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setAlpha(GET_SCRIPT_INT(a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::getActiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) return MAKE_SCRIPT_INT(g->guiobject_getActiveAlpha());
+ return MAKE_SCRIPT_INT(255);
+}
+
+scriptVar GuiObject_ScriptMethods::setActiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setActiveAlpha(GET_SCRIPT_INT(a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::getInactiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) return MAKE_SCRIPT_INT(g->guiobject_getInactiveAlpha());
+ return MAKE_SCRIPT_INT(255);
+}
+
+scriptVar GuiObject_ScriptMethods::setInactiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setInactiveAlpha(GET_SCRIPT_INT(a));
+ RETURN_SCRIPT_VOID;
+}
+
+
+scriptVar GuiObject_ScriptMethods::onMouseMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onLeftButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onLeftButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onRightButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onRightButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onLeftButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onRightButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onMouseWheelUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar clicked, scriptVar lines) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, clicked, lines);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, clicked, lines);
+}
+
+scriptVar GuiObject_ScriptMethods::onMouseWheelDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar clicked, scriptVar lines) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, clicked, lines);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, clicked, lines);
+}
+
+scriptVar GuiObject_ScriptMethods::onEnterArea(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::onLeaveArea(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::setEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&v));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *b = g->guiobject_getRootWnd();
+ if (b) b->setEnabled(GET_SCRIPT_BOOLEAN(v));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::getEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *b = g->guiobject_getRootWnd();
+ if (b) return MAKE_SCRIPT_BOOLEAN(b->isEnabled());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar GuiObject_ScriptMethods::onEnable(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, guiController, v);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, v);
+}
+
+scriptVar GuiObject_ScriptMethods::onSetVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, guiController, v);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, v);
+}
+
+scriptVar GuiObject_ScriptMethods::onResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, guiController, x, y, w, h);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, x, y, w, h);
+}
+
+scriptVar GuiObject_ScriptMethods::resize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ ASSERT(SOM::isNumeric(&w));
+ ASSERT(SOM::isNumeric(&h));
+ GuiObject *go = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) {
+ int _x = SOM::makeInt(&x);
+ int _y = SOM::makeInt(&y);
+ int _w = SOM::makeInt(&w);
+ int _h = SOM::makeInt(&h);
+ ifc_window *b = go->guiobject_getRootWnd();
+ if (b) b->resize(_x, _y, _w, _h);
+ go->guiobject_setGuiPosition(_x == NOCHANGE ? &_x : NULL, _y == NOCHANGE ? &_y : NULL, _w == NOCHANGE ? &_w : NULL, _h == NOCHANGE ? &_h : NULL, NULL, NULL, NULL, NULL);
+ if (b && b->getInterface(layoutGuid)) {
+ b->cascadeRepaint();
+ ((Layout *)b->getInterface(layoutGuid))->savePosition();
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::isMouseOver(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *b = g->guiobject_getRootWnd();
+ POINT pt={GET_SCRIPT_INT(x), GET_SCRIPT_INT(y)};
+ b->clientToScreen((int *)&pt.x, (int *)&pt.y);
+ return MAKE_SCRIPT_BOOLEAN(WASABI_API_WND->rootWndFromPoint(&pt) == b);
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar GuiObject_ScriptMethods::getLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ ifc_window *b = go->guiobject_getRootWnd();
+ int r=0;
+ if (b && b->isInited()) {
+ POINT pt;
+ b->getPosition(&pt);
+ r = pt.x;
+ } else if (b && !b->isInited()) {
+ go->guiobject_getGuiPosition(&r, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar GuiObject_ScriptMethods::movingToTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) return MAKE_SCRIPT_BOOLEAN(g->guiobject_movingToTarget());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar GuiObject_ScriptMethods::cancelTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g && g->guiobject_movingToTarget()) g->guiobject_cancelTarget();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::reverseTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_reverseTarget(GET_SCRIPT_INT(r));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::getTop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ ifc_window *b = go->guiobject_getRootWnd();
+ int r=0;
+ if (b && b->isInited()) {
+ POINT pt;
+ b->getPosition(&pt);
+ r = pt.y;
+ } else if (b && !b->isInited()) {
+ go->guiobject_getGuiPosition(NULL, &r, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar GuiObject_ScriptMethods::getWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ ifc_window *b = go->guiobject_getRootWnd();
+ int r=0;
+ if (b && b->isInited()) {
+ RECT rc;
+ b->getClientRect(&rc);
+ r = rc.right-rc.left;
+ } else if (b && !b->isInited()) {
+ go->guiobject_getGuiPosition(NULL, NULL, &r, NULL, NULL, NULL, NULL, NULL);
+ }
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar GuiObject_ScriptMethods::getHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ ifc_window *b = go->guiobject_getRootWnd();
+ int r=0;
+ if (b && b->isInited()) {
+ RECT rc;
+ b->getClientRect(&rc);
+ r = rc.bottom-rc.top;
+ } else if (b && !b->isInited()) {
+ go->guiobject_getGuiPosition(NULL, NULL, NULL, &r, NULL, NULL, NULL, NULL);
+ }
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar GuiObject_ScriptMethods::setTargetX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setTargetX(GET_SCRIPT_INT(x));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setTargetY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&y));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setTargetY(GET_SCRIPT_INT(y));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setTargetW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar w) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&w));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setTargetW(GET_SCRIPT_INT(w));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setTargetH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar h) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&h));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setTargetH(GET_SCRIPT_INT(h));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setTargetA(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&a));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setTargetA(GET_SCRIPT_INT(a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setTargetSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&s));
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setTargetSpeed(GET_SCRIPT_FLOAT(s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::gotoTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_gotoTarget();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::bringToFront(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_bringToFront();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::bringToBack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_bringToBack();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::bringAbove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(obj.data.odata != NULL);
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_bringAbove((static_cast<GuiObject *>(GET_SCRIPT_OBJECT_AS(obj, guiObjectGuid))));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::bringBelow(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(obj.data.odata != NULL);
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_bringBelow((static_cast<GuiObject *>(GET_SCRIPT_OBJECT_AS(obj, guiObjectGuid))));
+ RETURN_SCRIPT_VOID;
+}
+
+
+scriptVar GuiObject_ScriptMethods::onTargetReached(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::setXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar param, scriptVar value)
+{
+ SCRIPT_FUNCTION_INIT;
+ XmlObject *x = static_cast<XmlObject*>(o->vcpu_getInterface(xmlObjectGuid));
+ if (x)
+ x->setXmlParam(GET_SCRIPT_STRING(param), GET_SCRIPT_STRING(value));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::getXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar param) {
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *rt = NULL;
+ XmlObject *x = static_cast<XmlObject*>(o->vcpu_getInterface(xmlObjectGuid));
+ if (x) {
+ int r = x->getXmlParam(GET_SCRIPT_STRING(param));
+ if (r != -1)
+ rt = x->getXmlParamValue(r);
+ }
+ if (rt == NULL)
+ rt = L""; // returning null in a string is kinda bad, y'know?
+
+ return MAKE_SCRIPT_STRING(rt);
+}
+
+scriptVar GuiObject_ScriptMethods::onStartup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(&v, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, &v, NULL, NULL, NULL, NULL, NULL, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, NULL, &v, NULL, NULL, NULL, NULL, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, NULL, NULL, &v, NULL, NULL, NULL, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiRelatX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, NULL, NULL, NULL, &v, NULL, NULL, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiRelatY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, NULL, NULL, NULL, NULL, &v, NULL, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiRelatW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, NULL, NULL, NULL, NULL, NULL, &v, NULL);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getGuiRelatH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_getGuiPosition(NULL, NULL, NULL, NULL, NULL, NULL, NULL, &v);
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::clientToScreenX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ v = GET_SCRIPT_INT(x);
+ w->clientToScreen(&v, NULL);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::clientToScreenY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ v = GET_SCRIPT_INT(y);
+ w->clientToScreen(NULL, &v);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::clientToScreenW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar w) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *wn = g->guiobject_getRootWnd();
+ if (wn != NULL) {
+ v = GET_SCRIPT_INT(w);
+ double rr = wn->getRenderRatio();
+ v = (int)((double)(v) * rr);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::clientToScreenH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar h) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ v = GET_SCRIPT_INT(h);
+ double rr = w->getRenderRatio();
+ v = (int)((double)(v) * rr);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+
+scriptVar GuiObject_ScriptMethods::screenToClientX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ v = GET_SCRIPT_INT(x);
+ w->screenToClient(&v, NULL);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::screenToClientY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ v = GET_SCRIPT_INT(y);
+ w->screenToClient(NULL, &v);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::screenToClientW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar w) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *wn = g->guiobject_getRootWnd();
+ if (wn != NULL) {
+ v = GET_SCRIPT_INT(w);
+ double rr = wn->getRenderRatio();
+ v = (int)((double)(v) / rr);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::screenToClientH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar h) {
+ SCRIPT_FUNCTION_INIT;
+ int v=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ v = GET_SCRIPT_INT(h);
+ double rr = w->getRenderRatio();
+ v = (int)((double)(v) / rr);
+ }
+ }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::isActive(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = (static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid)))->guiobject_getRootWnd();
+ if (w) return MAKE_SCRIPT_INT(w->isActive());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar GuiObject_ScriptMethods::getParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = (static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid)));
+ if (go) {
+ GuiObject *g = go->guiobject_getParent();
+ ScriptObject *so = NULL;
+ if (g != NULL)
+ so = g->guiobject_getScriptObject();
+ return MAKE_SCRIPT_OBJECT(so);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+scriptVar GuiObject_ScriptMethods::getParentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = (static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid)));
+ if (go) {
+ Layout *l = go->guiobject_getParentLayout();
+ return MAKE_SCRIPT_OBJECT(l ? l->getGuiObject()->guiobject_getScriptObject() : NULL);
+ }
+ RETURN_SCRIPT_VOID;
+}
+#endif
+
+scriptVar GuiObject_ScriptMethods::getTopParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = (static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid)));
+ if (go) {
+ GuiObject *l = go->guiobject_getTopParent();
+ return MAKE_SCRIPT_OBJECT(l ? l->guiobject_getScriptObject() : NULL);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::getAutoWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = (static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid)));
+ int v = 0;
+ if (go) { v = go->guiobject_getRootWnd()->getPreferences(SUGGESTED_W); if (v == AUTOWH) v = go->guiobject_getAutoWidth(); }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::getAutoHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *go = (static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid)));
+ int v = 0;
+ if (go) { v = go->guiobject_getRootWnd()->getPreferences(SUGGESTED_H); if (v == AUTOWH) v = go->guiobject_getAutoHeight(); }
+ return MAKE_SCRIPT_INT(v);
+}
+
+scriptVar GuiObject_ScriptMethods::init(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar parentGroup) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(parentGroup.data.odata != NULL);
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ Group *pg = static_cast<Group *>(GET_SCRIPT_OBJECT_AS(parentGroup, groupGuid));
+ pg->addChild(g);
+ if (!g->guiobject_getRootWnd()->isInited())
+ g->guiobject_getRootWnd()->init(pg);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+scriptVar GuiObject_ScriptMethods::runModal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int r=0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) r = g->guiobject_runModal();
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar GuiObject_ScriptMethods::endModal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar retcode) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_endModal(GET_SCRIPT_INT(retcode));
+ RETURN_SCRIPT_VOID;
+}
+#endif
+
+scriptVar GuiObject_ScriptMethods::setFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) {
+ ifc_window *w = g->guiobject_getRootWnd();
+ if (w != NULL) {
+ w->setFocus();
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+scriptVar GuiObject_ScriptMethods::popParentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_popParentLayout();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setStatusText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text, scriptVar overlay) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g)
+ g->guiobject_setStatusText(GET_SCRIPT_STRING(text), GET_SCRIPT_INT(overlay));
+ RETURN_SCRIPT_VOID;
+}
+#endif
+
+scriptVar GuiObject_ScriptMethods::findObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ ScriptObject *s = NULL;
+ if (g) {
+ GuiObject *o = g->guiobject_findObject(GET_SCRIPT_STRING(id));
+ if (o != NULL) s = o->guiobject_getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar GuiObject_ScriptMethods::findObjectXY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ ScriptObject *s = NULL;
+ if (g) {
+ GuiObject *o = g->guiobject_findObjectXY(GET_SCRIPT_INT(x), GET_SCRIPT_INT(y));
+ if (o != NULL) s = o->guiobject_getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar GuiObject_ScriptMethods::getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g)
+ return MAKE_SCRIPT_STRING(g->guiobject_getName());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar GuiObject_ScriptMethods::getMover(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int r = 0;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) r = g->guiobject_getMover();
+ return MAKE_SCRIPT_INT(r);
+}
+
+scriptVar GuiObject_ScriptMethods::setMover(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i) {
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ if (g) g->guiobject_setMover(GET_SCRIPT_INT(i));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::setDropTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar targ) {
+ GuiObject *g = static_cast<GuiObject*>(o->vcpu_getInterface(guiObjectGuid));
+ const wchar_t *s = GET_SCRIPT_STRING(targ);
+ if (g)
+ g->guiobject_setDropTarget(s);
+ RETURN_SCRIPT_VOID;
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+scriptVar GuiObject_ScriptMethods::cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) return MAKE_SCRIPT_INT(go->guiobject_getCfgInt());
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar GuiObject_ScriptMethods::cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&v));
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) go->guiobject_setCfgInt(GET_SCRIPT_INT(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+
+ if (go)
+ return MAKE_SCRIPT_STRING(go->guiobject_getCfgString());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar GuiObject_ScriptMethods::cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) go->guiobject_setCfgString(GET_SCRIPT_STRING(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) return MAKE_SCRIPT_FLOAT(go->guiobject_getCfgFloat());
+ return MAKE_SCRIPT_FLOAT(0);
+}
+
+scriptVar GuiObject_ScriptMethods::cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) go->guiobject_setCfgFloat(GET_SCRIPT_FLOAT(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ if (go) {
+ CfgItem *i = go->guiobject_getCfgItem();
+ if (i != NULL)
+ {
+ GUID guid = i->getGuid();
+ nsGUID::toCharW(guid, txt);
+ return MAKE_SCRIPT_STRING(txt);
+ }
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar GuiObject_ScriptMethods::cfgGetAttributeName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+
+ if (go)
+ return MAKE_SCRIPT_STRING(go->guiobject_getCfgAttrib());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+#endif
+
+scriptVar GuiObject_ScriptMethods::isMouseOverRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ int r = 0;
+ if (go) {
+ ifc_window *w = go->guiobject_getRootWnd();
+ if (w != NULL) {
+ RECT rc;
+ int x, y;
+ w->getWindowRect(&rc);
+ Wasabi::Std::getMousePos(&x, &y);
+ if (x >= rc.left && x <= rc.right && y >= rc.top && y <= rc.bottom) r = 1;
+ }
+ }
+ return MAKE_SCRIPT_BOOLEAN(r);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+scriptVar GuiObject_ScriptMethods::onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+#endif
+
+scriptVar GuiObject_ScriptMethods::onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, guiController, c);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, c);
+}
+
+scriptVar GuiObject_ScriptMethods::onKeyDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, guiController, c);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, c);
+}
+
+scriptVar GuiObject_ScriptMethods::onKeyUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, guiController, c);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, c);
+}
+
+scriptVar GuiObject_ScriptMethods::onGetFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::onKillFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::sendAction(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar action, scriptVar param, scriptVar x, scriptVar y, scriptVar p1, scriptVar p2) {
+ SCRIPT_FUNCTION_INIT
+ GuiObject *go = static_cast<GuiObject *>(o->vcpu_getInterface(guiObjectGuid));
+ int a = 0;
+ if (go) {
+ ifc_window *w = go->guiobject_getRootWnd();
+ if (w!=NULL) {
+ a = w->onAction(GET_SCRIPT_STRING(action), GET_SCRIPT_STRING(param), GET_SCRIPT_INT(x), GET_SCRIPT_INT(y), GET_SCRIPT_INT(p1), GET_SCRIPT_INT(p2));
+ }
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+scriptVar GuiObject_ScriptMethods::onAccelerator(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar accel) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, guiController, accel);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, accel);
+}
+
+scriptVar GuiObject_ScriptMethods::onAction(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar action, scriptVar param, scriptVar x, scriptVar y, scriptVar p1, scriptVar p2, scriptVar source) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS7(o, guiController, action, param, x, y, p1, p2, source);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT7(o, action, param, x, y, p1, p2, source);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+int GuiObjectI::guiobject_getCfgInt()
+{
+ if (!cfgitem)
+ return 0;
+ return
+ cfgitem->getDataAsInt(cfgattrname);
+}
+
+void GuiObjectI::guiobject_setCfgInt(int i) {
+ if (!cfgitem) return;
+ cfgitem->setDataAsInt(cfgattrname, i);
+}
+
+float GuiObjectI::guiobject_getCfgFloat() {
+ if (!cfgitem) return 0;
+ return (float)cfgitem->getDataAsFloat(cfgattrname);
+}
+
+void GuiObjectI::guiobject_setCfgFloat(float f) {
+ if (!cfgitem) return;
+ cfgitem->setDataAsFloat(cfgattrname, f);
+}
+
+const wchar_t *GuiObjectI::guiobject_getCfgString()
+{
+ static StringW blah;
+ if (!cfgitem) return 0;
+ cfgitem->getData(cfgattrname, txt, 4096);
+ return txt;
+}
+
+void GuiObjectI::guiobject_setCfgString(const wchar_t *s)
+{
+ if (!cfgitem)
+ return;
+ cfgitem->setData(cfgattrname, s);
+}
+
+void GuiObjectI::setCfgAttr(const wchar_t *strvalue)
+{
+ ParamParser pp(strvalue);
+ if (pp.getNumItems() < 2) return;
+
+ GUID g = nsGUID::fromCharW(pp.enumItem(0));
+ if (g == INVALID_GUID) return;
+ CfgItem *i = WASABI_API_CONFIG->config_getCfgItemByGuid(g);
+ if (i == NULL) return;
+ cfgattrname = pp.enumItem(1);
+ guiobject_setCfgAttrib(i, cfgattrname);
+}
+
+int GuiObjectI::guiobject_hasCfgAttrib() {
+ return (guiobject_getCfgItem() && guiobject_getCfgAttrib());
+}
+#endif
+
+GuiObject *GuiObjectI::guiobject_findObject(const wchar_t *id)
+{
+ ifc_window *me = guiobject_getRootWnd();
+ ifc_window *w = me->findWindow(id);
+ if (w != NULL) return w->getGuiObject();
+ return NULL;
+}
+
+GuiObject *GuiObjectI::guiobject_findObjectXY(int x, int y) {
+ ifc_window *me = guiobject_getRootWnd();
+ POINT pt={x,y};
+ me->clientToScreen((int *)&pt.x, (int *)&pt.y);
+ ifc_window *w = WASABI_API_WND->rootWndFromPoint(&pt);
+ if (w != NULL) return w->getGuiObject();
+ return NULL;
+}
+
+GuiObject *GuiObjectI::guiobject_findObjectByInterface(GUID interface_guid) {
+ ifc_window *me = guiobject_getRootWnd();
+ ifc_window *w = me->findWindowByInterface(interface_guid);
+ if (w != NULL) return w->getGuiObject();
+ return NULL;
+}
+
+GuiObject *GuiObjectI::guiobject_findObjectByCallback(FindObjectCallback *cb) {
+ ifc_window *me = guiobject_getRootWnd();
+ ifc_window *w = me->findWindowByCallback(cb);
+ if (w != NULL) return w->getGuiObject();
+ return NULL;
+}
+
+void GuiObjectI::guiobject_onAccelerator(const wchar_t *accel)
+{
+ GuiObject_ScriptMethods::onAccelerator(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_STRING(accel));
+}
+
+int GuiObjectI::guiobject_onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ GuiObject *gsourceobj = (source == NULL) ? NULL : source->getGuiObject();
+ ScriptObject *sourceobj = (gsourceobj == NULL) ? NULL : gsourceobj->guiobject_getScriptObject();
+ GuiObject_ScriptMethods::onAction(SCRIPT_CALL, guiobject_getScriptObject(), MAKE_SCRIPT_STRING(action), MAKE_SCRIPT_STRING(param), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y), MAKE_SCRIPT_INT(p1), MAKE_SCRIPT_INT(p2), MAKE_SCRIPT_OBJECT(sourceobj));
+ return 1;
+}
+
+void GuiObjectI::guiobject_setTabOrder(int a) {
+ ifc_window *me = guiobject_getRootWnd();
+ me->setTabOrder(a);
+}
+
+void GuiObjectI::guiobject_onInit() {
+ // api_window *me = guiobject_getRootWnd();
+ // nothing to do here anymore, for now
+ return;
+}
+
+int GuiObjectI::guiobject_wantFocus() {
+ return wantfocus;
+}
+
+void GuiObjectI::guiobject_setNoDoubleClick(int no) {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL)
+ w->setNoDoubleClicks(no);
+}
+
+void GuiObjectI::guiobject_setNoLeftClick(int no) {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL)
+ w->setNoLeftClicks(no);
+}
+
+void GuiObjectI::guiobject_setNoRightClick(int no) {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL)
+ w->setNoRightClicks(no);
+}
+
+void GuiObjectI::guiobject_setNoMouseMove(int no) {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL)
+ w->setNoMouseMoves(no);
+}
+
+void GuiObjectI::guiobject_setNoContextMenu(int no) {
+ ifc_window *w = guiobject_getRootWnd();
+ if (w != NULL)
+ w->setNoContextMenus(no);
+}
+
+scriptVar GuiObject_ScriptMethods::getInterface(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar guid) {
+ SCRIPT_FUNCTION_INIT;
+ int type=-1;
+ GUID _g = nsGUID::fromCharW(GET_SCRIPT_STRING(guid));
+ void *i = o->vcpu_getInterface(_g, &type);
+ if (i != NULL && type == INTERFACE_SCRIPTOBJECT) {
+ return MAKE_SCRIPT_OBJECT(reinterpret_cast<ScriptObject*>(i));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GuiObject_ScriptMethods::onDragEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar GuiObject_ScriptMethods::onDragOver(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, guiController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+scriptVar GuiObject_ScriptMethods::onDragLeave(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, guiController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
diff --git a/Src/Wasabi/api/script/objects/guiobj.h b/Src/Wasabi/api/script/objects/guiobj.h
new file mode 100644
index 00000000..7997299d
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/guiobj.h
@@ -0,0 +1,423 @@
+#ifndef __GUIOBJ_H
+#define __GUIOBJ_H
+
+#include <api/timer/timerclient.h>
+#include <api/wnd/api_window.h>
+#include <bfc/string/StringW.h>
+#include <bfc/depview.h>
+#include <api/skin/xmlobject.h>
+#include <api/script/objects/guiobjectx.h>
+#include <api/config/items/cfgitem.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objcontroller.h>
+
+class Layout;
+class FindObjectCallback;
+class ScriptObject;
+class SkinCursor;
+
+#ifndef _REDOCK_STRUCT_DEFINED
+#define _REDOCK_STRUCT_DEFINED
+typedef struct
+{
+ Layout *l;
+ RECT original_rect;
+}
+redock_struct;
+#endif
+
+class GuiObjectScriptController : public ScriptObjectControllerI
+{
+public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual int getInstantiable();
+
+private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern GuiObjectScriptController *guiController;
+
+#define GUIOBJECT_SCRIPTPARENT RootObject
+
+#define TARGET_FROZEN 0
+#define TARGET_RUNNING 1
+#define TARGETTIMER_ID 0x1879
+
+#define ANCHOR_NONE 0
+#define ANCHOR_LEFT 1
+#define ANCHOR_TOP 2
+#define ANCHOR_RIGHT 4
+#define ANCHOR_BOTTOM 8
+
+class GuiObjectI;
+
+class GuiObjectTimer : public TimerClientDI
+{
+public:
+ GuiObjectTimer() { obj = NULL; }
+ virtual ~GuiObjectTimer() { }
+
+public:
+ virtual void timerclient_timerCallback(int id);
+ virtual void setGuiObjectI(GuiObjectI *o) { obj = o; }
+
+private:
+ GuiObjectI *obj;
+};
+
+class GuiObjectI : public GuiObjectX, public DependentViewerTPtr<CfgItem>
+{
+public:
+ GuiObjectI(ScriptObject *o);
+ virtual ~GuiObjectI();
+
+ virtual ifc_window *guiobject_getRootWnd();
+ virtual void guiobject_setRootWnd(ifc_window *w);
+ virtual void guiobject_onInit();
+
+ virtual void guiobject_getGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh);
+ virtual void guiobject_setGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh);
+ virtual int guiobject_getAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor);
+ virtual void guiobject_setAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor);
+ virtual void guiobject_validateAnchorage();
+
+ virtual void guiobject_setParentGroup(Group *g);
+ virtual ScriptObject *guiobject_getScriptObject();
+ virtual RootObject *guiobject_getRootObject();
+ virtual Group *guiobject_getParentGroup();
+ virtual GuiObject *guiobject_getParent();
+ virtual void guiobject_setTabOrder(int a);
+
+ virtual void guiobject_setId(const wchar_t *id);
+ virtual const wchar_t *guiobject_getId();
+
+ virtual void guiobject_setTargetX(int tx);
+ virtual void guiobject_setTargetY(int ty);
+ virtual void guiobject_setTargetW(int tw);
+ virtual void guiobject_setTargetH(int th);
+ virtual void guiobject_setTargetA(int th);
+ virtual void guiobject_setTargetSpeed(float s);
+ virtual void guiobject_gotoTarget(void);
+ virtual void guiobject_cancelTarget();
+ virtual void guiobject_reverseTarget(int reverse);
+
+ virtual int guiobject_getAutoWidth();
+ virtual int guiobject_getAutoHeight();
+ virtual int guiobject_movingToTarget();
+
+ virtual void guiobject_bringToFront();
+ virtual void guiobject_bringToBack();
+ virtual void guiobject_bringAbove(GuiObject *o);
+ virtual void guiobject_bringBelow(GuiObject *o);
+
+ virtual void guiobject_setClickThrough(int ct);
+ virtual int guiobject_isClickThrough();
+
+ virtual void guiobject_setAutoSysMetricsX(int a);
+ virtual void guiobject_setAutoSysMetricsY(int a);
+ virtual void guiobject_setAutoSysMetricsW(int a);
+ virtual void guiobject_setAutoSysMetricsH(int a);
+ virtual int guiobject_getAutoSysMetricsX();
+ virtual int guiobject_getAutoSysMetricsY();
+ virtual int guiobject_getAutoSysMetricsW();
+ virtual int guiobject_getAutoSysMetricsH();
+
+ virtual int guiobject_getRegionOp();
+ virtual void guiobject_setRegionOp(int op);
+ virtual int guiobject_isRectRgn();
+ virtual void guiobject_setRectRgn(int rrgn);
+
+ virtual void guiobject_onLeftButtonDown(int x, int y);
+ virtual void guiobject_onLeftButtonUp(int x, int y);
+ virtual void guiobject_onRightButtonDown(int x, int y);
+ virtual void guiobject_onRightButtonUp(int x, int y);
+ virtual void guiobject_onLeftButtonDblClk(int x, int y);
+ virtual void guiobject_onRightButtonDblClk(int x, int y);
+ virtual int guiobject_onMouseWheelUp(int click, int lines);
+ virtual int guiobject_onMouseWheelDown(int click, int lines);
+ virtual void guiobject_onMouseMove(int x, int y);
+ virtual void guiobject_onEnterArea();
+ virtual void guiobject_onLeaveArea();
+ virtual void guiobject_onEnable(int en);
+ virtual void guiobject_setEnabled(int en);
+ virtual void guiobject_onResize(int x, int y, int w, int h);
+ virtual void guiobject_onSetVisible(int v);
+ virtual void guiobject_onTargetReached();
+ virtual void guiobject_setAlpha(int a);
+ virtual void guiobject_setActiveAlpha(int a);
+ virtual void guiobject_setInactiveAlpha(int a);
+ virtual int guiobject_getAlpha();
+ virtual int guiobject_getActiveAlpha();
+ virtual int guiobject_getInactiveAlpha();
+ virtual int guiobject_isActive();
+ virtual void guiobject_onStartup();
+ virtual int guiobject_setXmlParam(const wchar_t *param, const wchar_t *value);
+ virtual const wchar_t *guiobject_getXmlParam(const wchar_t *param);
+ virtual int guiobject_setXmlParamById(int id, const wchar_t *value);
+ virtual svc_xuiObject *guiobject_getXuiService();
+ virtual void guiobject_setXuiService(svc_xuiObject *svc);
+ virtual waServiceFactory *guiobject_getXuiServiceFactory();
+ virtual void guiobject_setXuiServiceFactory(waServiceFactory *fac);
+ virtual GuiObject *guiobject_getTopParent();
+ virtual Layout *guiobject_getParentLayout();
+ virtual int guiobject_runModal();
+ virtual void guiobject_endModal(int retcode);
+ virtual void guiobject_popParentLayout();
+ virtual void guiobject_registerStatusCB(GuiStatusCallback *cb);
+ virtual void guiobject_setStatusText(const wchar_t *txt, int overlay = FALSE);
+ virtual void guiobject_addAppCmds(AppCmds *commands);
+ virtual void guiobject_removeAppCmds(AppCmds *commands);
+ virtual void guiobject_pushCompleted(int max = 100);
+ virtual void guiobject_incCompleted(int add = 1);
+ virtual void guiobject_setCompleted(int pos);
+ virtual void guiobject_popCompleted();
+ virtual GuiObject *guiobject_findObject(const wchar_t *id);
+ virtual GuiObject *guiobject_findObjectXY(int x, int y); // in client coordinates relative to this object
+ virtual GuiObject *guiobject_findObjectByInterface(GUID interface_guid);
+ virtual GuiObject *guiobject_findObjectByCallback(FindObjectCallback *cb);
+ virtual void guiobject_setMover(int m);
+ virtual int guiobject_getMover();
+ virtual void guiobject_onCancelCapture();
+ virtual void guiobject_onChar(wchar_t c);
+ virtual void guiobject_onKeyDown(int vkcode);
+ virtual void guiobject_onKeyUp(int vkcode);
+
+ virtual FOURCC guiobject_getDropTarget();
+ virtual void guiobject_setDropTarget(const wchar_t *strval);
+
+ virtual void onTargetTimer();
+#ifdef USEAPPBAR
+ virtual int guiobject_getAppBar();
+ virtual void guiobject_setAppBar(int en);
+ virtual void setAppBar(const wchar_t *en);
+#endif
+
+ virtual void guiobject_setCfgAttrib(CfgItem *item, const wchar_t *name);
+
+ virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual CfgItem *guiobject_getCfgItem();
+ const wchar_t *guiobject_getCfgAttrib();
+
+ virtual int guiobject_getCfgInt();
+ virtual void guiobject_setCfgInt(int i);
+ virtual float guiobject_getCfgFloat();
+ virtual void guiobject_setCfgFloat(float f);
+ virtual const wchar_t *guiobject_getCfgString();
+ virtual void guiobject_setCfgString(const wchar_t *s);
+ virtual int guiobject_hasCfgAttrib();
+
+ virtual const wchar_t *guiobject_getName();
+ virtual void guiobject_onAccelerator(const wchar_t *accel);
+ virtual int guiobject_onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ virtual int guiobject_wantFocus();
+ virtual void guiobject_setNoDoubleClick(int no);
+ virtual void guiobject_setNoLeftClick(int no);
+ virtual void guiobject_setNoRightClick(int no);
+ virtual void guiobject_setNoMouseMove(int no);
+ virtual void guiobject_setNoContextMenu(int no);
+
+ virtual void guiobject_setCursor(const wchar_t *c);
+
+ virtual int guiobject_wantTranslation();
+
+ virtual int guiobject_dragEnter(ifc_window *sourceWnd);
+ virtual int guiobject_dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual int guiobject_dragLeave(ifc_window *sourceWnd);
+
+private:
+ void setCfgAttr(const wchar_t *strvalue);
+ virtual void dataChanged();
+
+ void snapAdjust(ifc_window *w, RECT *r, int way);
+ void infoMenu(GuiObject *o, int x, int y);
+
+ int targetx, targety, targetw, targeth, targeta, targetspeed;
+ int start_time;
+ int targetstatus;
+
+ void startTargetTimer();
+ void stopTargetTimer();
+ void ensureTimerOk();
+
+ int autosysmetricsx, autosysmetricsy, autosysmetricsw, autosysmetricsh;
+
+ int startx, starty, startw, starth, starta;
+
+ int in_area;
+ StringW guiobject_id;
+ int clickthrough;
+ StringW autonotify;
+ ifc_window *my_root_wnd;
+ ScriptObject *my_script_object;
+ GuiObjectTimer timer;
+
+ int gui_x;
+ int gui_y;
+ int gui_w;
+ int gui_h;
+ int gui_rx;
+ int gui_ry;
+ int gui_rw;
+ int gui_rh;
+ int mover, moving;
+ FOURCC droptarget;
+ Group *p_group;
+ POINT anchor;
+ svc_xuiObject *xuisvc;
+ waServiceFactory *xuifac;
+ PtrList<StringW> notifylist;
+ int wantfocus;
+ int anchor_x1, anchor_y1, anchor_x2, anchor_y2, anchorage, anchorage_invalidated;
+ int reversetarget;
+ SkinCursor *cursor;
+ redock_struct redock;
+ int dodragcheck;
+ int m_lastnondocked_x, m_lastnondocked_y;
+#ifdef USEAPPBAR
+ int m_dock_side;
+ int m_initial_dock_side;
+#endif
+ StringW cfgattrname;
+ StringW cfgguid;
+ CfgItem *cfgitem;
+ int translate;
+};
+
+
+
+
+class GuiObject_ScriptMethods
+{
+public:
+
+ static scriptVar getId(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar show(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar hide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar isvisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar getActiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setActiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar getInactiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setInactiveAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar resize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h);
+ static scriptVar onResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h);
+ static scriptVar init(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar parentGroup);
+ static scriptVar bringToFront(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar bringToBack(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar bringAbove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar bringBelow(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar getIdVar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onLeftButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onLeftButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onRightButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onRightButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onRightButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onLeftButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onMouseWheelUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar clicked, scriptVar lines);
+ static scriptVar onMouseWheelDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar clicked, scriptVar lines);
+ static scriptVar onMouseMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onEnterArea(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onLeaveArea(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c);
+ static scriptVar onKeyDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c);
+ static scriptVar onKeyUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c);
+ static scriptVar setEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar getEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onEnable(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar isMouseOver(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar getLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getTop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setTargetX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar setTargetY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar setTargetW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar setTargetH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar setTargetA(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar setTargetSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar gotoTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onTargetReached(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar cancelTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar reverseTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar movingToTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar param, scriptVar value);
+ static scriptVar getXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar param);
+ static scriptVar onSetVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar onStartup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiRelatX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiRelatY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiRelatW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getGuiRelatH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar isActive(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getTopParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getParentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar runModal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar endModal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar retcode);
+ static scriptVar popParentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setStatusText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text, scriptVar overlay);
+ static scriptVar findObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id);
+ static scriptVar findObjectXY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getMover(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setMover(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar is);
+ static scriptVar setDropTarget(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar targ);
+
+ static scriptVar onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar cfgGetAttributeName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static scriptVar clientToScreenX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x);
+ static scriptVar clientToScreenY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y);
+ static scriptVar clientToScreenW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x);
+ static scriptVar clientToScreenH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y);
+ static scriptVar screenToClientX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x);
+ static scriptVar screenToClientY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y);
+ static scriptVar screenToClientW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x);
+ static scriptVar screenToClientH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar y);
+ static scriptVar getAutoWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getAutoHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onGetFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onKillFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onAccelerator(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar accel);
+ static scriptVar sendAction(SCRIPT_FUNCTION_PARAMS, ScriptObject *obj, scriptVar action, scriptVar param, scriptVar x, scriptVar y, scriptVar p1, scriptVar p2);
+ static scriptVar onAction(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar action, scriptVar param, scriptVar x, scriptVar y, scriptVar p1, scriptVar p2, scriptVar source);
+ static scriptVar isMouseOverRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar getInterface(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar interfaceguid);
+ static scriptVar onDragEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onDragOver(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar onDragLeave(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+extern const wchar_t guiobjectXuiStr[];
+extern char guiobjectXuiSvcName[];
+class GuiObjectXuiSvc : public XuiObjectSvc<GuiObjectWnd, guiobjectXuiStr, guiobjectXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/guiobject.h b/Src/Wasabi/api/script/objects/guiobject.h
new file mode 100644
index 00000000..f4cccfa2
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/guiobject.h
@@ -0,0 +1,855 @@
+#ifndef __GUIOBJECT_H
+#define __GUIOBJECT_H
+
+#include <bfc/dispatch.h>
+#include <bfc/nsguid.h>
+#include <api/service/waservicefactory.h>
+
+class ifc_window;
+class ScriptObject; // scriptobj.h
+class GuiObject; // this file
+class RootObject; // rootobj.h
+class svc_xuiObject; // studio/services/svc_xuiobject.h
+class GuiStatusCallback;
+class AppCmds;
+class CfgItem;
+class FindObjectCallback;
+
+class Group;
+class Layout;
+
+class GuiObject : public Dispatchable
+{
+public:
+
+ ifc_window *guiobject_getRootWnd();
+ void guiobject_setRootWnd(ifc_window *w);
+ void guiobject_onInit();
+
+ void guiobject_getGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh);
+ void guiobject_setGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh);
+ int guiobject_getAnchoragePosition(int *x1, int *x2, int *y1, int *y2, int *anchor); // returns anchor invalidation flag
+ void guiobject_setAnchoragePosition(int *x1, int *x2, int *y1, int *y2, int *anchor);
+ void guiobject_validateAnchorage(); // clears up anchor invalidation flag
+ void guiobject_setParentGroup(Group *l);
+ ScriptObject *guiobject_getScriptObject();
+ RootObject *guiobject_getRootObject();
+ Group *guiobject_getParentGroup();
+ GuiObject *guiobject_getParent();
+ Layout *guiobject_getParentLayout();
+
+ int guiobject_wantAutoContextMenu();
+
+ void guiobject_setId(const wchar_t *id);
+ const wchar_t *guiobject_getId();
+
+ void guiobject_setTargetX(int tx);
+ void guiobject_setTargetY(int ty);
+ void guiobject_setTargetW(int tw);
+ void guiobject_setTargetH(int th);
+ void guiobject_setTargetA(int th);
+ void guiobject_setTargetSpeed(float s);
+ void guiobject_gotoTarget(void);
+ void guiobject_cancelTarget();
+ void guiobject_reverseTarget(int reverse);
+
+ int guiobject_getAutoWidth();
+ int guiobject_getAutoHeight();
+ int guiobject_movingToTarget();
+
+ void guiobject_bringToFront();
+ void guiobject_bringToBack();
+ void guiobject_bringAbove(GuiObject *o);
+ void guiobject_bringBelow(GuiObject *o);
+
+ void guiobject_setClickThrough(int ct);
+ int guiobject_isClickThrough();
+
+ void guiobject_setAutoSysMetricsX(int a);
+ void guiobject_setAutoSysMetricsY(int a);
+ void guiobject_setAutoSysMetricsW(int a);
+ void guiobject_setAutoSysMetricsH(int a);
+ int guiobject_getAutoSysMetricsX();
+ int guiobject_getAutoSysMetricsY();
+ int guiobject_getAutoSysMetricsW();
+ int guiobject_getAutoSysMetricsH();
+
+ void guiobject_setRegionOp(int op);
+ int guiobject_getRegionOp();
+ void guiobject_setRectRgn(int rrgn);
+ int guiobject_isRectRgn();
+
+ void guiobject_setMover(int mover);
+ int guiobject_getMover();
+
+ FOURCC guiobject_getDropTarget();
+ void guiobject_setDropTarget(const wchar_t *target);
+
+ void guiobject_onLeftButtonDown(int x, int y);
+ void guiobject_onLeftButtonUp(int x, int y);
+ void guiobject_onRightButtonDown(int x, int y);
+ void guiobject_onRightButtonUp(int x, int y);
+ void guiobject_onLeftButtonDblClk(int x, int y);
+ void guiobject_onRightButtonDblClk(int x, int y);
+ void guiobject_onMouseMove(int x, int y);
+ int guiobject_onMouseWheelUp(int click, int lines); // Need to return 1 if handled
+ int guiobject_onMouseWheelDown(int click, int lines); // Need to return 1 if handled
+ void guiobject_onEnterArea();
+ void guiobject_onLeaveArea();
+ void guiobject_onCancelCapture();
+ void guiobject_setEnabled(int en);
+ void guiobject_onEnable(int en);
+ void guiobject_onResize(int x, int y, int w, int h);
+ void guiobject_onSetVisible(int v);
+ void guiobject_onTargetReached();
+ void guiobject_setAlpha(int a);
+ int guiobject_getAlpha();
+ void guiobject_setActiveAlpha(int a);
+ int guiobject_getActiveAlpha();
+ void guiobject_setInactiveAlpha(int a);
+ int guiobject_getInactiveAlpha();
+ void guiobject_onStartup();
+ const wchar_t *guiobject_getXmlParam(const wchar_t *param);
+ int guiobject_setXmlParam(const wchar_t *param, const wchar_t *value);
+ int guiobject_setXmlParamById(int id, const wchar_t *value);
+ GuiObject *guiobject_getTopParent();
+#ifdef WASABI_COMPILE_WNDMGR
+ int guiobject_runModal();
+ void guiobject_endModal(int retcode);
+ void guiobject_popParentLayout();
+ void guiobject_registerStatusCB(GuiStatusCallback *cb);
+ void guiobject_setStatusText(const wchar_t *text, int overlay=FALSE);
+ void guiobject_addAppCmds(AppCmds *commands);
+ void guiobject_removeAppCmds(AppCmds *commands);
+ void guiobject_pushCompleted(int max=100);
+ void guiobject_incCompleted(int add=1);
+ void guiobject_setCompleted(int pos);
+ void guiobject_popCompleted();
+#endif
+
+ void guiobject_onChar(wchar_t c);
+ void guiobject_onKeyDown(int vkcode);
+ void guiobject_onKeyUp(int vkcode);
+
+ svc_xuiObject *guiobject_getXuiService();
+ void guiobject_setXuiService(svc_xuiObject *svc);
+ waServiceFactory *guiobject_getXuiServiceFactory();
+ void guiobject_setXuiServiceFactory(waServiceFactory *fac);
+ GuiObject *guiobject_findObject(const wchar_t *id);
+ GuiObject *guiobject_findObjectXY(int x, int y);
+ GuiObject *guiobject_findObjectByInterface(GUID interface_guid);
+ GuiObject *guiobject_findObjectByCallback(FindObjectCallback *cb);
+ GuiObject *guiobject_findObjectChain(FindObjectCallback *cb, GuiObject *caller=NULL);
+ const wchar_t *guiobject_getName();
+
+#ifdef WASABI_COMPILE_CONFIG
+ void guiobject_setCfgAttrib(CfgItem *i, const wchar_t *attrib);
+ CfgItem *guiobject_getCfgItem();
+ const wchar_t *guiobject_getCfgAttrib();
+
+ int guiobject_getCfgInt();
+ void guiobject_setCfgInt(int i);
+ float guiobject_getCfgFloat();
+ void guiobject_setCfgFloat(float v);
+ const wchar_t *guiobject_getCfgString();
+ void guiobject_setCfgString(const wchar_t *s);
+ int guiobject_hasCfgAttrib();
+#endif
+
+ void guiobject_onGetFocus();
+ void guiobject_onKillFocus();
+ void guiobject_onAccelerator(const wchar_t *accel);
+ int guiobject_onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ int guiobject_wantFocus();
+
+ void guiobject_setNoDoubleClick(int no);
+ void guiobject_setNoLeftClick(int no);
+ void guiobject_setNoRightClick(int no);
+ void guiobject_setNoMouseMove(int no);
+ void guiobject_setNoContextMenu(int no);
+
+ void guiobject_setCursor(const wchar_t *c);
+
+ void guiobject_setAppBar(int enabled);
+ int guiobject_getAppBar();
+
+ int guiobject_wantTranslation();
+
+ int guiobject_dragEnter(ifc_window *sourceWnd);
+ int guiobject_dragOver(int x, int y, ifc_window *sourceWnd);
+ int guiobject_dragLeave(ifc_window *sourceWnd);
+
+ enum {
+ GUI_GETGUIPOSITION=10,
+ GUI_GETANCHORAGEPOSITION=11,
+ GUI_SETGUIPOSITION=20,
+ GUI_SETANCHORAGEPOSITION=21,
+ GUI_VALIDATEANCHORAGE=22,
+ GUI_SETPARENTGROUP=30,
+ GUI_GETPARENTGROUP=40,
+ GUI_GETPARENT=45,
+ GUI_GETPARENTLAYOUT=50,
+ GUI_GETTOPPARENT=55,
+ GUI_GETROOTWND=60,
+ GUI_WANTAUTOCTXMENU=70,
+ GUI_SETID=80,
+ GUI_GETID=90,
+ GUI_SETTARGETX=100,
+ GUI_SETTARGETY=110,
+ GUI_SETTARGETW=120,
+ GUI_SETTARGETH=130,
+ GUI_SETTARGETA=140,
+ GUI_SETTARGETSPEED=150,
+ GUI_GOTOTARGET=160,
+ GUI_CANCELTARGET=161,
+ GUI_REVERSETARGET=162,
+ GUI_MOVINGTOTARGET=170,
+ GUI_GETAUTOWIDTH=180,
+ GUI_GETAUTOHEIGHT=190,
+ GUI_BRINGTOFRONT=200,
+ GUI_BRINGTOBACK=210,
+ GUI_BRINGBELOW=220,
+ GUI_BRINGABOVE=230,
+ GUI_SETCLICKTHROUGH=240,
+ GUI_ISCLICKTHROUGH=250,
+ GUI_SETAUTOSMX=260,
+ GUI_SETAUTOSMY=270,
+ GUI_SETAUTOSMW=280,
+ GUI_SETAUTOSMH=290,
+ GUI_GETAUTOSMX=300,
+ GUI_GETAUTOSMY=310,
+ GUI_GETAUTOSMW=320,
+ GUI_GETAUTOSMH=330,
+ GUI_ONLEFTBUTTONDOWN=340,
+ GUI_ONLEFTBUTTONUP=350,
+ GUI_ONRIGHTBUTTONDOWN=360,
+ GUI_ONRIGHTBUTTONUP=370,
+ GUI_ONLEFTBUTTONDBLCLK=380,
+ GUI_ONRIGHTBUTTONDBLCLK=390,
+ GUI_ONMOUSEWHEELUP=394,
+ GUI_ONMOUSEWHEELDOWN=396,
+ GUI_ONMOUSEMOVE=400,
+ GUI_ONENTERAREA=410,
+ GUI_ONLEAVEAREA=420,
+ GUI_ONENABLE=430,
+ GUI_SETENABLED=431,
+ GUI_ONRESIZE=440,
+ GUI_ONSETVISIBLE=450,
+ GUI_ONTARGETREACHED=460,
+ GUI_SETALPHA=470,
+ GUI_GETALPHA=480,
+ GUI_SETACTIVEALPHA=490,
+ GUI_GETACTIVEALPHA=500,
+ GUI_SETINACTIVEALPHA=510,
+ GUI_GETINACTIVEALPHA=520,
+ GUI_ONSTARTUP=530,
+ GUI_SETXMLPARAM=540,
+ GUI_SETXMLPARAMBYID=541,
+ GUI_GETXMLPARAM=542,
+// GUI_ONUNKNOWNXMLPARAM=545, retired
+ GUI_SETROOTWND=550,
+ GUI_GETSCRIPTOBJECT=560,
+ GUI_GETROOTOBJECT=570,
+ GUI_RUNMODAL=580,
+ GUI_ENDMODAL=590,
+ GUI_SETXUISVC=600,
+ GUI_GETXUISVC=610,
+ GUI_POPPARENTLAYOUT=620,
+ GUI_SETREGIONOP=630,
+ GUI_GETREGIONOP=640,
+ GUI_SETRECTRGN=650,
+ GUI_ISRECTRGN=660,
+ GUI_REGISTERSTATUSCB=670,
+ GUI_SETSTATUSTXT=680,
+ GUI_ADDCTXTCMDS=690,
+ GUI_REMCTXTCMDS=700,
+ GUI_FINDOBJECT=800,
+ GUI_FINDOBJECTBYGUID=801,
+ GUI_FINDOBJECTBYCB=802,
+ GUI_FINDOBJECTCHAIN=803,
+ GUI_FINDOBJECTXY=804,
+ GUI_GETNAME=805,
+ GUI_GETMOVER=810,
+ GUI_SETMOVER=820,
+ GUI_GETDROPTARGET=830,
+ GUI_SETDROPTARGET=840,
+ GUI_ONCANCELCAPTURE=850,
+ GUI_SETCFGATTRIB=860,
+ GUI_GETCFGITEM=870,
+ GUI_GETCFGATTRIB=880,
+ GUI_SETCFGINT=890,
+ GUI_GETCFGINT=900,
+ GUI_GETCFGFLOAT=910,
+ GUI_SETCFGFLOAT=920,
+ GUI_SETCFGSTRING=930,
+ GUI_GETCFGSTRING=940,
+ GUI_HASATTRIB=950,
+ GUI_PUSHCOMPLETED=1000,
+ GUI_INCCOMPLETED=1010,
+ GUI_SETCOMPLETED=1020,
+ GUI_POPCOMPLETED=1030,
+ GUI_ONCHAR=1100,
+ GUI_ONKEYDOWN=1110,
+ GUI_ONKEYUP=1120,
+ GUI_ONGETFOCUS=1200,
+ GUI_ONKILLFOCUS=1210,
+ GUI_ONACCELERATOR=1300,
+ GUI_ONACTION=1400,
+ GUI_ONINIT=1500,
+ GUI_WANTFOCUS=1600,
+ GUI_SETNOMOUSEMOVE=1700,
+ GUI_SETNOLEFTCLICK=1800,
+ GUI_SETNORIGHTCLICK=1900,
+ GUI_SETNODOUBLECLICK=2000,
+ GUI_SETNOCONTEXTMENU=2100,
+ GUI_SETCURSOR=2200,
+ GUI_SETXUIFAC=2300,
+ GUI_GETXUIFAC=2310,
+ GUI_SETAPPBAR=2400,
+ GUI_GETAPPBAR=2410,
+ GUI_WANTTRANSLATION=2420,
+ GUI_DRAGENTER = 2430,
+ GUI_DRAGOVER = 2440,
+ GUI_DRAGLEAVE = 2450,
+ };
+
+ operator ScriptObject *() { return (this == NULL) ? NULL : guiobject_getScriptObject(); }
+ operator ifc_window *() { return (this == NULL) ? NULL : guiobject_getRootWnd(); }
+};
+
+inline void GuiObject::guiobject_getGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh) {
+ _voidcall(GUI_GETGUIPOSITION, x, y, w, h, rx, ry, rw, rh);
+}
+
+inline void GuiObject::guiobject_setGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh) {
+ _voidcall(GUI_SETGUIPOSITION, x, y, w, h, rx, ry, rw, rh);
+}
+
+inline int GuiObject::guiobject_getAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor) {
+ return _call(GUI_GETANCHORAGEPOSITION, 0, x1, y1, x2, y2, anchor);
+}
+
+inline void GuiObject::guiobject_setAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor) {
+ _voidcall(GUI_SETANCHORAGEPOSITION, x1, y1, x2, y2, anchor);
+}
+
+inline void GuiObject::guiobject_validateAnchorage() {
+ _voidcall(GUI_VALIDATEANCHORAGE);
+}
+
+inline void GuiObject::guiobject_setParentGroup(Group *g) {
+ _voidcall(GUI_SETPARENTGROUP, g);
+}
+
+inline Group *GuiObject::guiobject_getParentGroup() {
+ return _call(GUI_GETPARENTGROUP, (Group *)NULL);
+}
+
+inline GuiObject *GuiObject::guiobject_getParent() {
+ return _call(GUI_GETPARENT, (GuiObject *)NULL);
+}
+
+inline Layout *GuiObject::guiobject_getParentLayout() {
+ return _call(GUI_GETPARENTLAYOUT, (Layout*)NULL);
+}
+
+inline GuiObject *GuiObject::guiobject_getTopParent() {
+ return _call(GUI_GETTOPPARENT, (GuiObject *)NULL);
+}
+
+inline ifc_window *GuiObject::guiobject_getRootWnd() {
+ return _call(GUI_GETROOTWND, (ifc_window *)NULL);
+}
+
+inline void GuiObject::guiobject_setRootWnd(ifc_window *r) {
+ _voidcall(GUI_SETROOTWND, r);
+}
+
+inline int GuiObject::guiobject_wantAutoContextMenu() {
+ return _call(GUI_WANTAUTOCTXMENU, 0);
+}
+
+inline void GuiObject::guiobject_setId(const wchar_t *id) {
+ _voidcall(GUI_SETID, id);
+}
+
+inline const wchar_t *GuiObject::guiobject_getId() {
+ return _call(GUI_GETID, (const wchar_t *)NULL);
+}
+
+inline void GuiObject::guiobject_setTargetX(int tx) {
+ _voidcall(GUI_SETTARGETX, tx);
+}
+
+inline void GuiObject::guiobject_setTargetY(int ty) {
+ _voidcall(GUI_SETTARGETY, ty);
+}
+
+inline void GuiObject::guiobject_setTargetW(int tw) {
+ _voidcall(GUI_SETTARGETW, tw);
+}
+
+inline void GuiObject::guiobject_setTargetH(int th) {
+ _voidcall(GUI_SETTARGETH, th);
+}
+
+inline void GuiObject::guiobject_setTargetA(int ta) {
+ _voidcall(GUI_SETTARGETA, ta);
+}
+
+inline void GuiObject::guiobject_setTargetSpeed(float s) {
+ _voidcall(GUI_SETTARGETSPEED, s);
+}
+
+inline void GuiObject::guiobject_gotoTarget(void) {
+ _voidcall(GUI_GOTOTARGET);
+}
+
+inline void GuiObject::guiobject_cancelTarget() {
+ _voidcall(GUI_CANCELTARGET);
+}
+
+inline int GuiObject::guiobject_getAutoWidth() {
+ return _call(GUI_GETAUTOWIDTH, 0);
+}
+
+inline int GuiObject::guiobject_getAutoHeight() {
+ return _call(GUI_GETAUTOHEIGHT, 0);
+}
+
+inline int GuiObject::guiobject_movingToTarget() {
+ return _call(GUI_MOVINGTOTARGET, 0);
+}
+
+inline void GuiObject::guiobject_bringToFront() {
+ _voidcall(GUI_BRINGTOFRONT);
+}
+
+inline void GuiObject::guiobject_bringToBack() {
+ _voidcall(GUI_BRINGTOBACK);
+}
+
+inline void GuiObject::guiobject_bringAbove(GuiObject *o) {
+ _voidcall(GUI_BRINGABOVE, o);
+}
+
+inline void GuiObject::guiobject_bringBelow(GuiObject *o) {
+ _voidcall(GUI_BRINGBELOW, o);
+}
+
+inline void GuiObject::guiobject_setClickThrough(int ct) {
+ _voidcall(GUI_SETCLICKTHROUGH, ct);
+}
+
+inline void GuiObject::guiobject_setRegionOp(int op) {
+ _voidcall(GUI_SETREGIONOP, op);
+}
+
+inline int GuiObject::guiobject_getRegionOp() {
+ return _call(GUI_GETREGIONOP, 0);
+}
+
+inline void GuiObject::guiobject_setRectRgn(int rrgn) {
+ _voidcall(GUI_SETRECTRGN, rrgn);
+}
+
+inline int GuiObject::guiobject_isRectRgn() {
+ return _call(GUI_ISRECTRGN, 0);
+}
+
+inline int GuiObject::guiobject_isClickThrough() {
+ return _call(GUI_ISCLICKTHROUGH, 0);
+}
+
+inline void GuiObject::guiobject_setAutoSysMetricsX(int a) {
+ _voidcall(GUI_SETAUTOSMX, a);
+}
+
+inline void GuiObject::guiobject_setAutoSysMetricsY(int a) {
+ _voidcall(GUI_SETAUTOSMY, a);
+}
+
+inline void GuiObject::guiobject_setAutoSysMetricsW(int a) {
+ _voidcall(GUI_SETAUTOSMW, a);
+}
+
+inline void GuiObject::guiobject_setAutoSysMetricsH(int a) {
+ _voidcall(GUI_SETAUTOSMH, a);
+}
+
+inline int GuiObject::guiobject_getAutoSysMetricsX() {
+ return _call(GUI_GETAUTOSMX, 0);
+}
+
+inline int GuiObject::guiobject_getAutoSysMetricsY() {
+ return _call(GUI_GETAUTOSMY, 0);
+}
+
+inline int GuiObject::guiobject_getAutoSysMetricsW() {
+ return _call(GUI_GETAUTOSMW, 0);
+}
+
+inline int GuiObject::guiobject_getAutoSysMetricsH() {
+ return _call(GUI_GETAUTOSMH, 0);
+}
+
+inline void GuiObject::guiobject_onLeftButtonDown(int x, int y) {
+ _voidcall(GUI_ONLEFTBUTTONDOWN, x, y);
+}
+
+inline void GuiObject::guiobject_onLeftButtonUp(int x, int y) {
+ _voidcall(GUI_ONLEFTBUTTONUP, x, y);
+}
+
+inline void GuiObject::guiobject_onRightButtonDown(int x, int y) {
+ _voidcall(GUI_ONRIGHTBUTTONDOWN, x, y);
+}
+
+inline void GuiObject::guiobject_onRightButtonUp(int x, int y) {
+ _voidcall(GUI_ONRIGHTBUTTONUP, x, y);
+}
+
+inline void GuiObject::guiobject_onLeftButtonDblClk(int x, int y) {
+ _voidcall(GUI_ONLEFTBUTTONDBLCLK, x, y);
+}
+
+inline void GuiObject::guiobject_onRightButtonDblClk(int x, int y) {
+ _voidcall(GUI_ONRIGHTBUTTONDBLCLK, x, y);
+}
+
+inline int GuiObject::guiobject_onMouseWheelUp(int click, int lines)
+{
+ return _call(GUI_ONMOUSEWHEELUP, 0, click, lines);
+}
+
+inline int GuiObject::guiobject_onMouseWheelDown(int click, int lines)
+{
+ return _call(GUI_ONMOUSEWHEELDOWN, 0, click, lines);
+}
+
+inline void GuiObject::guiobject_onMouseMove(int x, int y) {
+ _voidcall(GUI_ONMOUSEMOVE, x, y);
+}
+
+inline void GuiObject::guiobject_onEnterArea() {
+ _voidcall(GUI_ONENTERAREA);
+}
+
+inline void GuiObject::guiobject_onLeaveArea() {
+ _voidcall(GUI_ONLEAVEAREA);
+}
+
+inline void GuiObject::guiobject_onEnable(int en) {
+ _voidcall(GUI_ONENABLE, en);
+}
+
+inline void GuiObject::guiobject_setEnabled(int en) {
+ _voidcall(GUI_SETENABLED, en);
+}
+
+inline void GuiObject::guiobject_onResize(int x, int y, int w, int h) {
+ _voidcall(GUI_ONRESIZE, x, y, w, h);
+}
+
+inline void GuiObject::guiobject_onSetVisible(int v) {
+ _voidcall(GUI_ONSETVISIBLE, v);
+}
+
+inline void GuiObject::guiobject_onTargetReached() {
+ _voidcall(GUI_ONTARGETREACHED);
+}
+
+inline void GuiObject::guiobject_setAlpha(int a) {
+ _voidcall(GUI_SETALPHA, a);
+}
+
+inline int GuiObject::guiobject_getAlpha() {
+ return _call(GUI_GETALPHA, 255);
+}
+
+inline void GuiObject::guiobject_setActiveAlpha(int a) {
+ _voidcall(GUI_SETACTIVEALPHA, a);
+}
+
+inline int GuiObject::guiobject_getActiveAlpha() {
+ return _call(GUI_GETACTIVEALPHA, 255);
+}
+
+inline void GuiObject::guiobject_setInactiveAlpha(int a) {
+ _voidcall(GUI_SETINACTIVEALPHA, a);
+}
+
+inline int GuiObject::guiobject_getInactiveAlpha() {
+ return _call(GUI_GETINACTIVEALPHA, 255);
+}
+
+inline void GuiObject::guiobject_onStartup() {
+ _voidcall(GUI_ONSTARTUP);
+}
+
+inline int GuiObject::guiobject_setXmlParam(const wchar_t *param, const wchar_t *value) {
+ return _call(GUI_SETXMLPARAM, 0, param, value);
+}
+
+inline int GuiObject::guiobject_setXmlParamById(int id, const wchar_t *value) {
+ return _call(GUI_SETXMLPARAMBYID, 0, id, value);
+}
+
+inline const wchar_t *GuiObject::guiobject_getXmlParam(const wchar_t *param) {
+ return _call(GUI_GETXMLPARAM, (const wchar_t *)NULL, param);
+}
+
+inline ScriptObject *GuiObject::guiobject_getScriptObject() {
+ return _call(GUI_GETSCRIPTOBJECT, (ScriptObject *)NULL);
+}
+
+inline RootObject *GuiObject::guiobject_getRootObject() {
+ return _call(GUI_GETROOTOBJECT, (RootObject *)NULL);
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+inline int GuiObject::guiobject_runModal() {
+ return _call(GUI_RUNMODAL, 0);
+}
+
+inline void GuiObject::guiobject_endModal(int retcode) {
+ _voidcall(GUI_ENDMODAL, retcode);
+}
+#endif
+
+inline svc_xuiObject *GuiObject::guiobject_getXuiService() {
+ return _call(GUI_GETXUISVC, (svc_xuiObject *)NULL);
+}
+
+inline void GuiObject::guiobject_setXuiService(svc_xuiObject *svc) {
+ _voidcall(GUI_SETXUISVC, svc);
+}
+
+inline waServiceFactory *GuiObject::guiobject_getXuiServiceFactory() {
+ return _call(GUI_GETXUIFAC, (waServiceFactory*)NULL);
+}
+
+inline void GuiObject::guiobject_setXuiServiceFactory(waServiceFactory *fac) {
+ _voidcall(GUI_SETXUIFAC, fac);
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+inline void GuiObject::guiobject_popParentLayout() {
+ _voidcall(GUI_POPPARENTLAYOUT);
+}
+
+inline void GuiObject::guiobject_setStatusText(const wchar_t *txt, int overlay) {
+ _voidcall(GUI_SETSTATUSTXT, txt, overlay);
+}
+
+inline void GuiObject::guiobject_addAppCmds(AppCmds *commands) {
+ _voidcall(GUI_ADDCTXTCMDS, commands);
+}
+
+inline void GuiObject::guiobject_removeAppCmds(AppCmds *commands) {
+ _voidcall(GUI_REMCTXTCMDS, commands);
+}
+
+inline
+void GuiObject::guiobject_pushCompleted(int max) {
+ _voidcall(GUI_PUSHCOMPLETED, max);
+}
+inline
+void GuiObject::guiobject_incCompleted(int add) {
+ _voidcall(GUI_INCCOMPLETED, add);
+}
+inline
+void GuiObject::guiobject_setCompleted(int pos) {
+ _voidcall(GUI_SETCOMPLETED, pos);
+}
+
+inline
+void GuiObject::guiobject_popCompleted() {
+ _voidcall(GUI_POPCOMPLETED);
+}
+
+inline void GuiObject::guiobject_registerStatusCB(GuiStatusCallback *callback) {
+ _voidcall(GUI_REGISTERSTATUSCB, callback);
+}
+#endif
+
+inline GuiObject *GuiObject::guiobject_findObject(const wchar_t *id) {
+ return _call(GUI_FINDOBJECT, (GuiObject *)NULL, id);
+}
+
+inline GuiObject *GuiObject::guiobject_findObjectXY(int x, int y) {
+ return _call(GUI_FINDOBJECTXY, (GuiObject *)NULL, x, y);
+}
+
+inline GuiObject *GuiObject::guiobject_findObjectByInterface(GUID interface_guid) {
+ return _call(GUI_FINDOBJECTBYGUID, (GuiObject *)NULL, interface_guid);
+}
+
+inline GuiObject *GuiObject::guiobject_findObjectByCallback(FindObjectCallback *cb) {
+ return _call(GUI_FINDOBJECTBYCB, (GuiObject *)NULL, cb);
+}
+
+inline GuiObject *GuiObject::guiobject_findObjectChain(FindObjectCallback *cb, GuiObject *caller) {
+ return _call(GUI_FINDOBJECTCHAIN, (GuiObject *)NULL, cb, caller);
+}
+
+inline const wchar_t *GuiObject::guiobject_getName() {
+ return _call(GUI_GETNAME, (const wchar_t *)NULL);
+}
+
+inline int GuiObject::guiobject_getMover() {
+ return _call(GUI_GETMOVER, 0);
+}
+
+inline void GuiObject::guiobject_setMover(int s) {
+ _voidcall(GUI_SETMOVER, s);
+}
+
+inline FOURCC GuiObject::guiobject_getDropTarget() {
+ return _call(GUI_GETDROPTARGET, (FOURCC)0);
+}
+
+inline void GuiObject::guiobject_setDropTarget(const wchar_t *target) {
+ _voidcall(GUI_SETDROPTARGET, target);
+}
+
+inline void GuiObject::guiobject_onCancelCapture() {
+ _voidcall(GUI_ONCANCELCAPTURE);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+inline void GuiObject::guiobject_setCfgAttrib(CfgItem *item, const wchar_t *attr) {
+ _voidcall(GUI_SETCFGATTRIB, item, attr);
+}
+
+inline CfgItem *GuiObject::guiobject_getCfgItem() {
+ return _call(GUI_GETCFGITEM, (CfgItem *)NULL);
+}
+
+inline const wchar_t *GuiObject::guiobject_getCfgAttrib() {
+ return _call(GUI_GETCFGATTRIB, (const wchar_t *)NULL);
+}
+
+inline int GuiObject::guiobject_getCfgInt() {
+ return _call(GUI_GETCFGINT, 0);
+}
+
+inline void GuiObject::guiobject_setCfgInt(int i) {
+ _voidcall(GUI_SETCFGINT, i);
+}
+
+inline float GuiObject::guiobject_getCfgFloat() {
+ return _call(GUI_GETCFGFLOAT, (float)0);
+}
+
+inline void GuiObject::guiobject_setCfgFloat(float v) {
+ _voidcall(GUI_SETCFGFLOAT, v);
+}
+
+inline const wchar_t *GuiObject::guiobject_getCfgString() {
+ return _call(GUI_GETCFGSTRING, (const wchar_t *)NULL);
+}
+
+inline void GuiObject::guiobject_setCfgString(const wchar_t *s) {
+ _voidcall(GUI_SETCFGSTRING, s);
+}
+
+inline int GuiObject::guiobject_hasCfgAttrib() {
+ return _call(GUI_HASATTRIB, 0);
+}
+#endif
+
+inline void GuiObject::guiobject_onChar(wchar_t c) {
+ _voidcall(GUI_ONCHAR, c);
+}
+
+inline void GuiObject::guiobject_onKeyDown(int k) {
+ _voidcall(GUI_ONKEYDOWN, k);
+}
+
+inline void GuiObject::guiobject_onKeyUp(int k) {
+ _voidcall(GUI_ONKEYUP, k);
+}
+
+inline void GuiObject::guiobject_onGetFocus() {
+ _voidcall(GUI_ONGETFOCUS);
+}
+
+inline void GuiObject::guiobject_onKillFocus() {
+ _voidcall(GUI_ONKILLFOCUS);
+}
+
+inline void GuiObject::guiobject_onAccelerator(const wchar_t *accel) {
+ _voidcall(GUI_ONACCELERATOR, accel);
+}
+
+inline int GuiObject::guiobject_onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ return _call(GUI_ONACTION, 0, action, param, x, y, p1, p2, data, datalen, source);
+}
+
+inline void GuiObject::guiobject_onInit() {
+ _voidcall(GUI_ONINIT);
+}
+
+inline int GuiObject::guiobject_wantFocus() {
+ return _call(GUI_WANTFOCUS, 0);
+}
+
+inline void GuiObject::guiobject_setNoDoubleClick(int no) {
+ _voidcall(GUI_SETNODOUBLECLICK, no);
+}
+
+inline void GuiObject::guiobject_setNoLeftClick(int no) {
+ _voidcall(GUI_SETNOLEFTCLICK, no);
+}
+
+inline void GuiObject::guiobject_setNoRightClick(int no) {
+ _voidcall(GUI_SETNORIGHTCLICK, no);
+}
+
+inline void GuiObject::guiobject_setNoMouseMove(int no) {
+ _voidcall(GUI_SETNOMOUSEMOVE, no);
+}
+
+inline void GuiObject::guiobject_setNoContextMenu(int no) {
+ _voidcall(GUI_SETNOCONTEXTMENU, no);
+}
+
+inline void GuiObject::guiobject_setCursor(const wchar_t *c) {
+ _voidcall(GUI_SETCURSOR, c);
+}
+
+inline void GuiObject::guiobject_reverseTarget(int reverse) {
+ _voidcall(GUI_REVERSETARGET, reverse);
+}
+
+inline void GuiObject::guiobject_setAppBar(int enabled) {
+ _voidcall(GUI_SETAPPBAR, enabled);
+}
+
+inline int GuiObject::guiobject_getAppBar() {
+ return _call(GUI_GETAPPBAR, 0);
+}
+
+inline int GuiObject::guiobject_wantTranslation()
+{
+ return _call(GUI_WANTTRANSLATION, (int)1);
+}
+
+inline int GuiObject::guiobject_dragEnter(ifc_window *sourceWnd)
+{
+ return _call(GUI_DRAGENTER, (int)1, sourceWnd);
+}
+
+inline int GuiObject::guiobject_dragOver(int x, int y, ifc_window *sourceWnd)
+{
+ return _call(GUI_DRAGOVER, (int)1, sourceWnd, x, y);
+}
+
+inline int GuiObject::guiobject_dragLeave(ifc_window *sourceWnd)
+{
+ return _call(GUI_DRAGLEAVE, (int)1, sourceWnd);
+}
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/guiobjectx.cpp b/Src/Wasabi/api/script/objects/guiobjectx.cpp
new file mode 100644
index 00000000..44d0ca83
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/guiobjectx.cpp
@@ -0,0 +1,131 @@
+#include <precomp.h>
+#include "guiobjectx.h"
+
+#define CBCLASS GuiObjectX
+START_DISPATCH;
+ CB(GUI_GETSCRIPTOBJECT, guiobject_getScriptObject);
+ CB(GUI_GETROOTWND, guiobject_getRootWnd);
+ CB(GUI_GETROOTOBJECT, guiobject_getRootObject);
+ VCB(GUI_SETROOTWND, guiobject_setRootWnd);
+ CB(GUI_SETXMLPARAM, guiobject_setXmlParam);
+ CB(GUI_SETXMLPARAMBYID, guiobject_setXmlParamById);
+ CB(GUI_GETXMLPARAM, guiobject_getXmlParam);
+ VCB(GUI_SETPARENTGROUP, guiobject_setParentGroup);
+ CB(GUI_GETPARENTGROUP, guiobject_getParentGroup);
+ CB(GUI_GETPARENT, guiobject_getParent);
+ CB(GUI_GETPARENTLAYOUT, guiobject_getParentLayout);
+ CB(GUI_GETTOPPARENT, guiobject_getTopParent);
+ VCB(GUI_GETGUIPOSITION, guiobject_getGuiPosition);
+ VCB(GUI_SETGUIPOSITION, guiobject_setGuiPosition);
+ CB(GUI_GETANCHORAGEPOSITION, guiobject_getAnchoragePosition);
+ VCB(GUI_SETANCHORAGEPOSITION, guiobject_setAnchoragePosition);
+ VCB(GUI_VALIDATEANCHORAGE, guiobject_validateAnchorage);
+ VCB(GUI_SETID, guiobject_setId);
+ CB(GUI_GETID, guiobject_getId);
+ VCB(GUI_SETTARGETX, guiobject_setTargetX);
+ VCB(GUI_SETTARGETY, guiobject_setTargetY);
+ VCB(GUI_SETTARGETW, guiobject_setTargetW);
+ VCB(GUI_SETTARGETH, guiobject_setTargetH);
+ VCB(GUI_SETTARGETA, guiobject_setTargetA);
+ VCB(GUI_SETTARGETSPEED, guiobject_setTargetSpeed);
+ VCB(GUI_GOTOTARGET, guiobject_gotoTarget);
+ VCB(GUI_CANCELTARGET, guiobject_cancelTarget);
+ VCB(GUI_REVERSETARGET, guiobject_reverseTarget);
+ CB(GUI_GETAUTOWIDTH, guiobject_getAutoWidth);
+ CB(GUI_GETAUTOHEIGHT, guiobject_getAutoHeight);
+ CB(GUI_MOVINGTOTARGET, guiobject_movingToTarget);
+ VCB(GUI_BRINGTOFRONT, guiobject_bringToFront);
+ VCB(GUI_BRINGTOBACK, guiobject_bringToBack);
+ VCB(GUI_BRINGABOVE, guiobject_bringAbove);
+ VCB(GUI_BRINGBELOW, guiobject_bringBelow);
+ VCB(GUI_SETCLICKTHROUGH, guiobject_setClickThrough);
+ CB(GUI_ISCLICKTHROUGH, guiobject_isClickThrough);
+ VCB(GUI_SETAUTOSMX, guiobject_setAutoSysMetricsX);
+ VCB(GUI_SETAUTOSMY, guiobject_setAutoSysMetricsY);
+ VCB(GUI_SETAUTOSMW, guiobject_setAutoSysMetricsW);
+ VCB(GUI_SETAUTOSMH, guiobject_setAutoSysMetricsH);
+ CB(GUI_GETAUTOSMX, guiobject_getAutoSysMetricsX);
+ CB(GUI_GETAUTOSMY, guiobject_getAutoSysMetricsY);
+ CB(GUI_GETAUTOSMW, guiobject_getAutoSysMetricsW);
+ CB(GUI_GETAUTOSMH, guiobject_getAutoSysMetricsH);
+ VCB(GUI_ONLEFTBUTTONDOWN, guiobject_onLeftButtonDown);
+ VCB(GUI_ONLEFTBUTTONUP, guiobject_onLeftButtonUp);
+ VCB(GUI_ONRIGHTBUTTONDOWN, guiobject_onRightButtonDown);
+ VCB(GUI_ONRIGHTBUTTONUP, guiobject_onRightButtonUp);
+ VCB(GUI_ONLEFTBUTTONDBLCLK, guiobject_onLeftButtonDblClk);
+ VCB(GUI_ONRIGHTBUTTONDBLCLK, guiobject_onRightButtonDblClk);
+ CB(GUI_ONMOUSEWHEELUP, guiobject_onMouseWheelUp);
+ CB(GUI_ONMOUSEWHEELDOWN, guiobject_onMouseWheelDown);
+ VCB(GUI_ONMOUSEMOVE, guiobject_onMouseMove);
+ VCB(GUI_ONENTERAREA, guiobject_onEnterArea);
+ VCB(GUI_ONLEAVEAREA, guiobject_onLeaveArea);
+ VCB(GUI_ONENABLE, guiobject_onEnable);
+ VCB(GUI_SETENABLED, guiobject_setEnabled);
+ VCB(GUI_ONRESIZE, guiobject_onResize);
+ VCB(GUI_ONSETVISIBLE, guiobject_onSetVisible);
+ VCB(GUI_ONTARGETREACHED, guiobject_onTargetReached);
+ VCB(GUI_SETALPHA, guiobject_setAlpha);
+ CB(GUI_GETALPHA, guiobject_getAlpha);
+ VCB(GUI_ONSTARTUP, guiobject_onStartup);
+ CB(GUI_GETXUISVC, guiobject_getXuiService);
+ VCB(GUI_SETXUISVC, guiobject_setXuiService);
+ CB(GUI_GETXUIFAC, guiobject_getXuiServiceFactory);
+ VCB(GUI_SETXUIFAC, guiobject_setXuiServiceFactory);
+ VCB(GUI_SETREGIONOP, guiobject_setRegionOp);
+ CB(GUI_GETREGIONOP, guiobject_getRegionOp);
+ VCB(GUI_SETRECTRGN, guiobject_setRectRgn);
+ CB(GUI_ISRECTRGN, guiobject_isRectRgn);
+ VCB(GUI_SETMOVER, guiobject_setMover);
+ CB(GUI_GETMOVER, guiobject_getMover);
+ CB(GUI_GETDROPTARGET, guiobject_getDropTarget);
+ VCB(GUI_ONCANCELCAPTURE, guiobject_onCancelCapture);
+ CB(GUI_ONACTION, guiobject_onAction);
+#ifdef WASABI_COMPILE_CONFIG
+ CB(GUI_GETCFGITEM, guiobject_getCfgItem);
+ CB(GUI_GETCFGATTRIB, guiobject_getCfgAttrib);
+ VCB(GUI_SETCFGATTRIB, guiobject_setCfgAttrib);
+ VCB(GUI_SETCFGINT, guiobject_setCfgInt);
+ CB(GUI_GETCFGINT, guiobject_getCfgInt);
+ CB(GUI_GETCFGFLOAT, guiobject_getCfgFloat);
+ VCB(GUI_SETCFGFLOAT, guiobject_setCfgFloat);
+ VCB(GUI_SETCFGSTRING, guiobject_setCfgString);
+ CB(GUI_GETCFGSTRING, guiobject_getCfgString);
+ CB(GUI_HASATTRIB, guiobject_hasCfgAttrib);
+#endif
+ VCB(GUI_ONCHAR, guiobject_onChar);
+ VCB(GUI_ONKEYDOWN, guiobject_onKeyDown);
+ VCB(GUI_ONKEYUP, guiobject_onKeyUp);
+ CB(GUI_FINDOBJECT, guiobject_findObject);
+ CB(GUI_FINDOBJECTBYGUID, guiobject_findObjectByInterface);
+ CB(GUI_FINDOBJECTBYCB, guiobject_findObjectByCallback);
+ CB(GUI_FINDOBJECTXY, guiobject_findObjectXY);
+ VCB(GUI_ONACCELERATOR, guiobject_onAccelerator);
+ VCB(GUI_ONINIT, guiobject_onInit);
+ CB(GUI_WANTFOCUS, guiobject_wantFocus);
+ VCB(GUI_SETNODOUBLECLICK, guiobject_setNoDoubleClick);
+ VCB(GUI_SETNOLEFTCLICK, guiobject_setNoLeftClick);
+ VCB(GUI_SETNORIGHTCLICK, guiobject_setNoRightClick);
+ VCB(GUI_SETNOMOUSEMOVE, guiobject_setNoMouseMove);
+ VCB(GUI_SETNOCONTEXTMENU, guiobject_setNoContextMenu);
+ VCB(GUI_SETCURSOR, guiobject_setCursor);
+#ifdef WASABI_COMPILE_WNDMGR
+ CB(GUI_RUNMODAL, guiobject_runModal);
+ VCB(GUI_ENDMODAL, guiobject_endModal);
+ VCB(GUI_SETDROPTARGET, guiobject_setDropTarget);
+ VCB(GUI_SETSTATUSTXT, guiobject_setStatusText);
+ VCB(GUI_ADDCTXTCMDS, guiobject_addAppCmds);
+ VCB(GUI_REMCTXTCMDS, guiobject_removeAppCmds);
+ VCB(GUI_PUSHCOMPLETED, guiobject_pushCompleted);
+ VCB(GUI_INCCOMPLETED, guiobject_incCompleted);
+ VCB(GUI_SETCOMPLETED, guiobject_setCompleted);
+ VCB(GUI_POPCOMPLETED, guiobject_popCompleted);
+ VCB(GUI_REGISTERSTATUSCB, guiobject_registerStatusCB);
+ VCB(GUI_POPPARENTLAYOUT, guiobject_popParentLayout);
+#endif
+ VCB(GUI_SETAPPBAR, guiobject_setAppBar);
+ CB(GUI_GETAPPBAR, guiobject_getAppBar);
+ CB(GUI_WANTTRANSLATION, guiobject_wantTranslation);
+ CB(GUI_DRAGENTER, guiobject_dragEnter);
+ CB(GUI_DRAGOVER, guiobject_dragOver);
+ CB(GUI_DRAGLEAVE, guiobject_dragLeave);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/script/objects/guiobjectx.h b/Src/Wasabi/api/script/objects/guiobjectx.h
new file mode 100644
index 00000000..c840476c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/guiobjectx.h
@@ -0,0 +1,177 @@
+#ifndef NULLSOFT_WASABI_GUIOBJECTX_H
+#define NULLSOFT_WASABI_GUIOBJECTX_H
+
+#include <wasabicfg.h>
+#include <api/script/objects/guiobject.h>
+
+class GuiObjectX : public GuiObject
+{
+public:
+ virtual ~GuiObjectX() {}
+
+ virtual ifc_window *guiobject_getRootWnd()=0;
+ virtual void guiobject_setRootWnd(ifc_window *w)=0;
+ virtual void guiobject_onInit()=0;
+
+ virtual void guiobject_getGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh)=0;
+ virtual void guiobject_setGuiPosition(int *x, int *y, int *w, int *h, int *rx, int *ry, int *rw, int *rh)=0;
+ virtual int guiobject_getAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor)=0;
+ virtual void guiobject_setAnchoragePosition(int *x1, int *y1, int *x2, int *y2, int *anchor)=0;
+ virtual void guiobject_validateAnchorage()=0;
+
+ virtual void guiobject_setParentGroup(Group *g)=0;
+ virtual ScriptObject *guiobject_getScriptObject()=0;
+ virtual RootObject *guiobject_getRootObject()=0;
+ virtual Group *guiobject_getParentGroup()=0;
+ virtual GuiObject *guiobject_getParent()=0;
+ virtual void guiobject_setTabOrder(int a)=0;
+
+ virtual void guiobject_setId(const wchar_t *id)=0;
+ virtual const wchar_t *guiobject_getId()=0;
+
+ virtual void guiobject_setTargetX(int tx)=0;
+ virtual void guiobject_setTargetY(int ty)=0;
+ virtual void guiobject_setTargetW(int tw)=0;
+ virtual void guiobject_setTargetH(int th)=0;
+ virtual void guiobject_setTargetA(int th)=0;
+ virtual void guiobject_setTargetSpeed(float s)=0;
+ virtual void guiobject_gotoTarget(void)=0;
+ virtual void guiobject_cancelTarget()=0;
+ virtual void guiobject_reverseTarget(int reverse)=0;
+
+ virtual int guiobject_getAutoWidth()=0;
+ virtual int guiobject_getAutoHeight()=0;
+ virtual int guiobject_movingToTarget()=0;
+
+ virtual void guiobject_bringToFront()=0;
+ virtual void guiobject_bringToBack()=0;
+ virtual void guiobject_bringAbove(GuiObject *o)=0;
+ virtual void guiobject_bringBelow(GuiObject *o)=0;
+
+ virtual void guiobject_setClickThrough(int ct)=0;
+ virtual int guiobject_isClickThrough()=0;
+
+ virtual void guiobject_setAutoSysMetricsX(int a)=0;
+ virtual void guiobject_setAutoSysMetricsY(int a)=0;
+ virtual void guiobject_setAutoSysMetricsW(int a)=0;
+ virtual void guiobject_setAutoSysMetricsH(int a)=0;
+ virtual int guiobject_getAutoSysMetricsX()=0;
+ virtual int guiobject_getAutoSysMetricsY()=0;
+ virtual int guiobject_getAutoSysMetricsW()=0;
+ virtual int guiobject_getAutoSysMetricsH()=0;
+
+ virtual int guiobject_getRegionOp()=0;
+ virtual void guiobject_setRegionOp(int op)=0;
+ virtual int guiobject_isRectRgn()=0;
+ virtual void guiobject_setRectRgn(int rrgn)=0;
+
+ virtual void guiobject_onLeftButtonDown(int x, int y)=0;
+ virtual void guiobject_onLeftButtonUp(int x, int y)=0;
+ virtual void guiobject_onRightButtonDown(int x, int y)=0;
+ virtual void guiobject_onRightButtonUp(int x, int y)=0;
+ virtual void guiobject_onLeftButtonDblClk(int x, int y)=0;
+ virtual void guiobject_onRightButtonDblClk(int x, int y)=0;
+ virtual int guiobject_onMouseWheelUp(int click, int lines)=0;
+ virtual int guiobject_onMouseWheelDown(int click, int lines)=0;
+ virtual void guiobject_onMouseMove(int x, int y)=0;
+ virtual void guiobject_onEnterArea()=0;
+ virtual void guiobject_onLeaveArea()=0;
+ virtual void guiobject_onEnable(int en)=0;
+ virtual void guiobject_setEnabled(int en)=0;
+ virtual void guiobject_onResize(int x, int y, int w, int h)=0;
+ virtual void guiobject_onSetVisible(int v)=0;
+ virtual void guiobject_onTargetReached()=0;
+ virtual void guiobject_setAlpha(int a)=0;
+ virtual void guiobject_setActiveAlpha(int a)=0;
+ virtual void guiobject_setInactiveAlpha(int a)=0;
+ virtual int guiobject_getAlpha()=0;
+ virtual int guiobject_getActiveAlpha()=0;
+ virtual int guiobject_getInactiveAlpha()=0;
+ virtual int guiobject_isActive()=0;
+ virtual void guiobject_onStartup()=0;
+ virtual int guiobject_setXmlParam(const wchar_t *param, const wchar_t *value)=0;
+ virtual const wchar_t *guiobject_getXmlParam(const wchar_t *param)=0;
+ virtual int guiobject_setXmlParamById(int id, const wchar_t *value)=0;
+ virtual svc_xuiObject *guiobject_getXuiService()=0;
+ virtual void guiobject_setXuiService(svc_xuiObject *svc)=0;
+ virtual waServiceFactory *guiobject_getXuiServiceFactory()=0;
+ virtual void guiobject_setXuiServiceFactory(waServiceFactory *fac)=0;
+ virtual GuiObject *guiobject_getTopParent()=0;
+#ifdef WASABI_COMPILE_WNDMGR
+ virtual Layout *guiobject_getParentLayout()=0;
+ virtual int guiobject_runModal()=0;
+ virtual void guiobject_endModal(int retcode)=0;
+ virtual void guiobject_popParentLayout()=0;
+ virtual void guiobject_registerStatusCB(GuiStatusCallback *cb)=0;
+ virtual void guiobject_setStatusText(const wchar_t *txt, int overlay = FALSE)=0;
+ virtual void guiobject_addAppCmds(AppCmds *commands)=0;
+ virtual void guiobject_removeAppCmds(AppCmds *commands)=0;
+ virtual void guiobject_pushCompleted(int max = 100)=0;
+ virtual void guiobject_incCompleted(int add = 1)=0;
+ virtual void guiobject_setCompleted(int pos)=0;
+ virtual void guiobject_popCompleted()=0;
+#endif
+ virtual GuiObject *guiobject_findObject(const wchar_t *id)=0;
+ virtual GuiObject *guiobject_findObjectXY(int x, int y)=0; // in client coordinates relative to this object
+ virtual GuiObject *guiobject_findObjectByInterface(GUID interface_guid)=0;
+ virtual GuiObject *guiobject_findObjectByCallback(FindObjectCallback *cb)=0;
+ virtual void guiobject_setMover(int m)=0;
+ virtual int guiobject_getMover()=0;
+ virtual void guiobject_onCancelCapture()=0;
+ virtual void guiobject_onChar(wchar_t c)=0;
+ virtual void guiobject_onKeyDown(int vkcode)=0;
+ virtual void guiobject_onKeyUp(int vkcode)=0;
+
+ virtual FOURCC guiobject_getDropTarget()=0;
+ virtual void guiobject_setDropTarget(const wchar_t *strval)=0;
+
+ virtual void onTargetTimer()=0;
+#ifdef USEAPPBAR
+ virtual int guiobject_getAppBar()=0;
+ virtual void guiobject_setAppBar(int en)=0;
+ virtual void setAppBar(const wchar_t *en)=0;
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+ virtual void guiobject_setCfgAttrib(CfgItem *item, const wchar_t *name)=0;
+
+ virtual CfgItem *guiobject_getCfgItem()=0;
+ virtual const wchar_t *guiobject_getCfgAttrib()=0;
+
+ virtual int guiobject_getCfgInt()=0;
+ virtual void guiobject_setCfgInt(int i)=0;
+ virtual float guiobject_getCfgFloat()=0;
+ virtual void guiobject_setCfgFloat(float f)=0;
+ virtual const wchar_t *guiobject_getCfgString()=0;
+ virtual void guiobject_setCfgString(const wchar_t *s)=0;
+ virtual int guiobject_hasCfgAttrib()=0;
+#endif
+
+ virtual const wchar_t *guiobject_getName()=0;
+ virtual void guiobject_onAccelerator(const wchar_t *accel)=0;
+ virtual int guiobject_onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)=0;
+
+ virtual int guiobject_wantFocus()=0;
+ virtual void guiobject_setNoDoubleClick(int no)=0;
+ virtual void guiobject_setNoLeftClick(int no)=0;
+ virtual void guiobject_setNoRightClick(int no)=0;
+ virtual void guiobject_setNoMouseMove(int no)=0;
+ virtual void guiobject_setNoContextMenu(int no)=0;
+
+ virtual void guiobject_setCursor(const wchar_t *c)=0;
+ virtual int guiobject_wantTranslation()=0;
+
+ virtual int guiobject_dragEnter(ifc_window *sourceWnd)=0;
+ virtual int guiobject_dragOver(int x, int y, ifc_window *sourceWnd)=0;
+ virtual int guiobject_dragLeave(ifc_window *sourceWnd)=0;
+
+protected:
+ RECVS_DISPATCH;
+
+};
+
+
+
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/rootobj.cpp b/Src/Wasabi/api/script/objects/rootobj.cpp
new file mode 100644
index 00000000..8791f430
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobj.cpp
@@ -0,0 +1,42 @@
+#include <api/script/objcontroller.h>
+#include "rootobj.h"
+#include <api/script/objects/rootobject.h>
+#include "api.h"
+#include <api/script/scriptguid.h>
+
+RootObjectInstance::RootObjectInstance()
+{
+ ASSERT(WASABI_API_MAKI != 0);
+ rootobject_init();
+}
+
+RootObjectInstance::~RootObjectInstance()
+{
+ WASABI_API_MAKI->maki_deencapsulate(rootObjectGuid, my_root_object);
+}
+
+RootObject *RootObjectInstance::getRootObject() {
+ return my_root_object;
+}
+
+ScriptObject *RootObjectInstance::getScriptObject() {
+ return &my_script_object;
+}
+
+const wchar_t *RootObjectInstance::getClassName()
+{
+ return my_root_object->rootobject_getClassName();
+}
+
+void RootObjectInstance::notify(const wchar_t *s, const wchar_t *t, int u, int v) {
+ my_root_object->rootobject_notify(s, t, u, v);
+}
+
+void RootObjectInstance::rootobject_init()
+{
+ my_root_object = static_cast<RootObject *>(WASABI_API_MAKI->maki_encapsulate(rootObjectGuid, &my_script_object)); // creates an encapsulated RootObject
+ my_script_object.vcpu_setInterface(rootObjectInstanceGuid, static_cast<void *>(this));
+ my_script_object.vcpu_setClassName(L"Object");
+ my_script_object.vcpu_setController(WASABI_API_MAKI->maki_getController(rootObjectGuid));
+}
+
diff --git a/Src/Wasabi/api/script/objects/rootobj.h b/Src/Wasabi/api/script/objects/rootobj.h
new file mode 100644
index 00000000..4a44f8c2
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobj.h
@@ -0,0 +1,40 @@
+#ifndef __ROOTOBJ_H
+#define __ROOTOBJ_H
+
+#include <bfc/dispatch.h>
+#include <api/script/objects/rootobjcbi.h>
+#include <api/script/scriptobji.h>
+
+class ScriptObject;
+class ScriptObjectI;
+class RootObject;
+
+// RootObjectInstance::this == RootObjectInstance::getScriptObject()->vcpu_getInterface(rootObjectInstanceGuid);
+// {F6D49468-4036-41a1-9683-C372416AD31B}
+static const GUID rootObjectInstanceGuid =
+{ 0xf6d49468, 0x4036, 0x41a1, { 0x96, 0x83, 0xc3, 0x72, 0x41, 0x6a, 0xd3, 0x1b } };
+
+// Instantiate this class to create an object from which you can trap notify events, or inherit from
+// it if you want to implement your own descendant of script class 'Object' (see GuiObjectWnd)
+class RootObjectInstance : public RootObjectCallbackI
+{
+public:
+
+ RootObjectInstance();
+ virtual ~RootObjectInstance();
+
+ virtual RootObject *getRootObject();
+ virtual ScriptObject *getScriptObject();
+
+ virtual void rootobjectcb_onNotify(const wchar_t *a, const wchar_t *b, int c, int d) {};
+ virtual const wchar_t *getClassName();
+ virtual void notify(const wchar_t *s, const wchar_t *t, int u, int v);
+
+ private:
+ void rootobject_init();
+ ScriptObjectI my_script_object;
+ RootObject * my_root_object;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/rootobjcb.cpp b/Src/Wasabi/api/script/objects/rootobjcb.cpp
new file mode 100644
index 00000000..212a943e
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcb.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:33 2003]
+//
+// File : rootobjcb.cpp
+// Class : RootObjectCallback
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "rootobjcb.h"
+
+
diff --git a/Src/Wasabi/api/script/objects/rootobjcb.h b/Src/Wasabi/api/script/objects/rootobjcb.h
new file mode 100644
index 00000000..9e3f1e3c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcb.h
@@ -0,0 +1,40 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:33 2003]
+//
+// File : rootobjcb.h
+// Class : RootObjectCallback
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __ROOTOBJECTCALLBACK_H
+#define __ROOTOBJECTCALLBACK_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+
+
+// ----------------------------------------------------------------------------
+
+class RootObjectCallback: public Dispatchable {
+ protected:
+ RootObjectCallback() {}
+ ~RootObjectCallback() {}
+ public:
+ void rootobjectcb_onNotify(const wchar_t *a, const wchar_t *b, int c, int d);
+
+ protected:
+ enum {
+ ROOTOBJECTCALLBACK_ROOTOBJECTCB_ONNOTIFY = 10,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline void RootObjectCallback::rootobjectcb_onNotify(const wchar_t *a, const wchar_t *b, int c, int d) {
+ _voidcall(ROOTOBJECTCALLBACK_ROOTOBJECTCB_ONNOTIFY, a, b, c, d);
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __ROOTOBJECTCALLBACK_H
diff --git a/Src/Wasabi/api/script/objects/rootobjcbi.cpp b/Src/Wasabi/api/script/objects/rootobjcbi.cpp
new file mode 100644
index 00000000..9545e59e
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcbi.cpp
@@ -0,0 +1,3 @@
+#include <precomp.h>
+#include "rootobjcb.h"
+
diff --git a/Src/Wasabi/api/script/objects/rootobjcbi.h b/Src/Wasabi/api/script/objects/rootobjcbi.h
new file mode 100644
index 00000000..14dd63ad
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcbi.h
@@ -0,0 +1,15 @@
+#ifndef __ROOTOBJCB_H
+#define __ROOTOBJCB_H
+
+//<?<autoheader/>
+#include "rootobjcb.h"
+#include "rootobjcbx.h"
+
+//?>
+
+class NOVTABLE RootObjectCallbackI : public RootObjectCallbackX {
+ public:
+ DISPATCH(10) virtual void rootobjectcb_onNotify(const wchar_t *a, const wchar_t *b, int c, int d)=0;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/rootobjcbx.cpp b/Src/Wasabi/api/script/objects/rootobjcbx.cpp
new file mode 100644
index 00000000..84ce169c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcbx.cpp
@@ -0,0 +1,20 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:33 2003]
+//
+// File : rootobjcbx.cpp
+// Class : RootObjectCallback
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include "rootobjcbx.h"
+#include "rootobjcbi.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS RootObjectCallbackX
+START_DISPATCH;
+ VCB(ROOTOBJECTCALLBACK_ROOTOBJECTCB_ONNOTIFY, rootobjectcb_onNotify);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/script/objects/rootobjcbx.h b/Src/Wasabi/api/script/objects/rootobjcbx.h
new file mode 100644
index 00000000..eb07530c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcbx.h
@@ -0,0 +1,29 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:06:33 2003]
+//
+// File : rootobjcbx.h
+// Class : RootObjectCallback
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __ROOTOBJECTCALLBACKX_H
+#define __ROOTOBJECTCALLBACKX_H
+
+#include "rootobjcb.h"
+
+
+
+
+// ----------------------------------------------------------------------------
+
+class RootObjectCallbackX : public RootObjectCallback {
+ protected:
+ RootObjectCallbackX() {}
+ public:
+ virtual void rootobjectcb_onNotify(const wchar_t *a, const wchar_t *b, int c, int d)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __ROOTOBJECTCALLBACKX_H
diff --git a/Src/Wasabi/api/script/objects/rootobjcontroller.cpp b/Src/Wasabi/api/script/objects/rootobjcontroller.cpp
new file mode 100644
index 00000000..94a6f396
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcontroller.cpp
@@ -0,0 +1,81 @@
+#include "precomp.h"
+//<?#include "<class data="implementationheader"/>"
+#include "rootobjcontroller.h"
+//?>
+
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobjecti.h>
+
+RootScriptObjectController _rootScriptObjectController;
+RootScriptObjectController *rootScriptObjectController = &_rootScriptObjectController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct RootScriptObjectController::exportedFunction[] = {
+ {L"getClassName", 0, (void*)RootObject_ScriptMethods::getClassName },
+ {L"notify", 4, (void*)RootObject_ScriptMethods::notify },
+ {L"onNotify", 4, (void*)RootObject_ScriptMethods::onNotify },
+};
+
+const wchar_t *RootScriptObjectController::getClassName() {
+ return L"Object";
+}
+
+const wchar_t *RootScriptObjectController::getAncestorClassName() {
+ return NULL;
+}
+
+int RootScriptObjectController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *RootScriptObjectController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID RootScriptObjectController::getClassGuid() {
+ return rootObjectGuid;
+}
+
+ScriptObject *RootScriptObjectController::instantiate() {
+ RootObjectInstance *o = new RootObjectInstance;
+ ASSERT(o != NULL);
+ return o->getScriptObject();
+}
+
+void RootScriptObjectController::destroy(ScriptObject *o) {
+ RootObjectInstance *obj = static_cast<RootObjectInstance *>(o->vcpu_getInterface(rootObjectGuid));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void RootScriptObjectController::deencapsulate(void *o) {
+ RootObjectI *obj = static_cast<RootObjectI *>(o);
+ delete obj;
+}
+
+void *RootScriptObjectController::encapsulate(ScriptObject *o) {
+ return new RootObjectI(o);
+}
+
+// -------------------------------------------------------------------------------------------------------------------------------------
+// Script Methods and Events for RootObject (Object)
+// -------------------------------------------------------------------------------------------------------------------------------------
+
+scriptVar RootObject_ScriptMethods::getClassName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(o->vcpu_getClassName());
+}
+
+scriptVar RootObject_ScriptMethods::onNotify(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s, scriptVar s2, scriptVar i1, scriptVar i2) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS4(o, rootScriptObjectController, s, s2, i1, i2);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, s, s2, i1, i2);
+}
+
+scriptVar RootObject_ScriptMethods::notify(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s, scriptVar s2, scriptVar i1, scriptVar i2) {
+ SCRIPT_FUNCTION_INIT
+ RootObject *ro = static_cast<RootObject*>(o->vcpu_getInterface(rootObjectGuid));
+ if (ro) ro->rootobject_notify(GET_SCRIPT_STRING(s), GET_SCRIPT_STRING(s2), GET_SCRIPT_INT(i1), GET_SCRIPT_INT(i2));
+ RETURN_SCRIPT_VOID;
+}
diff --git a/Src/Wasabi/api/script/objects/rootobjcontroller.h b/Src/Wasabi/api/script/objects/rootobjcontroller.h
new file mode 100644
index 00000000..4dbb81fb
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjcontroller.h
@@ -0,0 +1,36 @@
+#ifndef __ROOTSCRIPTOBJECTCONTROLLER_IMPL_H
+#define __ROOTSCRIPTOBJECTCONTROLLER_IMPL_H
+
+#include <api/script/objcontroller.h>
+/*<?<autoheader/>*/
+class ScriptObject;
+class ScriptObjectController;
+/*?>*/
+
+class RootScriptObjectController : public ScriptObjectControllerI
+{
+ public:
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return NULL; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual void *encapsulate(ScriptObject *o);
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+class RootObject_ScriptMethods {
+ public:
+ static scriptVar getClassName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar onNotify(SCRIPT_FUNCTION_PARAMS, ScriptObject *on, scriptVar s, scriptVar s2, scriptVar i1, scriptVar i2);
+ static scriptVar notify(SCRIPT_FUNCTION_PARAMS, ScriptObject *on, scriptVar s, scriptVar s2, scriptVar i1, scriptVar i2);
+};
+
+extern RootScriptObjectController *rootScriptObjectController;
+
+#endif // __ROOTSCRIPTOBJECTCONTROLLER_IMPL_H
diff --git a/Src/Wasabi/api/script/objects/rootobject.cpp b/Src/Wasabi/api/script/objects/rootobject.cpp
new file mode 100644
index 00000000..1ebc36f1
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobject.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri May 16 23:15:13 2003]
+//
+// File : rootobject.cpp
+// Class : RootObject
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "rootobject.h"
+
+
diff --git a/Src/Wasabi/api/script/objects/rootobject.h b/Src/Wasabi/api/script/objects/rootobject.h
new file mode 100644
index 00000000..c18fd1f9
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobject.h
@@ -0,0 +1,71 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri May 16 23:15:13 2003]
+//
+// File : rootobject.h
+// Class : RootObject
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __ROOTOBJECT_H
+#define __ROOTOBJECT_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+class RootObjectCallback;
+class ScriptObject;
+
+
+
+#include <api/script/objects/rootobjcontroller.h>
+
+// ----------------------------------------------------------------------------
+
+class RootObject: public Dispatchable {
+ protected:
+ RootObject() {}
+ ~RootObject() {}
+ public:
+ const wchar_t *rootobject_getClassName();
+ void rootobject_notify(const wchar_t *s, const wchar_t *t, int u, int v);
+ ScriptObject *rootobject_getScriptObject();
+ void rootobject_setScriptObject(ScriptObject *obj);
+ void rootobject_addCB(RootObjectCallback *cb);
+
+ protected:
+ enum {
+ ROOTOBJECT_ROOTOBJECT_GETCLASSNAME = 10,
+ ROOTOBJECT_ROOTOBJECT_NOTIFY = 20,
+ ROOTOBJECT_ROOTOBJECT_GETSCRIPTOBJECT = 30,
+ ROOTOBJECT_ROOTOBJECT_SETSCRIPTOBJECT = 40,
+ ROOTOBJECT_ROOTOBJECT_ADDCB = 50,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline const wchar_t *RootObject::rootobject_getClassName() {
+ const wchar_t *__retval = _call(ROOTOBJECT_ROOTOBJECT_GETCLASSNAME, (const wchar_t *)0);
+ return __retval;
+}
+
+inline void RootObject::rootobject_notify(const wchar_t *s, const wchar_t *t, int u, int v) {
+ _voidcall(ROOTOBJECT_ROOTOBJECT_NOTIFY, s, t, u, v);
+}
+
+inline ScriptObject *RootObject::rootobject_getScriptObject() {
+ ScriptObject *__retval = _call(ROOTOBJECT_ROOTOBJECT_GETSCRIPTOBJECT, (ScriptObject *)NULL);
+ return __retval;
+}
+
+inline void RootObject::rootobject_setScriptObject(ScriptObject *obj) {
+ _voidcall(ROOTOBJECT_ROOTOBJECT_SETSCRIPTOBJECT, obj);
+}
+
+inline void RootObject::rootobject_addCB(RootObjectCallback *cb) {
+ _voidcall(ROOTOBJECT_ROOTOBJECT_ADDCB, cb);
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __ROOTOBJECT_H
diff --git a/Src/Wasabi/api/script/objects/rootobjecti.cpp b/Src/Wasabi/api/script/objects/rootobjecti.cpp
new file mode 100644
index 00000000..cb6e2f3b
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjecti.cpp
@@ -0,0 +1,46 @@
+#include <precomp.h>
+
+//<?#include "<class data="implementationheader"/>"
+#include "rootobjecti.h"
+//?>
+
+#include <bfc/wasabi_std.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/scriptobj.h>
+#include <bfc/foreach.h>
+
+
+// --------------------------------------------------------------------------------------------
+
+RootObjectI::RootObjectI(ScriptObject *o) {
+ my_script_object = o;
+}
+
+RootObjectI::~RootObjectI() {
+}
+
+const wchar_t *RootObjectI::rootobject_getClassName()
+{
+ if (!my_script_object) return NULL;
+ return my_script_object->vcpu_getClassName();
+}
+
+void RootObjectI::rootobject_notify(const wchar_t *s, const wchar_t *t, int u, int v) {
+ foreach(cbs)
+ cbs.getfor()->rootobjectcb_onNotify(s, t, u, v);
+ endfor;
+ RootObject_ScriptMethods::onNotify(SCRIPT_CALL, rootobject_getScriptObject(), MAKE_SCRIPT_STRING(s), MAKE_SCRIPT_STRING(t), MAKE_SCRIPT_INT(u), MAKE_SCRIPT_INT(v));
+}
+
+ScriptObject *RootObjectI::rootobject_getScriptObject() {
+ return my_script_object;
+}
+
+void RootObjectI::rootobject_setScriptObject(ScriptObject *obj) {
+ my_script_object = obj;
+}
+
+void RootObjectI::rootobject_addCB(RootObjectCallback *cb) {
+ cbs.addItem(cb);
+}
+
diff --git a/Src/Wasabi/api/script/objects/rootobjecti.h b/Src/Wasabi/api/script/objects/rootobjecti.h
new file mode 100644
index 00000000..a76361e2
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjecti.h
@@ -0,0 +1,32 @@
+#ifndef __ROOTOBJECTI_IMPL_H
+#define __ROOTOBJECTI_IMPL_H
+
+/*<?<autoheader/>*/
+#include "rootobject.h"
+#include "rootobjectx.h"
+
+class RootObjectCallback;
+class ScriptObject;
+/*?>*/
+
+/*[interface.header.h]
+#include "common/script/rootobjcontroller.h"
+*/
+
+extern RootScriptObjectController *rootScriptObjectController;
+
+class RootObjectI : public RootObjectX {
+public:
+ RootObjectI(ScriptObject *o);
+ virtual ~RootObjectI();
+ DISPATCH(10) virtual const wchar_t *rootobject_getClassName();
+ DISPATCH(20) virtual void rootobject_notify(const wchar_t *s, const wchar_t *t, int u, int v);
+ DISPATCH(30) virtual ScriptObject *rootobject_getScriptObject();
+ DISPATCH(40) virtual void rootobject_setScriptObject(ScriptObject *obj);
+ DISPATCH(50) virtual void rootobject_addCB(RootObjectCallback *cb);
+ PtrList < RootObjectCallback > cbs;
+ ScriptObject * my_script_object;
+};
+
+
+#endif // __ROOTOBJECTI_IMPL_H
diff --git a/Src/Wasabi/api/script/objects/rootobjectx.cpp b/Src/Wasabi/api/script/objects/rootobjectx.cpp
new file mode 100644
index 00000000..824a6825
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjectx.cpp
@@ -0,0 +1,22 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri May 16 23:15:13 2003]
+//
+// File : rootobjectx.cpp
+// Class : RootObject
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include "precomp.h"
+
+#include "rootobjectx.h"
+#include "rootobjecti.h"
+
+#define CBCLASS RootObjectX
+START_DISPATCH;
+ CB(ROOTOBJECT_ROOTOBJECT_GETCLASSNAME, rootobject_getClassName);
+ VCB(ROOTOBJECT_ROOTOBJECT_NOTIFY, rootobject_notify);
+ CB(ROOTOBJECT_ROOTOBJECT_GETSCRIPTOBJECT, rootobject_getScriptObject);
+ VCB(ROOTOBJECT_ROOTOBJECT_SETSCRIPTOBJECT, rootobject_setScriptObject);
+ VCB(ROOTOBJECT_ROOTOBJECT_ADDCB, rootobject_addCB);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/script/objects/rootobjectx.h b/Src/Wasabi/api/script/objects/rootobjectx.h
new file mode 100644
index 00000000..687293a7
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/rootobjectx.h
@@ -0,0 +1,35 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Fri May 16 23:15:13 2003]
+//
+// File : rootobjectx.h
+// Class : RootObject
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __ROOTOBJECTX_H
+#define __ROOTOBJECTX_H
+
+#include "rootobject.h"
+
+class RootObjectCallback;
+class ScriptObject;
+
+
+
+// ----------------------------------------------------------------------------
+
+class RootObjectX : public RootObject {
+ protected:
+ RootObjectX() {}
+ public:
+ virtual const wchar_t *rootobject_getClassName()=0;
+ virtual void rootobject_notify(const wchar_t *s, const wchar_t *t, int u, int v)=0;
+ virtual ScriptObject *rootobject_getScriptObject()=0;
+ virtual void rootobject_setScriptObject(ScriptObject *obj)=0;
+ virtual void rootobject_addCB(RootObjectCallback *cb)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __ROOTOBJECTX_H
diff --git a/Src/Wasabi/api/script/objects/sapplication.cpp b/Src/Wasabi/api/script/objects/sapplication.cpp
new file mode 100644
index 00000000..d1dca910
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sapplication.cpp
@@ -0,0 +1,213 @@
+#include "sapplication.h"
+#include <api/application/api_application.h>
+#include <api.h>
+
+// {B8E867B0-2715-4da7-A5BA-53DBA1FCFEAC}
+static const GUID application_script_object_guid =
+{ 0xb8e867b0, 0x2715, 0x4da7, { 0xa5, 0xba, 0x53, 0xdb, 0xa1, 0xfc, 0xfe, 0xac } };
+
+static ApplicationScriptObjectController _applicationController;
+ScriptObjectController *applicationController=&_applicationController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ApplicationScriptObjectController::exportedFunction[] =
+{
+ {L"GetApplicationName", 0, (void*)SApplication::GetApplicationName },
+ {L"GetVersionString", 0, (void*)SApplication::GetVersionString },
+ {L"GetVersionNumberString", 0, (void*)SApplication::GetVersionNumberString },
+ {L"GetBuildNumber",0, (void*)SApplication::GetBuildNumber },
+ {L"GetGUID",0, (void*)SApplication::GetGUID },
+ {L"GetCommandLine",0, (void*)SApplication::GetCommandLine },
+ {L"Shutdown",0, (void*)SApplication::Shutdown },
+ {L"CancelShutdown",0, (void*)SApplication::CancelShutdown },
+ {L"IsShuttingDown",0, (void*)SApplication::IsShuttingDown },
+ {L"GetApplicationPath",0, (void*)SApplication::GetApplicationPath },
+ {L"GetSettingsPath",0, (void*)SApplication::GetSettingsPath },
+ {L"GetWorkingPath",0, (void*)SApplication::GetWorkingPath },
+ {L"SetWorkingPath",1, (void*)SApplication::SetWorkingPath },
+ {L"GetMachineGUID",0, (void*)SApplication::GetMachineGUID },
+ {L"GetUserGUID",0, (void*)SApplication::GetUserGUID },
+ {L"GetSessionGUID",0, (void*)SApplication::GetSessionGUID },
+};
+// --------------------------------------------------------
+
+const wchar_t *ApplicationScriptObjectController::getClassName()
+{
+ return L"Application";
+}
+
+const wchar_t *ApplicationScriptObjectController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObjectController *ApplicationScriptObjectController::getAncestorController()
+{
+ return NULL;
+}
+
+ScriptObject *ApplicationScriptObjectController::instantiate()
+{
+ SApplication *c = new SApplication;
+ if (!c) return NULL;
+ return c->getScriptObject();
+}
+
+int ApplicationScriptObjectController::getInstantiable()
+{
+ return 0;
+}
+
+void ApplicationScriptObjectController::destroy(ScriptObject *o)
+{
+ SApplication *obj = static_cast<SApplication *>(o->vcpu_getInterface(application_script_object_guid));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *ApplicationScriptObjectController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void ApplicationScriptObjectController::deencapsulate(void *o)
+{
+}
+
+int ApplicationScriptObjectController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ApplicationScriptObjectController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID ApplicationScriptObjectController::getClassGuid()
+{
+ return application_script_object_guid;
+}
+
+
+SApplication::SApplication()
+{
+ getScriptObject()->vcpu_setInterface(application_script_object_guid, static_cast<SApplication *>(this));
+ getScriptObject()->vcpu_setClassName(L"Application");
+ getScriptObject()->vcpu_setController(applicationController);
+}
+SApplication::~SApplication()
+{
+}
+
+static wchar_t guid_scratchpad[40];
+
+scriptVar SApplication::GetApplicationName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->main_getAppName());
+}
+
+scriptVar SApplication::GetVersionString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->main_getVersionString());
+}
+
+scriptVar SApplication::GetVersionNumberString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->main_getVersionNumString());
+}
+
+scriptVar SApplication::GetBuildNumber(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT(WASABI_API_APP->main_getBuildNumber());
+}
+
+scriptVar SApplication::GetGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ GUID g = WASABI_API_APP->main_getGUID();
+ nsGUID::toCharW(g, guid_scratchpad);
+ return MAKE_SCRIPT_STRING(guid_scratchpad);
+}
+
+scriptVar SApplication::GetCommandLine(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->main_getCommandLine());
+}
+
+scriptVar SApplication::Shutdown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ WASABI_API_APP->main_shutdown();
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SApplication::CancelShutdown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ WASABI_API_APP->main_cancelShutdown();
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SApplication::IsShuttingDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_BOOLEAN(WASABI_API_APP->main_isShuttingDown());
+}
+
+scriptVar SApplication::GetApplicationPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->path_getAppPath());
+}
+
+scriptVar SApplication::GetSettingsPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->path_getUserSettingsPath());
+}
+
+scriptVar SApplication::GetWorkingPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING(WASABI_API_APP->path_getWorkingPath());
+}
+
+scriptVar SApplication::SetWorkingPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar string_path)
+{
+ SCRIPT_FUNCTION_INIT;
+ WASABI_API_APP->path_setWorkingPath(GET_SCRIPT_STRING(string_path));
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SApplication::GetMachineGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ GUID g;
+ WASABI_API_APP->GetMachineID(&g);
+ nsGUID::toCharW(g, guid_scratchpad);
+ return MAKE_SCRIPT_STRING(guid_scratchpad);
+}
+
+scriptVar SApplication::GetUserGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ GUID g;
+ WASABI_API_APP->GetUserID(&g);
+ nsGUID::toCharW(g, guid_scratchpad);
+ return MAKE_SCRIPT_STRING(guid_scratchpad);
+}
+
+scriptVar SApplication::GetSessionGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ GUID g;
+ WASABI_API_APP->GetSessionID(&g);
+ nsGUID::toCharW(g, guid_scratchpad);
+ return MAKE_SCRIPT_STRING(guid_scratchpad);
+}
diff --git a/Src/Wasabi/api/script/objects/sapplication.h b/Src/Wasabi/api/script/objects/sapplication.h
new file mode 100644
index 00000000..f6ec099f
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sapplication.h
@@ -0,0 +1,57 @@
+#pragma once
+#include <api/script/api_maki.h>
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+
+#define SApplication_SCRIPTPARENT RootObjectInstance
+
+class ApplicationScriptObjectController : public ScriptObjectControllerI
+{
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual int getInstantiable();
+ virtual int getReferenceable() {return 0;}
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern ScriptObjectController *applicationController;
+
+class SApplication : public SApplication_SCRIPTPARENT
+{
+public:
+ SApplication();
+ virtual ~SApplication();
+
+public:
+ static scriptVar GetApplicationName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetVersionString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetVersionNumberString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetBuildNumber(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetCommandLine(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar Shutdown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar CancelShutdown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar IsShuttingDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetApplicationPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetSettingsPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetWorkingPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar SetWorkingPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar string_path);
+ static scriptVar GetMachineGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetUserGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar GetSessionGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
diff --git a/Src/Wasabi/api/script/objects/sbitlist.cpp b/Src/Wasabi/api/script/objects/sbitlist.cpp
new file mode 100644
index 00000000..d41afa47
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sbitlist.cpp
@@ -0,0 +1,118 @@
+#include <precomp.h>
+#include "sbitlist.h"
+#include <bfc/bitlist.h>
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+
+// {87C65778-E743-49fe-85F9-09CC532AFD56}
+static const GUID bitlistGuid =
+{ 0x87c65778, 0xe743, 0x49fe, { 0x85, 0xf9, 0x9, 0xcc, 0x53, 0x2a, 0xfd, 0x56 } };
+
+BitlistScriptController _bitlistController;
+BitlistScriptController *bitlistController = &_bitlistController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct BitlistScriptController::exportedFunction[] = {
+ {L"getItem", 1, (void*)SBitlist::script_vcpu_getitem },
+ {L"setItem", 2, (void*)SBitlist::script_vcpu_setitem },
+ {L"setSize", 1, (void*)SBitlist::script_vcpu_setsize },
+ {L"getSize", 0, (void*)SBitlist::script_vcpu_getsize },
+};
+// --------------------------------------------------------
+
+const wchar_t *BitlistScriptController::getClassName() {
+ return L"BitList";
+}
+
+const wchar_t *BitlistScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObject *BitlistScriptController::instantiate() {
+ SBitlist *bl = new SBitlist;
+ ASSERT(bl != NULL);
+ return bl->getScriptObject();
+}
+
+void BitlistScriptController::destroy(ScriptObject *o)
+{
+ // TODO?
+ SBitlist *bl = static_cast<SBitlist *>(o->vcpu_getInterface(bitlistGuid));
+}
+
+void *BitlistScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for bitlist yet
+}
+
+void BitlistScriptController::deencapsulate(void *o) {
+}
+
+int BitlistScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *BitlistScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID BitlistScriptController::getClassGuid() {
+ return bitlistGuid;
+}
+
+//-------------------------------------------------------------------------------------------------------------
+
+
+SBitlist::SBitlist() {
+ list = new BitList;
+ getScriptObject()->vcpu_setInterface(bitlistGuid, (void *)static_cast<SBitlist *>(this));
+ getScriptObject()->vcpu_setClassName(L"BitList");
+ getScriptObject()->vcpu_setController(bitlistController);
+}
+
+SBitlist::~SBitlist() {
+ delete list;
+}
+
+BitList *SBitlist::getBitList() {
+ return list;
+}
+
+scriptVar SBitlist::script_vcpu_getitem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&n)); // Compiler shouldn't do this
+ scriptVar r;
+ r = SOM::makeVar(SCRIPT_INT);
+ SBitlist *bl = static_cast<SBitlist *>(o->vcpu_getInterface(bitlistGuid));
+ if (bl) SOM::assign(&r, bl->getBitList()->getitem(SOM::makeInt(&n)));
+ return r;
+}
+
+scriptVar SBitlist::script_vcpu_setitem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n, scriptVar v) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&n)); // Compiler shouldn't do this
+ ASSERT(SOM::isNumeric(&v)); // Compiler shouldn't do this
+ SBitlist *bl = static_cast<SBitlist *>(o->vcpu_getInterface(bitlistGuid));
+ if (bl) bl->getBitList()->setitem(SOM::makeInt(&n), SOM::makeBoolean(&v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SBitlist::script_vcpu_setsize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newsize) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&newsize)); // Compiler shouldn't do this
+ SBitlist *bl = static_cast<SBitlist *>(o->vcpu_getInterface(bitlistGuid));
+ if (bl) bl->getBitList()->setSize(SOM::makeInt(&newsize));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SBitlist::script_vcpu_getsize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ scriptVar r;
+ r = SOM::makeVar(SCRIPT_INT);
+ SBitlist *bl = static_cast<SBitlist *>(o->vcpu_getInterface(bitlistGuid));
+ if (bl) SOM::assign(&r, bl->getBitList()->getsize());
+ return r;
+}
+
+
+
diff --git a/Src/Wasabi/api/script/objects/sbitlist.h b/Src/Wasabi/api/script/objects/sbitlist.h
new file mode 100644
index 00000000..9c6f023a
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sbitlist.h
@@ -0,0 +1,56 @@
+#ifndef __SBITLIST_H
+#define __SBITLIST_H
+
+#include <api/script/objects/rootobj.h>
+
+#include <api/script/script.h>
+#include <api/script/objects/rootobject.h>
+
+class BitList;
+
+#define SBITLIST_SCRIPTPARENT RootObjectInstance
+
+class BitlistScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern BitlistScriptController *bitlistController;
+
+
+class SBitlist : public SBITLIST_SCRIPTPARENT {
+
+public:
+ SBitlist();
+ virtual ~SBitlist();
+
+ BitList *getBitList();
+
+private:
+
+ BitList *list;
+
+public:
+ static scriptVar script_vcpu_getitem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_setitem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n, scriptVar v);
+ static scriptVar script_vcpu_setsize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newsize);
+ static scriptVar script_vcpu_getsize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/scolor.cpp b/Src/Wasabi/api/script/objects/scolor.cpp
new file mode 100644
index 00000000..cd00642d
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/scolor.cpp
@@ -0,0 +1,236 @@
+#include <precomp.h>
+#include "SColor.h"
+#include <api.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+#include <api/imgldr/imgldr.h>
+
+
+// {95DDB221-00E3-4e2b-8EA5-833548C13C10}
+static const GUID colorSoGuid =
+{ 0x95ddb221, 0xe3, 0x4e2b, { 0x8e, 0xa5, 0x83, 0x35, 0x48, 0xc1, 0x3c, 0x10 } };
+
+
+colorScriptController _colorController;
+colorScriptController *colorController=&_colorController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct colorScriptController::exportedFunction[] = {
+ {L"getID", 0, (void*)SColor::script_vcpu_getColorID },
+ {L"getRed", 0, (void*)SColor::script_vcpu_getRed },
+ {L"getGreen", 0, (void*)SColor::script_vcpu_getGreen },
+ {L"getBlue", 0, (void*)SColor::script_vcpu_getBlue },
+ {L"getAlpha", 0, (void*)SColor::script_vcpu_getAlpha },
+ {L"getGreenWithGamma", 0, (void*)SColor::script_vcpu_getGreenWithGamma },
+ {L"getBlueWithGamma", 0, (void*)SColor::script_vcpu_getBlueWithGamma },
+ {L"getRedWithGamma", 0, (void*)SColor::script_vcpu_getRedWithGamma },
+ {L"getGammagroup", 0, (void*)SColor::script_vcpu_getGammagroup },
+};
+// --------------------------------------------------------
+
+const wchar_t *colorScriptController::getClassName() {
+ return L"Color";
+}
+
+const wchar_t *colorScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *colorScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *colorScriptController::instantiate() {
+ SColor *xd = new SColor;
+ ASSERT(xd != NULL);
+ return xd->getScriptObject();
+}
+
+void colorScriptController::destroy(ScriptObject *o) {
+ SColor *xd = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ ASSERT(xd != NULL);
+ delete xd;
+}
+
+void *colorScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for now
+}
+
+void colorScriptController::deencapsulate(void *o) {
+}
+
+int colorScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *colorScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID colorScriptController::getClassGuid() {
+ return colorSoGuid;
+}
+
+void SColor::__construct()
+{
+ getScriptObject()->vcpu_setInterface(colorSoGuid, (void *)static_cast<SColor *>(this));
+ getScriptObject()->vcpu_setClassName(L"Color");
+ getScriptObject()->vcpu_setController(colorController);
+ gammagroup = NULL;
+ colorID = NULL;
+ color = 0;
+}
+
+SColor::SColor()
+{
+ SColor::__construct();
+}
+
+SColor::SColor(const wchar_t* colorID)
+{
+ __construct();
+ this->colorID = colorID;
+ color = WASABI_API_PALETTE->getColorElement(colorID, &gammagroup);
+}
+
+SColor::SColor(int n)
+{
+ __construct();
+ colorID = WASABI_API_PALETTE->enumColorElement(n);
+ color = WASABI_API_PALETTE->getColorElement(colorID, &gammagroup);
+}
+
+SColor::~SColor()
+{
+}
+
+int SColor::getARGBValue(int whichCol)
+{
+
+ whichCol %= 4;
+
+ /**
+ whichCol
+ 0: red
+ 1: green
+ 2: blue
+ 3: alpha
+ */
+
+ ARGB32 c = this->color;
+
+ c = c >> (whichCol * 8);
+ c &= 0x000000FF;
+
+ return (int)c;
+}
+
+int SColor::getARGBValueWithGamma(int whichCol)
+{
+ ARGB32 c = imageLoader::filterSkinColor(this->color, this->colorID, NULL);
+ whichCol %= 4;
+
+ /**
+ whichCol
+ 0: red
+ 1: green
+ 2: blue
+ 3: alpha
+ */
+
+ c = c >> (whichCol * 8);
+ c &= 0x000000FF;
+
+ return (int)c;
+}
+
+// VCPU
+
+scriptVar SColor::script_vcpu_getBlue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValue(2));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getGreen(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValue(1));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getRed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValue(0));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getBlueWithGamma(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValueWithGamma(2));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getGreenWithGamma(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValueWithGamma(1));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getRedWithGamma(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValueWithGamma(0));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->getARGBValue(3));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SColor::script_vcpu_getColorID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_STRING(m->colorID);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar SColor::script_vcpu_getGammagroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SColor *m = static_cast<SColor *>(o->vcpu_getInterface(colorSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_STRING(m->gammagroup?m->gammagroup:L"");
+ }
+ return MAKE_SCRIPT_STRING(L"");
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/scolor.h b/Src/Wasabi/api/script/objects/scolor.h
new file mode 100644
index 00000000..94f03671
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/scolor.h
@@ -0,0 +1,66 @@
+#ifndef __SColor_H
+#define __SColor_H
+
+class SColor;
+
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+#include <api/skin/skinelem.h>
+#include <api/skin/gammamgr.h>
+#define SCOLOR_SCRIPTPARENT RootObjectInstance
+
+class colorScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern colorScriptController *colorController;
+
+class SColor : public SCOLOR_SCRIPTPARENT {
+public:
+ SColor();
+ SColor(const wchar_t*);
+ SColor(int i);
+ virtual ~SColor();
+ void enumColor(int n);
+ int getARGBValue(int whichCol);
+ int getARGBValueWithGamma(int whichCol);
+
+protected:
+ const wchar_t *gammagroup;
+ const wchar_t *colorID;
+ ARGB32 color;
+
+private:
+ void __construct();
+
+public:
+ static scriptVar script_vcpu_getRed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGreen(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBlue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getRedWithGamma(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGreenWithGamma(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBlueWithGamma(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGammagroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getColorID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/scolormgr.cpp b/Src/Wasabi/api/script/objects/scolormgr.cpp
new file mode 100644
index 00000000..fb135bdf
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/scolormgr.cpp
@@ -0,0 +1,235 @@
+#include <precomp.h>
+#include "SColorMgr.h"
+#include <api.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+
+
+// {AEE235FF-EBD1-498f-96AF-D7E0DAD4541A}
+static const GUID colorMgrSoGuid =
+{ 0xaee235ff, 0xebd1, 0x498f, { 0x96, 0xaf, 0xd7, 0xe0, 0xda, 0xd4, 0x54, 0x1a } };
+
+ColorMgrScriptController _colorMgrController;
+ColorMgrScriptController *colorMgrController=&_colorMgrController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ColorMgrScriptController::exportedFunction[] = {
+ {L"getColor", 1, (void*)SColorMgr::script_vcpu_getColor },
+ {L"enumColor", 1, (void*)SColorMgr::script_vcpu_enumColor },
+ {L"getNumColors", 0, (void*)SColorMgr::script_vcpu_getNumColors },
+ {L"getGammaSet", 1, (void*)SColorMgr::script_vcpu_getGammaSet },
+ {L"getCurrentGammaSet", 0, (void*)SColorMgr::script_vcpu_getCurrentGammaSet },
+ {L"enumGammaSet", 1, (void*)SColorMgr::script_vcpu_enumGammaSet },
+ {L"getNumGammaSets", 0, (void*)SColorMgr::script_vcpu_getNumGammaSets },
+ {L"onGuiLoaded", 0, (void*)SColorMgr::script_vcpu_onGuiLoaded },
+ {L"onLoaded", 0, (void*)SColorMgr::script_vcpu_onLoaded },
+ {L"newGammaSet", 1, (void*)SColorMgr::script_vcpu_newGammaSet },
+ {L"onBeforeLoadingElements", 0, (void*)SColorMgr::script_vcpu_onBeforeLoadingElements },
+ {L"onColorThemeChanged", 1, (void*)SColorMgr::script_vcpu_onColorThemeChanged },
+ {L"onColorThemesListChanged", 0, (void*)SColorMgr::script_vcpu_onColorThemesListChanged },
+};
+// --------------------------------------------------------
+
+const wchar_t *ColorMgrScriptController::getClassName() {
+ return L"ColorMgr";
+}
+
+const wchar_t *ColorMgrScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *ColorMgrScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *ColorMgrScriptController::instantiate() {
+ SColorMgr *xd = new SColorMgr;
+ ASSERT(xd != NULL);
+ return xd->getScriptObject();
+}
+
+void ColorMgrScriptController::destroy(ScriptObject *o) {
+ SColorMgr *xd = static_cast<SColorMgr *>(o->vcpu_getInterface(colorMgrSoGuid));
+ ASSERT(xd != NULL);
+ delete xd;
+}
+
+void *ColorMgrScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for now
+}
+
+void ColorMgrScriptController::deencapsulate(void *o) {
+}
+
+int ColorMgrScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ColorMgrScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID ColorMgrScriptController::getClassGuid() {
+ return colorMgrSoGuid;
+}
+
+SColorMgr::SColorMgr()
+{
+ getScriptObject()->vcpu_setInterface(colorMgrSoGuid, (void *)static_cast<SColorMgr *>(this));
+ getScriptObject()->vcpu_setClassName(L"ColorMgr");
+ getScriptObject()->vcpu_setController(colorMgrController);
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+}
+
+SColorMgr::~SColorMgr()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+}
+
+int SColorMgr::skincb_onGuiLoaded ()
+{
+ script_vcpu_onGuiLoaded(SCRIPT_CALL, this->getScriptObject());
+ return 0;
+}
+
+int SColorMgr::skincb_onLoaded ()
+{
+ script_vcpu_onLoaded(SCRIPT_CALL, this->getScriptObject());
+ return 0;
+}
+
+int SColorMgr::skincb_onBeforeLoadingElements ()
+{
+ script_vcpu_onBeforeLoadingElements(SCRIPT_CALL, this->getScriptObject());
+ return 0;
+}
+
+int SColorMgr::skincb_onColorThemeChanged (const wchar_t* newcolortheme)
+{
+ script_vcpu_onColorThemeChanged(SCRIPT_CALL, this->getScriptObject(), MAKE_SCRIPT_STRING(newcolortheme));
+ return 0;
+}
+
+
+int SColorMgr::skincb_onColorThemesListChanged()
+{
+ script_vcpu_onColorThemesListChanged(SCRIPT_CALL, this->getScriptObject());
+ return 0;
+}
+
+
+// VCPU
+
+scriptVar SColorMgr::script_vcpu_getColor(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar colorID)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(colorID.type == SCRIPT_STRING);
+ ScriptObject *s = NULL;
+ SColor *sc = new SColor(colorID.data.sdata);
+ if (sc != NULL) s = sc->getScriptObject();
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SColorMgr::script_vcpu_enumColor(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(n.type == SCRIPT_INT);
+ ScriptObject *s = NULL;
+ SColor *sc = new SColor(n.data.idata);
+ if (sc != NULL) s = sc->getScriptObject();
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SColorMgr::script_vcpu_getNumColors(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT(WASABI_API_PALETTE->getNumColorElements());
+}
+
+scriptVar SColorMgr::script_vcpu_getGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar colorID)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(colorID.type == SCRIPT_STRING);
+ ScriptObject *s = NULL;
+ SGammaset *gs = new SGammaset(colorID.data.sdata);
+ if (gs != NULL) s = gs->getScriptObject();
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SColorMgr::script_vcpu_newGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar colorID)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(colorID.type == SCRIPT_STRING);
+ WASABI_API_COLORTHEMES->newGammaSet(colorID.data.sdata);
+ ScriptObject *s = NULL;
+ SGammaset *gs = new SGammaset(colorID.data.sdata);
+ if (gs != NULL) s = gs->getScriptObject();
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SColorMgr::script_vcpu_enumGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(n.type == SCRIPT_INT);
+ ScriptObject *s = NULL;
+ SGammaset *gs = new SGammaset(n.data.idata);
+ if (gs != NULL) s = gs->getScriptObject();
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SColorMgr::script_vcpu_getCurrentGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ ScriptObject *s = NULL;
+ const wchar_t * cur = WASABI_API_COLORTHEMES->getGammaSet();
+ SGammaset *gs = NULL;
+ if (cur != NULL) new SGammaset(cur);
+ if (gs != NULL) s = gs->getScriptObject();
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SColorMgr::script_vcpu_getNumGammaSets(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT(WASABI_API_COLORTHEMES->getNumGammaSets());
+}
+
+scriptVar SColorMgr::script_vcpu_onGuiLoaded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, colorMgrController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar SColorMgr::script_vcpu_onLoaded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, colorMgrController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+
+scriptVar SColorMgr::script_vcpu_onBeforeLoadingElements(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, colorMgrController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar SColorMgr::script_vcpu_onColorThemesListChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, colorMgrController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar SColorMgr::script_vcpu_onColorThemeChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newTheme)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, colorMgrController, newTheme);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newTheme);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/scolormgr.h b/Src/Wasabi/api/script/objects/scolormgr.h
new file mode 100644
index 00000000..35258e2d
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/scolormgr.h
@@ -0,0 +1,66 @@
+#ifndef __SColorMgr_H
+#define __SColorMgr_H
+
+class SColorMgr;
+
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+#include <api/skin/skinelem.h>
+#include <api/skin/gammamgr.h>
+#include "scolor.h"
+#include "sgammaset.h"
+#define SCOLORMGR_SCRIPTPARENT RootObjectInstance
+
+class ColorMgrScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern ColorMgrScriptController *colorMgrController;
+
+class SColorMgr : public SCOLORMGR_SCRIPTPARENT, public SkinCallbackI {
+public:
+ SColorMgr();
+ virtual ~SColorMgr();
+
+ virtual int skincb_onBeforeLoadingElements();
+ virtual int skincb_onGuiLoaded();
+ virtual int skincb_onLoaded();
+ virtual int skincb_onColorThemeChanged(const wchar_t *newcolortheme);
+ virtual int skincb_onColorThemesListChanged();
+
+public:
+ static scriptVar script_vcpu_getColor(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar colorID);
+ static scriptVar script_vcpu_enumColor(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_getNumColors(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getCurrentGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar colorID);
+ static scriptVar script_vcpu_enumGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_getNumGammaSets(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_newGammaSet(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar colorID);
+
+ static scriptVar script_vcpu_onBeforeLoadingElements(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onGuiLoaded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onColorThemeChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newcolortheme);
+ static scriptVar script_vcpu_onColorThemesListChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onLoaded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/sfile.cpp b/Src/Wasabi/api/script/objects/sfile.cpp
new file mode 100644
index 00000000..e7feaaac
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sfile.cpp
@@ -0,0 +1,119 @@
+#include <precomp.h>
+#include "SFile.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+
+
+// {836F8B2E-E0D1-4db4-937F-0D0A04C8DCD1}
+static const GUID fileGuid =
+{ 0x836f8b2e, 0xe0d1, 0x4db4, { 0x93, 0x7f, 0xd, 0xa, 0x4, 0xc8, 0xdc, 0xd1 } };
+
+
+fileScriptController _fileController;
+fileScriptController *fileController=&_fileController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct fileScriptController::exportedFunction[] = {
+ {L"load", 1, (void*)SFile::script_vcpu_load },
+ {L"getSize", 0, (void*)SFile::script_vcpu_getSize },
+ {L"exists", 0, (void*)SFile::script_vcpu_exists },
+};
+// --------------------------------------------------------
+
+const wchar_t *fileScriptController::getClassName() {
+ return L"File";
+}
+
+const wchar_t *fileScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *fileScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *fileScriptController::instantiate() {
+ SFile *xd = new SFile;
+ ASSERT(xd != NULL);
+ return xd->getScriptObject();
+}
+
+void fileScriptController::destroy(ScriptObject *o) {
+ SFile *xd = static_cast<SFile *>(o->vcpu_getInterface(fileGuid));
+ ASSERT(xd != NULL);
+ delete xd;
+}
+
+void *fileScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for files for now
+}
+
+void fileScriptController::deencapsulate(void *o) {
+}
+
+int fileScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *fileScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID fileScriptController::getClassGuid() {
+ return fileGuid;
+}
+
+
+
+SFile::SFile() {
+ getScriptObject()->vcpu_setInterface(fileGuid, (void *)static_cast<SFile *>(this));
+ getScriptObject()->vcpu_setClassName(L"File");
+ getScriptObject()->vcpu_setController(fileController);
+ filename = NULL;
+}
+
+SFile::~SFile() {
+ //if (bmp) delete bmp;
+}
+
+void SFile::loadfile(const wchar_t *b)
+{
+ filename = b;
+}
+
+// VCPU
+
+scriptVar SFile::script_vcpu_load(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar fn) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(fn.type == SCRIPT_STRING);
+ SFile *m = static_cast<SFile *>(o->vcpu_getInterface(fileGuid));
+ if (m) m->loadfile(fn.data.sdata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SFile::script_vcpu_getSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SFile *m = static_cast<SFile *>(o->vcpu_getInterface(fileGuid));
+ if (m)
+ {
+ OSFILETYPE in = WFOPEN(m->filename, WF_READONLY_BINARY);
+ if (in == OPEN_FAILED) RETURN_SCRIPT_ZERO;
+ int size = (int)FGETSIZE(in);
+ FCLOSE(in);
+ return MAKE_SCRIPT_INT(size);
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SFile::script_vcpu_exists(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SFile *m = static_cast<SFile *>(o->vcpu_getInterface(fileGuid));
+ if (m)
+ {
+ OSFILETYPE in = WFOPEN(m->filename, WF_READONLY_BINARY);
+ if (in == OPEN_FAILED) return MAKE_SCRIPT_BOOLEAN(0);
+ FCLOSE(in);
+ return MAKE_SCRIPT_BOOLEAN(1);
+ }
+ return MAKE_SCRIPT_BOOLEAN(0);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/sfile.h b/Src/Wasabi/api/script/objects/sfile.h
new file mode 100644
index 00000000..91a0ee9c
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sfile.h
@@ -0,0 +1,53 @@
+#ifndef __SFile_H
+#define __SFile_H
+
+class SFile;
+
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+
+#define SFile_SCRIPTPARENT RootObjectInstance
+
+class fileScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern fileScriptController *fileController;
+
+class SFile : public SFile_SCRIPTPARENT {
+public:
+ SFile();
+ virtual ~SFile();
+
+
+ void loadfile(const wchar_t *b);
+
+
+protected:
+ const wchar_t *filename;
+
+public:
+ static scriptVar script_vcpu_load(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar fn);
+ static scriptVar script_vcpu_getSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_exists(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/sgammagroup.cpp b/Src/Wasabi/api/script/objects/sgammagroup.cpp
new file mode 100644
index 00000000..55c1b872
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sgammagroup.cpp
@@ -0,0 +1,235 @@
+#include <precomp.h>
+#include "SGammagroup.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+
+// {B81F004D-ACBA-453d-A06B-30192A1DA17D}
+static const GUID gammagroupSoGuid =
+{ 0xb81f004d, 0xacba, 0x453d, { 0xa0, 0x6b, 0x30, 0x19, 0x2a, 0x1d, 0xa1, 0x7d } };
+
+
+GammagroupScriptController _gammagroupController;
+GammagroupScriptController *gammagroupController=&_gammagroupController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GammagroupScriptController::exportedFunction[] = {
+ {L"getRed", 0, (void*)SGammagroup::script_vcpu_getRed },
+ {L"getGreen", 0, (void*)SGammagroup::script_vcpu_getGreen },
+ {L"getBlue", 0, (void*)SGammagroup::script_vcpu_getBlue },
+ {L"getBoost", 0, (void*)SGammagroup::script_vcpu_getBoost },
+ {L"getGray", 0, (void*)SGammagroup::script_vcpu_getGray },
+ {L"setRed", 1, (void*)SGammagroup::script_vcpu_setRed },
+ {L"setGreen", 1, (void*)SGammagroup::script_vcpu_setGreen },
+ {L"setBlue", 1, (void*)SGammagroup::script_vcpu_setBlue },
+ {L"setBoost", 1, (void*)SGammagroup::script_vcpu_setBoost },
+ {L"setGray", 1, (void*)SGammagroup::script_vcpu_setGray },
+ {L"getID", 0, (void*)SGammagroup::script_vcpu_getID },
+ {L"setID", 1, (void*)SGammagroup::script_vcpu_setID },
+};
+// --------------------------------------------------------
+
+const wchar_t *GammagroupScriptController::getClassName() {
+ return L"Gammagroup";
+}
+
+const wchar_t *GammagroupScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *GammagroupScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *GammagroupScriptController::instantiate() {
+ SGammagroup *xd = new SGammagroup;
+ ASSERT(xd != NULL);
+ return xd->getScriptObject();
+}
+
+void GammagroupScriptController::destroy(ScriptObject *o) {
+ SGammagroup *xd = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ ASSERT(xd != NULL);
+ delete xd;
+}
+
+void *GammagroupScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for now
+}
+
+void GammagroupScriptController::deencapsulate(void *o) {
+}
+
+int GammagroupScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GammagroupScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID GammagroupScriptController::getClassGuid() {
+ return gammagroupSoGuid;
+}
+
+void SGammagroup::__construct()
+{
+ getScriptObject()->vcpu_setInterface(gammagroupSoGuid, (void *)static_cast<SGammagroup *>(this));
+ getScriptObject()->vcpu_setClassName(L"Gammagroup");
+ getScriptObject()->vcpu_setController(gammagroupController);
+ this->grp = NULL;
+}
+
+SGammagroup::SGammagroup()
+{
+ this->__construct();
+}
+
+SGammagroup::SGammagroup(const wchar_t * parentSet, const wchar_t * grp)
+{
+ this->__construct();
+ this->parentSet = parentSet;
+ this->grp = WASABI_API_COLORTHEMES->getColorThemeGroup(parentSet, grp);
+}
+
+SGammagroup::SGammagroup(const wchar_t * parentSet, int n)
+{
+ this->__construct();
+ this->parentSet = parentSet;
+ for (int i = 0; i < (int)WASABI_API_COLORTHEMES->getNumGammaSets(); i++)
+ {
+ if(WCSICMPSAFE(parentSet, WASABI_API_COLORTHEMES->enumGammaSet(i)))
+ {
+ continue;
+ }
+
+ this->grp = WASABI_API_COLORTHEMES->enumColorThemeGroup(i, n);
+ break;
+ }
+}
+
+SGammagroup::~SGammagroup()
+{
+}
+
+// VCPU
+
+
+scriptVar SGammagroup::script_vcpu_getID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_STRING(m->grp->getName());
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar SGammagroup::script_vcpu_getBlue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->grp->getBlue());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SGammagroup::script_vcpu_getGreen(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->grp->getGreen());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SGammagroup::script_vcpu_getRed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->grp->getRed());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SGammagroup::script_vcpu_getBoost(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->grp->getBoost());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SGammagroup::script_vcpu_getGray(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_INT(m->grp->getGray());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SGammagroup::script_vcpu_setID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ (m->grp->setName(color.data.sdata));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammagroup::script_vcpu_setBlue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ (m->grp->setBlue(color.data.idata));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammagroup::script_vcpu_setGreen(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ (m->grp->setGreen(color.data.idata));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammagroup::script_vcpu_setRed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ (m->grp->setRed(color.data.idata));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammagroup::script_vcpu_setBoost(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ (m->grp->setBoost(color.data.idata));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammagroup::script_vcpu_setGray(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color) {
+ SCRIPT_FUNCTION_INIT;
+ SGammagroup *m = static_cast<SGammagroup *>(o->vcpu_getInterface(gammagroupSoGuid));
+ if (m)
+ {
+ (m->grp->setGray(color.data.idata));
+ }
+ RETURN_SCRIPT_VOID;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/sgammagroup.h b/Src/Wasabi/api/script/objects/sgammagroup.h
new file mode 100644
index 00000000..01113039
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sgammagroup.h
@@ -0,0 +1,66 @@
+#ifndef __SGammagroup_H
+#define __SGammagroup_H
+
+class SGamma;
+
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+#include <api/skin/skinelem.h>
+#include <api/skin/gammamgr.h>
+#define SGAMMAGROUP_SCRIPTPARENT RootObjectInstance
+
+class GammagroupScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern GammagroupScriptController *gammagroupController;
+
+class SGammagroup : public SGAMMAGROUP_SCRIPTPARENT {
+public:
+ SGammagroup();
+ SGammagroup(const wchar_t * parentSet, const wchar_t * grpName);
+ SGammagroup(const wchar_t * parentSet, int i);
+ virtual ~SGammagroup();
+
+//protected:
+ ColorThemeGroup * grp;
+ const wchar_t * parentSet;
+
+private:
+ void __construct();
+
+public:
+ static scriptVar script_vcpu_setRed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color);
+ static scriptVar script_vcpu_setGreen(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color);
+ static scriptVar script_vcpu_setBlue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color);
+ static scriptVar script_vcpu_setBoost(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color);
+ static scriptVar script_vcpu_setGray(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color);
+ static scriptVar script_vcpu_setID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar color);
+
+ static scriptVar script_vcpu_getRed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGreen(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBlue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBoost(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGray(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/sgammaset.cpp b/Src/Wasabi/api/script/objects/sgammaset.cpp
new file mode 100644
index 00000000..e1913e43
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sgammaset.cpp
@@ -0,0 +1,201 @@
+#include <precomp.h>
+#include "SGammaset.h"
+
+#include <api.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+
+// {0D024DB9-9574-42d0-B8C7-26B553F1F987}
+static const GUID gammasetSoGuid =
+{ 0xd024db9, 0x9574, 0x42d0, { 0xb8, 0xc7, 0x26, 0xb5, 0x53, 0xf1, 0xf9, 0x87 } };
+
+GammasetScriptController _gammasetController;
+GammasetScriptController *gammasetController=&_gammasetController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GammasetScriptController::exportedFunction[] = {
+ {L"apply", 0, (void*)SGammaset::script_vcpu_apply },
+ {L"getID", 0, (void*)SGammaset::script_vcpu_getID },
+ {L"rename", 1, (void*)SGammaset::script_vcpu_rename },
+ {L"remove", 0, (void*)SGammaset::script_vcpu_update },
+ {L"delete", 0, (void*)SGammaset::script_vcpu_delete },
+ {L"getGeneralGroup", 0, (void*)SGammaset::script_vcpu_getDefaultGammaGroup },
+ {L"getGammaGroup", 1, (void*)SGammaset::script_vcpu_getGammaGroup },
+ {L"getNumGammaGroups", 0, (void*)SGammaset::script_vcpu_getNumGammaGroups },
+ {L"enumGammaGroup", 0, (void*)SGammaset::script_vcpu_enumGammaGroup },
+};
+// --------------------------------------------------------
+
+const wchar_t *GammasetScriptController::getClassName() {
+ return L"Gammaset";
+}
+
+const wchar_t *GammasetScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *GammasetScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *GammasetScriptController::instantiate() {
+ SGammaset *xd = new SGammaset;
+ ASSERT(xd != NULL);
+ return xd->getScriptObject();
+}
+
+void GammasetScriptController::destroy(ScriptObject *o) {
+ SGammaset *xd = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ ASSERT(xd != NULL);
+ delete xd;
+}
+
+void *GammasetScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for now
+}
+
+void GammasetScriptController::deencapsulate(void *o) {
+}
+
+int GammasetScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GammasetScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID GammasetScriptController::getClassGuid() {
+ return gammasetSoGuid;
+}
+
+void SGammaset::__construct()
+{
+ getScriptObject()->vcpu_setInterface(gammasetSoGuid, (void *)static_cast<SGammaset *>(this));
+ getScriptObject()->vcpu_setClassName(L"Gammaset");
+ getScriptObject()->vcpu_setController(gammasetController);
+ this->gammasetID = NULL;
+}
+
+SGammaset::SGammaset()
+{
+ this->__construct();
+}
+
+SGammaset::SGammaset(const wchar_t * gammaSetID)
+{
+ this->__construct();
+ this->gammasetID = gammaSetID;
+}
+
+SGammaset::SGammaset(int n)
+{
+ this->__construct();
+ this->gammasetID = WASABI_API_COLORTHEMES->enumGammaSet(n);
+}
+
+SGammaset::~SGammaset()
+{
+}
+
+// VCPU
+
+scriptVar SGammaset::script_vcpu_apply(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ WASABI_API_SKIN->colortheme_setColorSet(m->gammasetID);
+ //WASABI_API_COLORTHEMES->setGammaSet(m->gammasetID);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammaset::script_vcpu_update(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ WASABI_API_COLORTHEMES->updateGammaSet(m->gammasetID);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammaset::script_vcpu_delete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ WASABI_API_COLORTHEMES->deleteGammaSet(m->gammasetID);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammaset::script_vcpu_rename(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(name.type == SCRIPT_STRING);
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ WASABI_API_COLORTHEMES->renameGammaSet(m->gammasetID, name.data.sdata);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SGammaset::script_vcpu_getID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ return MAKE_SCRIPT_STRING(m->gammasetID);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar SGammaset::script_vcpu_getDefaultGammaGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ ScriptObject *s = NULL;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ SGammagroup *gg = new SGammagroup(m->gammasetID, -1);
+ if (gg != NULL && gg->grp != NULL) s = gg->getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SGammaset::script_vcpu_getGammaGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(name.type == SCRIPT_STRING);
+ ScriptObject *s = NULL;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ SGammagroup *gg = new SGammagroup(m->gammasetID, GET_SCRIPT_STRING(name));
+ if (gg != NULL) s = gg->getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SGammaset::script_vcpu_enumGammaGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(n.type == SCRIPT_INT);
+ ScriptObject *s = NULL;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ SGammagroup *gg = new SGammagroup(m->gammasetID, GET_SCRIPT_INT(n));
+ if (gg != NULL) s = gg->getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(s);
+}
+
+scriptVar SGammaset::script_vcpu_getNumGammaGroups(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ int n = 0;
+ SGammaset *m = static_cast<SGammaset *>(o->vcpu_getInterface(gammasetSoGuid));
+ if (m)
+ {
+ n = WASABI_API_COLORTHEMES->getNumGammaGroups(m->gammasetID);
+ }
+ return MAKE_SCRIPT_INT(n);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/sgammaset.h b/Src/Wasabi/api/script/objects/sgammaset.h
new file mode 100644
index 00000000..ea4343d4
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sgammaset.h
@@ -0,0 +1,62 @@
+#ifndef __SGammaset_H
+#define __SGammaset_H
+
+class SGamma;
+
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+#include <api/skin/skinelem.h>
+#include <api/skin/gammamgr.h>
+#include "sgammagroup.h"
+#define SGAMMASET_SCRIPTPARENT RootObjectInstance
+
+class GammasetScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern GammasetScriptController *gammasetController;
+
+class SGammaset : public SGAMMASET_SCRIPTPARENT {
+public:
+ SGammaset();
+ SGammaset(const wchar_t *);
+ SGammaset(int i);
+ virtual ~SGammaset();
+
+protected:
+ const wchar_t *gammasetID;
+
+private:
+ void __construct();
+
+public:
+ static scriptVar script_vcpu_apply(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_rename(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar script_vcpu_update(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_delete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getDefaultGammaGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getGammaGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar script_vcpu_getNumGammaGroups(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_enumGammaGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/slist.cpp b/Src/Wasabi/api/script/objects/slist.cpp
new file mode 100644
index 00000000..1bfe53bf
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/slist.cpp
@@ -0,0 +1,172 @@
+#include <precomp.h>
+#include "slist.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+
+ListScriptController _listController;
+ListScriptController *listController=&_listController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ListScriptController::exportedFunction[] = {
+ {L"addItem", 1, (void*)SList::script_vcpu_addItem },
+ {L"removeItem", 1, (void*)SList::script_vcpu_removeItem },
+ {L"enumItem", 1, (void*)SList::script_vcpu_enumItem },
+ {L"findItem2", 2, (void*)SList::script_vcpu_findItem2 },
+ {L"findItem", 1, (void*)SList::script_vcpu_findItem },
+ {L"getNumItems", 0, (void*)SList::script_vcpu_getNumItems },
+ {L"removeAll", 0, (void*)SList::script_vcpu_removeAll },
+};
+// --------------------------------------------------------
+
+const wchar_t *ListScriptController::getClassName() {
+ return L"List";
+}
+
+const wchar_t *ListScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObject *ListScriptController::instantiate() {
+ SList *l = new SList;
+ ASSERT(l != NULL);
+ return l->getScriptObject();
+}
+
+void ListScriptController::destroy(ScriptObject *o) {
+ SList *obj = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *ListScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for list yet
+}
+
+void ListScriptController::deencapsulate(void *o) {
+}
+
+int ListScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ListScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID ListScriptController::getClassGuid() {
+ return slistGuid;
+}
+
+//------------------------------------------------------------------------
+
+SList::SList() {
+ getScriptObject()->vcpu_setInterface(slistGuid, (void *)static_cast<SList *>(this));
+ getScriptObject()->vcpu_setClassName(L"List");
+ getScriptObject()->vcpu_setController(listController);
+}
+
+SList::~SList() {
+}
+
+TList<scriptVar> *SList::getTList() {
+ return &list;
+}
+
+scriptVar SList::script_vcpu_enumItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&i));
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) return l->getTList()->enumItem(SOM::makeInt(&i));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SList::script_vcpu_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) {
+ SCRIPT_FUNCTION_INIT;
+ scriptVar dup;
+ dup = SOM::makeVar(obj.type);
+ SOM::assignPersistent(&dup, &obj);
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) l->getTList()->addItem(dup);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SList::script_vcpu_removeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&i));
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) {
+ scriptVar dup = l->getTList()->enumItem(SOM::makeInt(&i));
+ if (dup.type == SCRIPT_STRING) {
+ if (dup.data.odata) FREE(dup.data.odata);
+ }
+ l->getTList()->delByPos(SOM::makeInt(&i));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SList::script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) return MAKE_SCRIPT_INT(l->getTList()->getNumItems());
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar SList::script_vcpu_findItem2(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj, scriptVar start) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&start));
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) {
+ if (obj.type != SCRIPT_STRING) {
+ for (int i=SOM::makeInt(&start);i<l->getTList()->getNumItems();i++) {
+ if (!MEMCMP(&l->getTList()->enumItem(i), &obj, sizeof(scriptVar))) {
+ return MAKE_SCRIPT_INT(i);
+ }
+ }
+ } else {
+ for (int i=SOM::makeInt(&start);i<l->getTList()->getNumItems();i++) {
+ if (!wcscmp(l->getTList()->enumItem(i).data.sdata, obj.data.sdata)) {
+ return MAKE_SCRIPT_INT(i);
+ }
+ }
+ }
+ }
+ return MAKE_SCRIPT_INT(-1);
+}
+
+scriptVar SList::script_vcpu_findItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj) {
+ SCRIPT_FUNCTION_INIT;
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) {
+ if (obj.type != SCRIPT_STRING) {
+ for (int i=0;i<l->getTList()->getNumItems();i++) {
+ if (!MEMCMP(&l->getTList()->enumItem(i), &obj, sizeof(scriptVar))) {
+ return MAKE_SCRIPT_INT(i);
+ }
+ }
+ } else {
+ for (int i=0;i<l->getTList()->getNumItems();i++) {
+ if (!wcscmp(l->getTList()->enumItem(i).data.sdata, obj.data.sdata)) {
+ return MAKE_SCRIPT_INT(i);
+ }
+ }
+ }
+ }
+ return MAKE_SCRIPT_INT(-1);
+}
+
+scriptVar SList::script_vcpu_removeAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SList *l = static_cast<SList *>(o->vcpu_getInterface(slistGuid));
+ if (l) {
+ for (int i=0;i<l->getTList()->getNumItems();i++) {
+ scriptVar v = l->getTList()->enumItem(i);
+ if (v.type == SCRIPT_STRING)
+ FREE((wchar_t *)v.data.sdata);
+ }
+ l->getTList()->removeAll();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+
diff --git a/Src/Wasabi/api/script/objects/slist.h b/Src/Wasabi/api/script/objects/slist.h
new file mode 100644
index 00000000..c81c2dd6
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/slist.h
@@ -0,0 +1,62 @@
+#ifndef __SLIST_H
+#define __SLIST_H
+
+#include <api/script/objects/rootobject.h>
+#include <api/script/objects/rootobj.h>
+#include <bfc/ptrlist.h>
+#include <bfc/tlist.h>
+class ScriptObject;
+
+// {B2023AB5-434D-4ba1-BEAE-59637503F3C6}
+static const GUID slistGuid =
+{ 0xb2023ab5, 0x434d, 0x4ba1, { 0xbe, 0xae, 0x59, 0x63, 0x75, 0x3, 0xf3, 0xc6 } };
+
+#define SLIST_SCRIPTPARENT RootObjectInstance
+
+class ListScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern ListScriptController *listController;
+
+
+class SList : public SLIST_SCRIPTPARENT {
+
+public:
+ SList();
+ virtual ~SList();
+
+ TList<scriptVar> *getTList();
+
+private:
+ TList<scriptVar> list;
+
+// -- SCRIPT -----------------------------------------------------
+public:
+// INSERT_SCRIPT_OBJECT_CONTROL
+ static scriptVar script_vcpu_enumItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i);
+ static scriptVar script_vcpu_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_vcpu_removeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_findItem2(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj, scriptVar start);
+ static scriptVar script_vcpu_findItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_vcpu_removeAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/smap.cpp b/Src/Wasabi/api/script/objects/smap.cpp
new file mode 100644
index 00000000..6c829628
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/smap.cpp
@@ -0,0 +1,205 @@
+#include <precomp.h>
+#include "smap.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/sregion.h>
+#include <api/script/objecttable.h>
+
+MapScriptController _mapController;
+MapScriptController *mapController=&_mapController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct MapScriptController::exportedFunction[] = {
+ {L"getValue", 2, (void*)SMap::script_vcpu_getValue },
+ {L"getARGBValue", 3, (void*)SMap::script_vcpu_getARGBValue },
+ {L"inRegion", 2, (void*)SMap::script_vcpu_inRegion },
+ {L"loadMap", 1, (void*)SMap::script_vcpu_loadMap },
+ {L"getWidth", 0, (void*)SMap::script_vcpu_getWidth },
+ {L"getHeight", 0, (void*)SMap::script_vcpu_getHeight },
+ {L"getRegion", 0, (void*)SMap::script_vcpu_getRegion },
+ // todo: stretch
+};
+// --------------------------------------------------------
+
+const wchar_t *MapScriptController::getClassName() {
+ return L"Map";
+}
+
+const wchar_t *MapScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *MapScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *MapScriptController::instantiate() {
+ SMap *m = new SMap;
+ ASSERT(m != NULL);
+ return m->getScriptObject();
+}
+
+void MapScriptController::destroy(ScriptObject *o) {
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ ASSERT(m != NULL);
+ delete m;
+}
+
+void *MapScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for maps for now
+}
+
+void MapScriptController::deencapsulate(void *o) {
+}
+
+int MapScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *MapScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID MapScriptController::getClassGuid() {
+ return mapGuid;
+}
+
+
+
+SMap::SMap() {
+ getScriptObject()->vcpu_setInterface(mapGuid, (void *)static_cast<SMap *>(this));
+ getScriptObject()->vcpu_setClassName(L"Map");
+ getScriptObject()->vcpu_setController(mapController);
+ bmp = NULL;
+ region_so = ObjectTable::instantiate(ObjectTable::getClassFromName(L"Region"));
+ reg = static_cast<SRegion *>(region_so->vcpu_getInterface(regionGuid));
+}
+
+SMap::~SMap() {
+ if (bmp) delete bmp;
+ ObjectTable::destroy(region_so);
+}
+
+int SMap::getValue(int x, int y) {
+ if (!bmp) return 0;
+ ARGB32 c = bmp->getPixel(x, y);
+// if ((c & 0xFF000000) >> 24 != 0xFF) return -1;
+ int v = MAX(MAX((c & 0xFF0000) >> 16, (c & 0xFF00) >> 8), c & 0xFF);
+ return v;
+}
+
+int SMap::getARGBValue(int x, int y, int whichCol) {
+ if (!bmp) return 0;
+ ARGB32 c = bmp->getPixel(x, y);
+
+ whichCol %= 4;
+
+ /**
+ whichCol
+ 0: blue
+ 1: green
+ 2: red
+ 3: alpha
+ */
+
+ ARGB32 a = c >> 24;
+ a &= 0x000000FF; //just to be sure
+
+ if (whichCol == 3) return a;
+
+ c = c >> (whichCol * 8);
+ c &= 0x000000FF;
+
+ if (0 == a || 255 == a) return c;
+
+ double d = c*255/a; // Correction for bitmaps w/ alpha channel, otherwise a lesser rgb value is returned
+ d = ceil(d);
+
+ return (int)d;
+}
+
+void SMap::loadMap(const wchar_t *b)
+{
+ bmp = new SkinBitmap(b, 0);
+ reg->loadFromBitmap(b);
+}
+
+int SMap::getWidth() {
+ if (!bmp) return 0;
+ return bmp->getWidth();
+}
+
+int SMap::getHeight() {
+ if (!bmp) return 0;
+ return bmp->getHeight();
+}
+
+int SMap::inRegion(int x, int y) {
+ POINT pt={x,y};
+ return reg->getRegion()->ptInRegion(&pt);
+}
+
+SRegion *SMap::getSRegion() {
+ return reg;
+}
+
+// VCPU
+
+scriptVar SMap::script_vcpu_loadMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar bmp) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(bmp.type == SCRIPT_STRING);
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) m->loadMap(bmp.data.sdata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SMap::script_vcpu_getValue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) return MAKE_SCRIPT_INT(m->getValue(SOM::makeInt(&x), SOM::makeInt(&y)));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SMap::script_vcpu_getARGBValue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar wichCol) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ ASSERT(SOM::isNumeric(&wichCol));
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) return MAKE_SCRIPT_INT(m->getARGBValue(SOM::makeInt(&x), SOM::makeInt(&y), SOM::makeInt(&wichCol)));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SMap::script_vcpu_getWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) return MAKE_SCRIPT_INT(m->getWidth());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SMap::script_vcpu_getHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) return MAKE_SCRIPT_INT(m->getHeight());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SMap::script_vcpu_inRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) return MAKE_SCRIPT_BOOLEAN(m->inRegion(SOM::makeInt(&x), SOM::makeInt(&y)));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SMap::script_vcpu_getRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SMap *m = static_cast<SMap *>(o->vcpu_getInterface(mapGuid));
+ if (m) {
+ SRegion *s = m->getSRegion();
+ if (s) return MAKE_SCRIPT_OBJECT(s->getScriptObject());
+ }
+ RETURN_SCRIPT_ZERO;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/smap.h b/Src/Wasabi/api/script/objects/smap.h
new file mode 100644
index 00000000..7cd04b41
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/smap.h
@@ -0,0 +1,74 @@
+#ifndef __SMAP_H
+#define __SMAP_H
+
+class SMap;
+class SRegion;
+
+#include <tataki/bitmap/bitmap.h>
+#include <api/script/script.h>
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+
+// {38603665-461B-42a7-AA75-D83F6667BF73}
+static const GUID mapGuid =
+{ 0x38603665, 0x461b, 0x42a7, { 0xaa, 0x75, 0xd8, 0x3f, 0x66, 0x67, 0xbf, 0x73 } };
+
+#define SMAP_SCRIPTPARENT RootObjectInstance
+
+class MapScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern MapScriptController *mapController;
+
+class SMap : public SMAP_SCRIPTPARENT {
+public:
+ SMap();
+ virtual ~SMap();
+
+ int getValue(int x, int y);
+ int getARGBValue(int x, int y, int whichCol);
+ int inRegion(int x, int y);
+ int getWidth();
+ int getHeight();
+ void loadMap(const wchar_t *b);
+ static void instantiate(SMap *s);
+ virtual SkinBitmap *getBitmap() { return bmp; };
+ SRegion *getSRegion();
+
+private:
+ SkinBitmap *bmp;
+ SRegion *reg;
+ ScriptObject *region_so;
+
+public:
+ static scriptVar script_vcpu_loadMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar bitmap);
+ static scriptVar script_vcpu_getValue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_getARGBValue(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar whichCol);
+ static scriptVar script_vcpu_getWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_inRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_getRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/spopup.cpp b/Src/Wasabi/api/script/objects/spopup.cpp
new file mode 100644
index 00000000..84cc6254
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/spopup.cpp
@@ -0,0 +1,140 @@
+#include <precomp.h>
+#include <api/script/objects/spopup.h>
+#include <api/script/scriptmgr.h>
+
+SPopup::SPopup() {
+ getScriptObject()->vcpu_setInterface(popupGuid, (void *)static_cast<SPopup*>(this));
+ getScriptObject()->vcpu_setClassName(L"Popup");
+ getScriptObject()->vcpu_setController(popupController);
+}
+
+SPopup::~SPopup() {
+}
+
+PopupScriptController _popupController;
+PopupScriptController *popupController = &_popupController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct PopupScriptController::exportedFunction[] = {
+ {L"addSubMenu", 2, (void*)SPopup::script_vcpu_addSubMenu },
+ {L"addCommand", 4, (void*)SPopup::script_vcpu_addCommand },
+ {L"addSeparator", 0, (void*)SPopup::script_vcpu_addSeparator },
+ {L"popAtXY", 2, (void*)SPopup::script_vcpu_popAtXY },
+ {L"popAtMouse", 0, (void*)SPopup::script_vcpu_popAtMouse },
+ {L"getNumCommands", 0, (void*)SPopup::script_vcpu_getNumCommands },
+ {L"checkCommand", 2, (void*)SPopup::script_vcpu_checkCommand },
+ {L"disableCommand", 2, (void*)SPopup::script_vcpu_disableCommand },
+
+//todo: events
+};
+
+// --------------------------------------------------------
+const wchar_t *PopupScriptController::getClassName() {
+ return L"Popup";
+}
+
+const wchar_t *PopupScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObject *PopupScriptController::instantiate() {
+ SPopup *p = new SPopup;
+ ASSERT(p != NULL);
+ return p->getScriptObject();
+}
+
+void PopupScriptController::destroy(ScriptObject *o) {
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ ASSERT(p != NULL);
+ delete p;
+}
+
+void *PopupScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for popups yet
+}
+
+void PopupScriptController::deencapsulate(void *o) {
+}
+
+int PopupScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *PopupScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID PopupScriptController::getClassGuid() {
+ return popupGuid;
+}
+
+// -----------------------------------------------------------------------
+scriptVar SPopup::script_vcpu_addSubMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar popup, scriptVar str)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(str.type == SCRIPT_STRING); // compiler discarded
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ SPopup *p2 = static_cast<SPopup *>(GET_SCRIPT_OBJECT_AS(popup, popupGuid));
+ if (p) p->addSubMenu(p2, GET_SCRIPT_STRING(str));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPopup::script_vcpu_addCommand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str, scriptVar cmd, scriptVar checked, scriptVar disabled) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(str.type == SCRIPT_STRING); // compiler discarded
+ ASSERT(SOM::isNumeric(&cmd)); // compiler discarded
+ ASSERT(SOM::isNumeric(&checked)); // compiler discarded
+ ASSERT(SOM::isNumeric(&disabled)); // compiler discarded
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p)
+ p->addCommand(str.data.sdata, SOM::makeInt(&cmd), SOM::makeBoolean(&checked), SOM::makeBoolean(&disabled));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPopup::script_vcpu_addSeparator(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p) p->addSeparator();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPopup::script_vcpu_checkCommand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i, scriptVar check) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&i));
+ ASSERT(SOM::isNumeric(&check));
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p) p->checkCommand(SOM::makeInt(&i), SOM::makeBoolean(&check));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPopup::script_vcpu_disableCommand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i, scriptVar disable) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&i));
+ ASSERT(SOM::isNumeric(&disable));
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p) p->disableCommand(SOM::makeInt(&i), SOM::makeBoolean(&disable));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPopup::script_vcpu_popAtXY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p) return MAKE_SCRIPT_INT(p->popAtXY(SOM::makeInt(&x), SOM::makeInt(&y)));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SPopup::script_vcpu_popAtMouse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p) return MAKE_SCRIPT_INT(p->popAtMouse());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SPopup::script_vcpu_getNumCommands(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SPopup *p = static_cast<SPopup *>(o->vcpu_getInterface(popupGuid));
+ if (p) return MAKE_SCRIPT_INT(p->getNumCommands());
+ RETURN_SCRIPT_ZERO;
+}
diff --git a/Src/Wasabi/api/script/objects/spopup.h b/Src/Wasabi/api/script/objects/spopup.h
new file mode 100644
index 00000000..07bd82df
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/spopup.h
@@ -0,0 +1,60 @@
+//PORTABLE
+#ifndef _SPOPUP_H
+#define _SPOPUP_H
+
+#include <api/wnd/popup.h>
+#include <api/script/objects/rootobject.h>
+
+// {F4787AF4-B2BB-4ef7-9CFB-E74BA9BEA88D}
+static const GUID popupGuid =
+{ 0xf4787af4, 0xb2bb, 0x4ef7, { 0x9c, 0xfb, 0xe7, 0x4b, 0xa9, 0xbe, 0xa8, 0x8d } };
+
+#define SPOPUP_PARENT PopupMenu
+
+class PopupScriptController: public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern PopupScriptController *popupController;
+
+
+#ifndef WANT_NEW_POPUPMENU
+class SPopup : public SPOPUP_PARENT, public RootObjectInstance {
+#else
+class SPopup : public SPOPUP_PARENT {
+#endif
+public:
+ SPopup();
+ virtual ~SPopup();
+
+private:
+
+public:
+
+ static scriptVar script_vcpu_addSubMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar popup, scriptVar str);
+ static scriptVar script_vcpu_addCommand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str, scriptVar cmd, scriptVar checked, scriptVar disabled);
+ static scriptVar script_vcpu_addSeparator(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_popAtXY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_popAtMouse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getNumCommands(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_disableCommand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cmd, scriptVar disable);
+ static scriptVar script_vcpu_checkCommand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cmd, scriptVar check);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/sprivate.cpp b/Src/Wasabi/api/script/objects/sprivate.cpp
new file mode 100644
index 00000000..515fbb08
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sprivate.cpp
@@ -0,0 +1,258 @@
+#include <precomp.h>
+#include "sprivate.h"
+#include "main.h"
+#include <api/application/api_application.h>
+#include "wa2frontend.h"
+#include <api.h>
+#include "../Agave/Language/api_language.h"
+#include "../../../../Components/wac_network/wac_network_http_receiver_api.h"
+#include "../nu/AutoWide.h"
+#include "../nu/AutoChar.h"
+#include "../nu/ns_wc.h"
+#include "../Winamp/buildtype.h"
+#include "../nu/refcount.h"
+#include <shlobj.h>
+#include <shlwapi.h>
+
+// {78BD6ED9-0DBC-4fa5-B5CD-5977E3A912F8}
+static const GUID SPrivate_script_object_guid =
+{ 0x78bd6ed9, 0xdbc, 0x4fa5, { 0xb5, 0xcd, 0x59, 0x77, 0xe3, 0xa9, 0x12, 0xf8 } };
+
+
+static SPrivateScriptObjectController _SPrivateController;
+ScriptObjectController *SPrivateController=&_SPrivateController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct SPrivateScriptObjectController::exportedFunction[] =
+{
+ {L"updateLinks", 2, (void*)SPrivate::vcpu_updateLinks },
+ {L"onLinksUpdated", 1, (void*)SPrivate::vcpu_onLinksUpdated },
+};
+// --------------------------------------------------------
+
+const wchar_t *SPrivateScriptObjectController::getClassName()
+{
+ return L"Private";
+}
+
+const wchar_t *SPrivateScriptObjectController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObjectController *SPrivateScriptObjectController::getAncestorController()
+{
+ return NULL;
+}
+
+ScriptObject *SPrivateScriptObjectController::instantiate()
+{
+ SPrivate *c = new SPrivate;
+ if (!c) return NULL;
+ return c->getScriptObject();
+}
+
+int SPrivateScriptObjectController::getInstantiable()
+{
+ return 1;
+}
+
+void SPrivateScriptObjectController::destroy(ScriptObject *o)
+{
+ SPrivate *obj = static_cast<SPrivate *>(o->vcpu_getInterface(SPrivate_script_object_guid));
+ ASSERT(obj != NULL);
+ obj->dlcb = false;
+ delete obj;
+}
+
+void *SPrivateScriptObjectController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void SPrivateScriptObjectController::deencapsulate(void *o)
+{
+}
+
+int SPrivateScriptObjectController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *SPrivateScriptObjectController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID SPrivateScriptObjectController::getClassGuid()
+{
+ return SPrivate_script_object_guid;
+}
+
+/*-----------------------------------*/
+
+static void DoAPC(PAPCFUNC apc, ULONG_PTR data)
+{
+ HANDLE hMainThread = WASABI_API_APP->main_getMainThreadHandle();
+ if (hMainThread)
+ {
+ QueueUserAPC(apc, hMainThread, data);
+ CloseHandle(hMainThread);
+ }
+}
+
+static void CALLBACK LinksUpdatedAPC(ULONG_PTR data)
+{
+ ScriptObject* scriptCallback = (ScriptObject *)data;
+ SPrivate::vcpu_onLinksUpdated(SCRIPT_CALL, scriptCallback);
+}
+
+class PDownloadCallback : public Countable<ifc_downloadManagerCallback>
+{
+public:
+ PDownloadCallback (const char *url, ScriptObject* scriptCallback)
+ {
+ this->scriptCallback = scriptCallback;
+ validSO = true;
+ }
+
+ ~PDownloadCallback ()
+ {
+ }
+
+
+ void OnFinish (DownloadToken token)
+ {
+ if (!validSO)
+ {
+ DeleteFileW(WAC_API_DOWNLOADMANAGER->GetLocation(token));
+ delete this;
+ return;
+ }
+
+ api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token);
+ if (http)
+ {
+ int replyCode;
+ replyCode = http->getreplycode();
+ if (204 != replyCode)
+ {
+ BOOL succeeded;
+ HANDLE hDest;
+ const wchar_t *downloadDest;
+ wchar_t finalFileName[MAX_PATH] = {0};
+
+ downloadDest = WAC_API_DOWNLOADMANAGER->GetLocation(token);
+ succeeded = FALSE;
+
+ hDest = CreateFileW(downloadDest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (INVALID_HANDLE_VALUE != hDest)
+ {
+ LARGE_INTEGER fileSize;
+ if (FALSE != GetFileSizeEx(hDest, &fileSize) &&
+ 0 != fileSize.QuadPart)
+ {
+ succeeded = TRUE;
+ }
+
+ CloseHandle(hDest);
+
+ if (FALSE == succeeded)
+ {
+ DeleteFileW(downloadDest);
+ downloadDest = NULL;
+ }
+ }
+
+ if (FALSE != succeeded &&
+ NULL != (PathCombineW(finalFileName, WASABI_API_APP->path_getUserSettingsPath(), L"links.xml")))
+ {
+ // then move the file there
+ succeeded = MoveFileW(downloadDest, finalFileName);
+ if (FALSE == succeeded)
+ {
+ succeeded = CopyFileW(downloadDest, finalFileName, FALSE);
+ DeleteFileW(downloadDest);
+ }
+ if (FALSE != succeeded)
+ {
+ // hop back on the main thread for the callback
+ DoAPC(LinksUpdatedAPC, (ULONG_PTR)scriptCallback);
+ }
+ }
+ }
+ }
+ Release();
+ }
+
+ void OnError (DownloadToken token, int error)
+ {
+ Release();
+ }
+ void OnCancel (DownloadToken token)
+ {
+ Release();
+ }
+
+ void OnTick (DownloadToken token) {}
+
+ ScriptObject* scriptCallback;
+ bool validSO;
+ REFERENCE_COUNT_IMPLEMENTATION;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+SPrivate::SPrivate()
+{
+ getScriptObject()->vcpu_setInterface(SPrivate_script_object_guid, static_cast<SPrivate *>(this));
+ getScriptObject()->vcpu_setClassName(L"Private");
+ getScriptObject()->vcpu_setController(SPrivateController);
+ dlcb = false;
+}
+SPrivate::~SPrivate()
+{
+}
+
+scriptVar SPrivate::vcpu_updateLinks(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar version, scriptVar bversion)
+{
+ SCRIPT_FUNCTION_INIT;
+
+ String url;
+
+ //if defined(BETA) || defined(INTERNAL)
+ const wchar_t *langIdentifier = WASABI_API_LNG?(WASABI_API_LNG->GetLanguageIdentifier(LANG_IDENT_STR)):0;
+ if (!langIdentifier)
+ langIdentifier = L"en-US";
+
+ url = StringPrintf("http://client.winamp.com/data/skins?o=links&sid=bento&version=%s&waversion=%s&build=%i&browserversion=%s&lang=%s", AutoChar(version.data.sdata), WASABI_API_APP->main_getVersionNumString(), WASABI_API_APP->main_getBuildNumber(),AutoChar(bversion.data.sdata), AutoChar(langIdentifier));
+ //url = StringPrintf("http://martin.skinconsortium.com/links.php?o=links&sid=bento&version=%s&waversion=%s&build=%i&browserversion=%s", AutoChar(version.data.sdata), WASABI_API_APP->main_getVersionNumString(), WASABI_API_APP->main_getBuildNumber(),AutoChar(bversion.data.sdata));
+
+ SPrivate *sp = static_cast<SPrivate *>(object->vcpu_getInterface(SPrivate_script_object_guid));
+ sp->dlcb = new PDownloadCallback(url, object);
+ WAC_API_DOWNLOADMANAGER->Download(url, sp->dlcb);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SPrivate::vcpu_onLinksUpdated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, SPrivateController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT(o);
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+
+#define CBCLASS PDownloadCallback
+START_DISPATCH;
+REFERENCE_COUNTED;
+VCB(IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish)
+VCB(IFC_DOWNLOADMANAGERCALLBACK_ONTICK, OnTick)
+VCB(IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError)
+VCB(IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/sprivate.h b/Src/Wasabi/api/script/objects/sprivate.h
new file mode 100644
index 00000000..503fbb1a
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sprivate.h
@@ -0,0 +1,47 @@
+#pragma once
+#include <api/script/api_maki.h>
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+
+class PDownloadCallback;
+
+#define SPRIVATE_SCRIPTPARENT RootObjectInstance
+
+class SPrivateScriptObjectController : public ScriptObjectControllerI
+{
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual int getInstantiable();
+ virtual int getReferenceable() {return 0;}
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern ScriptObjectController *SPrivateController;
+
+class SPrivate : public SPRIVATE_SCRIPTPARENT
+{
+public:
+ SPrivate();
+ virtual ~SPrivate();
+
+ PDownloadCallback * dlcb;
+
+public:
+ static scriptVar vcpu_updateLinks(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar version, scriptVar bversion);
+ static scriptVar vcpu_onLinksUpdated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
diff --git a/Src/Wasabi/api/script/objects/sregion.cpp b/Src/Wasabi/api/script/objects/sregion.cpp
new file mode 100644
index 00000000..0a966f8a
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sregion.cpp
@@ -0,0 +1,256 @@
+#include <precomp.h>
+#include "sregion.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+
+RegionScriptController _regionController;
+RegionScriptController *regionController=&_regionController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct RegionScriptController::exportedFunction[] = {
+ {L"add", 1, (void*)SRegion::script_vcpu_add },
+ {L"sub", 1, (void*)SRegion::script_vcpu_sub },
+ {L"offset", 2, (void*)SRegion::script_vcpu_offset },
+ {L"stretch", 1, (void*)SRegion::script_vcpu_stretch },
+ {L"copy", 1, (void*)SRegion::script_vcpu_copy },
+ {L"loadFromMap", 3, (void*)SRegion::script_vcpu_loadFromMap },
+ {L"loadFromBitmap", 1, (void*)SRegion::script_vcpu_loadFromBitmap },
+ {L"getBoundingBoxX", 0, (void*)SRegion::script_vcpu_getBoundX },
+ {L"getBoundingBoxY", 0, (void*)SRegion::script_vcpu_getBoundY },
+ {L"getBoundingBoxW", 0, (void*)SRegion::script_vcpu_getBoundW },
+ {L"getBoundingBoxH", 0, (void*)SRegion::script_vcpu_getBoundH },
+};
+// --------------------------------------------------------
+
+const wchar_t *RegionScriptController::getClassName() {
+ return L"Region";
+}
+
+const wchar_t *RegionScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *RegionScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *RegionScriptController::instantiate() {
+ SRegion *r = new SRegion;
+ ASSERT(r != NULL);
+ return r->getScriptObject();
+}
+
+void RegionScriptController::destroy(ScriptObject *o) {
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ ASSERT(r != NULL);
+ delete r;
+}
+
+void *RegionScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for regions yet
+}
+
+void RegionScriptController::deencapsulate(void *o) {
+}
+
+int RegionScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *RegionScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID RegionScriptController::getClassGuid() {
+ return regionGuid;
+}
+
+SRegion::SRegion() {
+ getScriptObject()->vcpu_setInterface(regionGuid, (void *)static_cast<SRegion*>(this));
+ getScriptObject()->vcpu_setClassName(L"Region");
+ getScriptObject()->vcpu_setController(regionController);
+ reg = new RegionI;
+}
+
+SRegion::~SRegion() {
+ delete reg;
+}
+
+int SRegion::inRegion(int x, int y) {
+ if (!reg) return 0;
+ POINT pt={x,y};
+ return reg->ptInRegion(&pt);
+}
+
+int SRegion::getBoundX() {
+ if (!reg) return 0;
+ RECT r;
+ reg->getBox(&r);
+ return r.left;
+}
+
+int SRegion::getBoundY() {
+ if (!reg) return 0;
+ RECT r;
+ reg->getBox(&r);
+ return r.top;
+}
+
+int SRegion::getBoundW() {
+ if (!reg) return 0;
+ RECT r;
+ reg->getBox(&r);
+ return r.right-r.left;
+}
+
+int SRegion::getBoundH() {
+ if (!reg) return 0;
+ RECT r;
+ reg->getBox(&r);
+ return r.bottom-r.top;
+}
+
+api_region *SRegion::getRegion() {
+ return reg;
+}
+
+void SRegion::addRegion(SRegion *s) {
+ if (!reg) reg = new RegionI;
+ reg->addRegion(s->getRegion());
+}
+
+void SRegion::subRegion(SRegion *s) {
+ if (!reg) return;
+ reg->subtractRgn(s->getRegion());
+}
+
+void SRegion::offset(int x, int y) {
+ if (!reg) return;
+ reg->offset(x, y);
+}
+
+void SRegion::stretch(double s) {
+ if (!reg) return;
+ reg->scale(s, s);
+}
+
+void SRegion::copy(SRegion *s) {
+ if (!reg) reg = new RegionI;
+ else reg->empty();
+ reg->addRegion(s->getRegion());
+}
+
+void SRegion::loadFromMap(SMap *m, int byte, int inverted) {
+ delete reg;
+ RECT r={m->getBitmap()->getX(), m->getBitmap()->getY(), m->getBitmap()->getWidth(), m->getBitmap()->getHeight()};
+ reg = new RegionI(m->getBitmap(), &r, 0, 0, FALSE, 1, byte, inverted);
+}
+
+void SRegion::loadFromBitmap(const wchar_t *p)
+{
+ delete reg;
+ SkinBitmap *b = new SkinBitmap(p);
+ ASSERT(b); // TODO: should be guru
+ reg = new RegionI(b);
+ delete b;
+}
+
+// -----------------------------------------------------------------------
+
+scriptVar SRegion::script_vcpu_loadFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&byte));
+ ASSERT(SOM::isNumeric(&inv));
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ SMap *m = static_cast<SMap *>(GET_SCRIPT_OBJECT_AS(map, mapGuid));
+ if (r) r->loadFromMap(m, GET_SCRIPT_INT(byte), GET_SCRIPT_BOOLEAN(inv));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SRegion::script_vcpu_loadFromBitmap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar b)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(b.type == SCRIPT_STRING);
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) r->loadFromBitmap(GET_SCRIPT_STRING(b));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SRegion::script_vcpu_inRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) return MAKE_SCRIPT_INT(r->inRegion(GET_SCRIPT_INT(x), GET_SCRIPT_INT(y)));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SRegion::script_vcpu_add(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r1 = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ SRegion *r2 = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(r, regionGuid));
+ if (r1) r1->addRegion(r2);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SRegion::script_vcpu_sub(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r1 = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ SRegion *r2 = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(r, regionGuid));
+ if (r1) r1->subRegion(r2);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SRegion::script_vcpu_offset(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) r->offset(GET_SCRIPT_INT(x), GET_SCRIPT_INT(y));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SRegion::script_vcpu_stretch(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&s));
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) r->stretch(SOM::makeDouble(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SRegion::script_vcpu_getBoundX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) return MAKE_SCRIPT_INT(r->getBoundX());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SRegion::script_vcpu_getBoundY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) return MAKE_SCRIPT_INT(r->getBoundY());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SRegion::script_vcpu_getBoundW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) return MAKE_SCRIPT_INT(r->getBoundW());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SRegion::script_vcpu_getBoundH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ if (r) return MAKE_SCRIPT_INT(r->getBoundH());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SRegion::script_vcpu_copy(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r) {
+ SCRIPT_FUNCTION_INIT;
+ SRegion *r1 = static_cast<SRegion *>(o->vcpu_getInterface(regionGuid));
+ SRegion *r2 = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(r, regionGuid));
+ if (r1) r1->copy(r2);
+ RETURN_SCRIPT_VOID;
+}
+
+
diff --git a/Src/Wasabi/api/script/objects/sregion.h b/Src/Wasabi/api/script/objects/sregion.h
new file mode 100644
index 00000000..00d0e607
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sregion.h
@@ -0,0 +1,92 @@
+#ifndef __SREGION_H
+#define __SREGION_H
+
+class SRegion;
+
+#ifndef _NOSTUDIO
+
+#include <tataki/region/region.h>
+#include <api/script/objects/smap.h>
+
+#endif
+
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+
+// {3A370C02-3CBF-439f-84F1-86885BCF1E36}
+static const GUID regionGuid =
+{ 0x3a370c02, 0x3cbf, 0x439f, { 0x84, 0xf1, 0x86, 0x88, 0x5b, 0xcf, 0x1e, 0x36 } };
+
+#define SREGION_SCRIPTPARENT RootObjectInstance
+
+class RegionScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern RegionScriptController *regionController;
+
+
+#ifndef _NOSTUDIO
+
+class SRegion : public SREGION_SCRIPTPARENT {
+public:
+ SRegion();
+ virtual ~SRegion();
+
+ int inRegion(int x, int y);
+ void loadFromMap(SMap *map, int byte, int inv);
+ void loadFromBitmap(const wchar_t *p);
+ int getBoundX();
+ int getBoundY();
+ int getBoundW();
+ int getBoundH();
+ api_region *getRegion();
+ void addRegion(SRegion *s);
+ void subRegion(SRegion *s);
+ void offset(int x, int y);
+ void stretch(double s);
+ void copy(SRegion *s);
+
+
+private:
+ RegionI *reg;
+
+#else
+class SRegion : SREGION_SCRIPTPARENT {
+#endif
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+public:
+ static scriptVar script_vcpu_loadFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv);
+ static scriptVar script_vcpu_loadFromBitmap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map);
+ static scriptVar script_vcpu_inRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_add(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar script_vcpu_sub(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar script_vcpu_offset(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_stretch(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_copy(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar script_vcpu_getBoundX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBoundY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBoundW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getBoundH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/svcwnd.cpp b/Src/Wasabi/api/script/objects/svcwnd.cpp
new file mode 100644
index 00000000..2ab301e9
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/svcwnd.cpp
@@ -0,0 +1,239 @@
+#include "precomp.h"
+#include "../../bfc/std.h"
+#include "script.h"
+#include "scriptmgr.h"
+#include "../../bfc/notifmsg.h"
+#include "../../common/script/scriptobj.h"
+#include "compoobj.h"
+#include "../api.h"
+#include "vcpu.h"
+#include "../smap.h"
+#include "../skinparse.h"
+#include "svcwnd.h"
+#include "../services/services.h"
+#include "../services/servicei.h"
+#include "../svcmgr.h"
+#include "../services/svc_wndcreate.h"
+
+char svcWndXuiObjectStr[] = "SvcWnd"; // This is the xml tag
+char svcWndXuiSvcName[] = "SvcWnd xui object"; // this is the name of the xuiservice
+
+
+SvcWndScriptController _svcWndController;
+SvcWndScriptController *svcWndController = &_svcWndController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct SvcWndScriptController::exportedFunction[] = {
+ {"getGUID", 1, (void*)SvcWnd::script_vcpu_getGUID },
+ {"getWac", 0, (void*)SvcWnd::script_vcpu_getWac },
+};
+// --------------------------------------------------------
+
+const wchar_t *SvcWndScriptController::getClassName() {
+ return L"SvcGuiObject";
+}
+
+const wchar_t *SvcWndScriptController::getAncestorClassName() {
+ return "GuiObject";
+}
+
+int SvcWndScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *SvcWndScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID SvcWndScriptController::getClassGuid() {
+ return svcWndGuid;
+}
+
+ScriptObject *SvcWndScriptController::instantiate() {
+ SvcWnd *sv = new SvcWnd();
+ ASSERT(sv != NULL);
+ return sv->getScriptObject();
+}
+
+void SvcWndScriptController::destroy(ScriptObject *o) {
+ SvcWnd *obj = static_cast<SvcWnd*>(o->vcpu_getInterface(svcWndGuid));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *SvcWndScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for svcwnd yet
+}
+
+void SvcWndScriptController::deencapsulate(void *o) {
+}
+
+char SvcWndParams[][] =
+{
+ "DBLCLICKACTION", //SVCWND_DBLCLKACTION
+ "GUID" // SVCWND_GUID
+};
+SvcWnd::SvcWnd() {
+ getScriptObject()->vcpu_setInterface(svcWndGuid, (void *)static_cast<SvcWnd*>(this));
+ getScriptObject()->vcpu_setClassName("SvcGuiObject");
+ getScriptObject()->vcpu_setController(svcWndController);
+ myGUID = INVALID_GUID;
+ svcwnd = NULL;
+ svc = NULL;
+ forwarded = 0;
+ xuihandle = newXuiHandle();
+
+ addParam(xuihandle, SvcWndParams[0], SVCWND_DBLCLKACTION, XUI_ATTRIBUTE_IMPLIED);
+ addParam(xuihandle, SvcWndParams[1], SVCWND_GUID, XUI_ATTRIBUTE_IMPLIED);
+
+}
+
+// servicewnd to svcwnd
+
+int SvcWnd::childNotify(api_window *child, int msg, intptr_t param1, intptr_t param2) {
+ if (child == svcwnd) {
+ switch (msg) {
+ case ChildNotify::SVCWND_LBUTTONDOWN:
+ onLeftButtonDown(param1, param2);
+ break;
+ case ChildNotify::SVCWND_RBUTTONDOWN:
+ onRightButtonDown(param1, param2);
+ break;
+ case ChildNotify::SVCWND_LBUTTONUP:
+ onLeftButtonUp(param1, param2);
+ break;
+ case ChildNotify::SVCWND_RBUTTONUP:
+ onRightButtonUp(param1, param2);
+ break;
+ case ChildNotify::SVCWND_LBUTTONDBLCLK:
+ onLeftButtonDblClk(param1, param2);
+ break;
+ case ChildNotify::SVCWND_RBUTTONDBLCLK:
+ onRightButtonDblClk(param1, param2);
+ break;
+ case ChildNotify::SVCWND_MOUSEMOVE:
+ onMouseMove(param1, param2);
+ break;
+ }
+ forwarded = 0;
+ } else
+ return SVCWND_PARENT::childNotify(child, msg, param1, param2);
+ return 1;
+}
+
+// virtualwnd to guiobject bridging
+
+int SvcWnd::onLeftButtonDblClk(int x, int y) {
+ if(!dblClickAction.isempty()) {
+ const char *toCheck="SWITCH;";
+ if(!STRNINCMP(dblClickAction,toCheck)) {
+ onLeftButtonUp(x,y);
+ getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue()+STRLEN(toCheck));
+ }
+ }
+ return SVCWND_PARENT::onLeftButtonDblClk(x, y);
+}
+
+int SvcWnd::onResize() {
+ SVCWND_PARENT::onResize();
+ RECT r = clientRect();
+ if (svcwnd)
+ svcwnd->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ return 1;
+}
+
+void SvcWnd::onSetVisible(int v) {
+ if (svcwnd) svcwnd->setVisible(v);
+ SVCWND_PARENT::onSetVisible(v);
+}
+
+int SvcWnd::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (_xuihandle == xuihandle) {
+ switch (xmlattributeid) {
+ case SVCWND_GUID: {
+ GUID *g;
+ g = SkinParser::getComponentGuid(value);
+ if (g)
+ setGUID(*g);
+ return 1;
+ }
+ case SVCWND_DBLCLKACTION:
+ dblClickAction = value;
+ return 1;
+ }
+ }
+ return SVCWND_PARENT::setXuiParam(_xuihandle,xmlattributeid,xmlattributename,value);
+}
+
+int SvcWnd::onUnknownXuiParam(const wchar_t *param, const wchar_t *value) {
+ params.addItem(new String(param));
+ params.addItem(new String(value));
+ return 0;
+}
+
+int SvcWnd::onInit() {
+ int r = SVCWND_PARENT::onInit();
+ WindowCreateByGuidEnum wce(getGUID());
+ for (;;) {
+ if (!svc)
+ svc = wce.getNext();
+ if (!svc) return 0;
+ svcwnd = svc->createWindowByGuid(getGUID(), this);
+ if (svcwnd != NULL) break;
+ SvcEnum::release(svc); svc = NULL;
+ }
+ if (svcwnd != NULL)
+ {
+ svcwnd->setStartHidden(1);
+ if (!svcwnd->isInited())
+ r &= svcwnd->init(this);
+ if (params.getNumItems() > 0) {
+ for (int i=0;i<params.getNumItems();i+=2) {
+ svcwnd->getGuiObject()->guiobject_setXmlParam(params[i]->getValue(), params[i+1]->getValue());
+ }
+ }
+ }
+ params.deleteAll();
+ return r;
+}
+
+SvcWnd::~SvcWnd() {
+ if (svc) {
+ svc->destroyWindow(svcwnd);
+ ServiceManager::release(svc);
+ }
+}
+
+int SvcWnd::handleRatio() {
+ return 1; // todo: ask window
+}
+
+void SvcWnd::setGUID(GUID g) {
+ myGUID = g;
+}
+
+GUID SvcWnd::getGUID(void) {
+ return myGUID;
+}
+
+int SvcWnd::getPreferences(int what) {
+ if (svcwnd) return svcwnd->getPreferences(what);
+ return SVCWND_PARENT::getPreferences(what);
+}
+
+scriptVar SvcWnd::script_vcpu_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SvcWnd *s = static_cast<SvcWnd *>(o->vcpu_getInterface(svcWndGuid));
+ if (s)
+ return MAKE_SCRIPT_STRING(StringPrintf(s->myGUID));
+ else
+ return MAKE_SCRIPT_STRING("");
+}
+
+scriptVar SvcWnd::script_vcpu_getWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SvcWnd *s = static_cast<SvcWnd *>(o->vcpu_getInterface(svcWndGuid));
+ if (s) return MAKE_SCRIPT_OBJECT(SOM::getWACObject(s->getGUID())->getScriptObject());
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/script/objects/svcwnd.h b/Src/Wasabi/api/script/objects/svcwnd.h
new file mode 100644
index 00000000..41f83f28
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/svcwnd.h
@@ -0,0 +1,89 @@
+#ifndef _SVCWND_H
+#define _SVCWND_H
+
+#include "script.h"
+#include "../../common/script/scriptobj.h"
+#include "guiobj.h"
+#include "../../bfc/svc_enum.h"
+
+class SMap;
+class SRegion;
+class Container;
+class Layout;
+
+// {8776F715-503A-41f9-BD63-FB148AD05765}
+static const GUID svcWndGuid =
+{ 0x8776f715, 0x503a, 0x41f9, { 0xbd, 0x63, 0xfb, 0x14, 0x8a, 0xd0, 0x57, 0x65 } };
+
+#define SVCWND_PARENT GuiObjectWnd
+
+class SvcWndScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern SvcWndScriptController *svcWndController;
+
+class SvcWnd : public SVCWND_PARENT {
+public:
+ SvcWnd();
+ virtual ~SvcWnd();
+
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int onResize();
+ virtual void onSetVisible(int v);
+ virtual int onInit();
+
+ virtual int getPreferences(int what);
+ virtual int handleRatio();
+
+ void setGUID(GUID g);
+ GUID getGUID(void);
+
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2);
+ virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+ virtual int onUnknownXuiParam(const wchar_t *param, const wchar_t *value);
+
+ // VCPU
+ static scriptVar script_vcpu_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getWac(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ PtrList<StringW> params;
+ // End VCPU
+
+protected:
+
+ enum {
+ SVCWND_GUID=0,
+ SVCWND_DBLCLKACTION,
+ };
+
+private:
+ GUID myGUID;
+ ifc_window *svcwnd;
+ svc_windowCreate *svc;
+ int forwarded;
+ StringW dblClickAction;
+ int xuihandle;
+};
+
+extern char svcWndXuiObjectStr[];
+extern char svcWndXuiSvcName[];
+class SvcWndXuiSvc : public XuiObjectSvc<SvcWnd, svcWndXuiObjectStr, svcWndXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/sxmldoc.cpp b/Src/Wasabi/api/script/objects/sxmldoc.cpp
new file mode 100644
index 00000000..f5954c20
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sxmldoc.cpp
@@ -0,0 +1,231 @@
+#include <precomp.h>
+#include "sxmldoc.h"
+
+#include "slist.h"
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objecttable.h>
+
+
+// {417FFB69-987F-4be8-8D87-D9965EEEC868}
+static const GUID xmlDocGuid =
+{ 0x417ffb69, 0x987f, 0x4be8, { 0x8d, 0x87, 0xd9, 0x96, 0x5e, 0xee, 0xc8, 0x68 } };
+
+
+XmlDocScriptController _xmlDocController;
+XmlDocScriptController *xmlDocController=&_xmlDocController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct XmlDocScriptController::exportedFunction[] = {
+ {L"parser_addCallback", 1, (void*)SXmlDoc::script_vcpu_addParserCallback },
+ {L"parser_start", 0, (void*)SXmlDoc::script_vcpu_parse },
+ {L"parser_destroy", 0, (void*)SXmlDoc::script_vcpu_destroyParser },
+ {L"parser_onCallback", 4, (void*)SXmlDoc::script_vcpu_onXmlParserCallback},
+ {L"parser_onCloseCallback", 2, (void*)SXmlDoc::script_vcpu_onXmlParserEndCallback},
+ {L"parser_onError", 5, (void*)SXmlDoc::script_vcpu_onXmlParserError},
+};
+// --------------------------------------------------------
+
+const wchar_t *XmlDocScriptController::getClassName() {
+ return L"XmlDoc";
+}
+
+const wchar_t *XmlDocScriptController::getAncestorClassName() {
+ return L"File";
+}
+
+ScriptObjectController *XmlDocScriptController::getAncestorController() { return rootScriptObjectController; }
+
+ScriptObject *XmlDocScriptController::instantiate() {
+ SXmlDoc *xd = new SXmlDoc;
+ ASSERT(xd != NULL);
+ return xd->getScriptObject();
+}
+
+void XmlDocScriptController::destroy(ScriptObject *o) {
+ SXmlDoc *xd = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
+ ASSERT(xd != NULL);
+ delete xd;
+}
+
+void *XmlDocScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for XmlDocs for now
+}
+
+void XmlDocScriptController::deencapsulate(void *o) {
+}
+
+int XmlDocScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *XmlDocScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID XmlDocScriptController::getClassGuid() {
+ return xmlDocGuid;
+}
+
+
+SXmlDoc::SXmlDoc() {
+ getScriptObject()->vcpu_setInterface(xmlDocGuid, (void *)static_cast<SXmlDoc *>(this));
+ getScriptObject()->vcpu_setClassName(L"XmlDoc");
+ getScriptObject()->vcpu_setController(xmlDocController);
+ filename = NULL;
+ myXmlParser = NULL;
+}
+
+SXmlDoc::~SXmlDoc() {
+ destroyParser();
+}
+
+void SXmlDoc::addParserCallback(const wchar_t *name)
+{
+ createParser();
+ StringW sw_name = name;
+ sw_name.replace(L"/", L"\f"); // We call subsections in Maki with a single /. in Wasabi \f is used
+ //debug: Std::messageBox(sw_name,name,0);
+ myXmlParser->xmlreader_registerCallback(sw_name, &myXmlParserCallback);
+ //debug: myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbla", &myXmlParserCallback);
+}
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+void SXmlDoc::startParsing()
+{
+/* debug: createParser();
+myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbla", &myXmlParserCallback);
+myXmlParser->xmlreader_registerCallback(L"WasabiXML\fbrowserQuickLinks", &myXmlParserCallback);*/
+
+ if (!myXmlParser) return;
+ myXmlParser->xmlreader_open();
+ LoadXmlFile(myXmlParser, filename);
+}
+
+void SXmlDoc::createParser()
+{
+ if (myXmlParser != NULL) return;
+
+ myXmlParserCallback.parent = this;
+
+ myXmlParserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (myXmlParserFactory)
+ {
+ myXmlParser = (obj_xml *)myXmlParserFactory->getInterface();
+
+ if (myXmlParser)
+ {
+ const wchar_t *file = Wasabi::Std::filename(filename);
+ int fnlen = wcslen(file);
+ StringW path = filename;
+ path.trunc( -fnlen);
+ XMLAutoInclude include(myXmlParser, path);
+ }
+ }
+}
+
+void SXmlDoc::destroyParser()
+{
+ if (!myXmlParser) return;
+ myXmlParser->xmlreader_unregisterCallback(&myXmlParserCallback);
+ myXmlParser->xmlreader_close();
+ myXmlParserFactory->releaseInterface(myXmlParser);
+ myXmlParser = NULL;
+}
+
+// ParserCallbacks
+
+void SXmlDocParserCallback::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ //debug: Std::messageBox(xmlpath,xmltag,0);
+ StringW sw_xmlpath = xmlpath;
+ sw_xmlpath.replace(L"\f", L"/");
+
+ // Store the params and paramvalues in a SList
+ SList param;
+ SList paramvalue;
+
+ for (size_t i = 0; i != params->getNbItems(); i++)
+ {
+ SList::script_vcpu_addItem(SCRIPT_CALL, param.getScriptObject(), MAKE_SCRIPT_STRING(params->getItemName(i)));
+ SList::script_vcpu_addItem(SCRIPT_CALL, paramvalue.getScriptObject(), MAKE_SCRIPT_STRING(params->getItemValue(i)));
+ }
+
+ // and now the monster call ;)
+ SXmlDoc::script_vcpu_onXmlParserCallback(
+ SCRIPT_CALL, parent->getScriptObject(),
+ MAKE_SCRIPT_STRING(sw_xmlpath),
+ MAKE_SCRIPT_STRING(xmltag),
+ MAKE_SCRIPT_OBJECT(param.getScriptObject()),
+ MAKE_SCRIPT_OBJECT(paramvalue.getScriptObject()) );
+}
+
+void SXmlDocParserCallback::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ StringW sw_xmlpath = xmlpath;
+ sw_xmlpath.replace(L"\f", L"/");
+
+ SXmlDoc::script_vcpu_onXmlParserEndCallback(SCRIPT_CALL, parent->getScriptObject(), MAKE_SCRIPT_STRING(sw_xmlpath), MAKE_SCRIPT_STRING(xmltag));
+}
+
+void SXmlDocParserCallback::xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr)
+{
+ SXmlDoc::script_vcpu_onXmlParserError(
+ SCRIPT_CALL, parent->getScriptObject(),
+ MAKE_SCRIPT_STRING(L""), // xml api changed, but we should keep the same maki function!
+ MAKE_SCRIPT_INT(linenum),
+ MAKE_SCRIPT_STRING(L""), // xml api changed, but we should keep the same maki function!
+ MAKE_SCRIPT_INT(errcode),
+ MAKE_SCRIPT_STRING(errstr) );
+}
+
+// VCPU
+
+scriptVar SXmlDoc::script_vcpu_addParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar fn) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(fn.type == SCRIPT_STRING);
+ SXmlDoc *m = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
+ if (m) m->addParserCallback(fn.data.sdata);
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SXmlDoc::script_vcpu_parse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SXmlDoc *m = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
+ if (m) m->startParsing();
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SXmlDoc::script_vcpu_destroyParser(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ SXmlDoc *m = static_cast<SXmlDoc *>(o->vcpu_getInterface(xmlDocGuid));
+ if (m) m->destroyParser();
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SXmlDoc::script_vcpu_onXmlParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag, scriptVar param, scriptVar paramvalue)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS4(o, xmlDocController, xmlpath, xmltag, param, paramvalue);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, xmlpath, xmltag, param, paramvalue);
+}
+scriptVar SXmlDoc::script_vcpu_onXmlParserEndCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, xmlDocController, xmlpath, xmltag);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, xmlpath, xmltag);
+}
+scriptVar SXmlDoc::script_vcpu_onXmlParserError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar filename, scriptVar linenum, scriptVar incpath, scriptVar errcode, scriptVar errstr)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS5(o, xmlDocController, filename, linenum, incpath, errcode, errstr);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT5(o, filename, linenum, incpath, errcode, errstr);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/sxmldoc.h b/Src/Wasabi/api/script/objects/sxmldoc.h
new file mode 100644
index 00000000..cfee2551
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/sxmldoc.h
@@ -0,0 +1,76 @@
+#ifndef __SXMLDOC_H
+#define __SXMLDOC_H
+
+class SXmlDoc;
+
+#include <api/script/objects/sfile.h>
+
+#include <api/script/script.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/rootobject.h>
+
+#include <api/xml/XMLAutoInclude.h>
+
+#define SXMLDOC_SCRIPTPARENT SFile
+
+class XmlDocScriptController : public fileScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+class SXmlDocParserCallback : public ifc_xmlreadercallbackI
+{
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+ void xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr);
+
+public: SXmlDoc *parent; // reference to the xmldoc that triggered this callback
+};
+
+extern XmlDocScriptController *xmlDocController;
+
+class SXmlDoc : public SXMLDOC_SCRIPTPARENT
+{
+public:
+ SXmlDoc();
+ virtual ~SXmlDoc();
+
+ void addParserCallback(const wchar_t *b);
+ void startParsing();
+ void destroyParser();
+ void elementCallback(const wchar_t *xmltag);
+
+private:
+ obj_xml *myXmlParser;
+ SXmlDocParserCallback myXmlParserCallback;
+ waServiceFactory *myXmlParserFactory;
+
+ void createParser();
+
+public:
+ static scriptVar script_vcpu_addParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar fn);
+ static scriptVar script_vcpu_parse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_destroyParser(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onXmlParserCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag, scriptVar param, scriptVar paramvalue);
+ static scriptVar script_vcpu_onXmlParserError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar filename, scriptVar linenum, scriptVar incpath, scriptVar errcode, scriptVar errstr);
+ static scriptVar script_vcpu_onXmlParserEndCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar xmlpath, scriptVar xmltag);
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/systemobj.cpp b/Src/Wasabi/api/script/objects/systemobj.cpp
new file mode 100644
index 00000000..fb13ee2b
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/systemobj.cpp
@@ -0,0 +1,3500 @@
+#include <precomp.h>
+
+#include <bfc/wasabi_std.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/scriptobj.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/systemobj.h>
+#include <api/service/svcs/svc_action.h>
+#include <api/util/selectfile.h>
+#include <api/script/vcpu.h> // for getAtom, CUT
+
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wnd/wndclass/wndholder.h>
+#include <api/wndmgr/skinembed.h>
+#endif
+
+#include <api/script/objects/timer.h>
+#include <time.h>
+#include <api.h>
+
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/skinparse.h>
+#include <api/skin/skin.h>
+#endif
+#include <math.h>
+#include <shlobj.h>
+
+#include <bfc/string/url.h>
+#include <bfc/parse/pathparse.h>
+#include <bfc/tlist.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/util/varmgr.h>
+#endif
+
+#include <bfc/nsguid.h>
+#include <api/script/objecttable.h>
+#include <api/skin/groupmgr.h>
+
+#ifdef WA3COMPATIBILITY
+#include <api/skin/widgets/mb/xuibrowser.h>
+#include <api/skin/widgets/mb/mainminibrowser.h>
+#include <api/util/dde.h>
+#include <api/wac/main.h>//CUT!!
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+#include <api/service/svcs/svc_player.h>
+#include <api/core/buttons.h>
+#include <api/core/api_core.h>
+#include <api/core/corehandle.h> // safe to include even if core isn't there
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+#include <api/config/items/attrbool.h>
+#endif
+
+#include <api/locales/xlatstr.h>
+#include "../Agave/Language/api_language.h"
+#include <api/syscb/callbacks/consolecb.h>
+#include "../nu/AutoChar.h"
+#include "../nu/AutoUrl.h"
+#include "../nu/AutoWide.h"
+#ifdef _WIN32
+#include <shlwapi.h>
+extern HINSTANCE hInstance;
+#endif
+
+#ifdef GEN_FF
+#include "../../../../Plugins/General/gen_ff/wa2frontend.h"
+#endif
+
+SystemScriptObjectController _systemController;
+SystemScriptObjectController *systemController = &_systemController;
+
+#define MAKI_RUNTIME_VERSION 2
+
+// -- Functions table -------------------------------------
+function_descriptor_struct SystemScriptObjectController::exportedFunction[] =
+{
+ {L"getRuntimeVersion", 0, (void*)SystemObject::vcpu_getVersion},
+ {L"onScriptLoaded", 0, (void*)SystemObject::vcpu_onScriptLoaded},
+ {L"onScriptUnloading", 0, (void*)SystemObject::vcpu_onScriptUnloading},
+ {L"onQuit", 0, (void*)SystemObject::vcpu_onQuit},
+ {L"onKeyDown", 1, (void*)SystemObject::vcpu_onKeyDown},
+ {L"onKeyUp", 1, (void*)SystemObject::vcpu_onKeyUp},
+ {L"onAccelerator", 3, (void*)SystemObject::vcpu_onAccelerator},
+ {L"getMousePosX", 0, (void*)SystemObject::vcpu_getMousePosX},
+ {L"getMousePosY", 0, (void*)SystemObject::vcpu_getMousePosY},
+ {L"isMinimized", 0, (void*)SystemObject::vcpu_isMinimized},
+ {L"restoreApplication", 0, (void*)SystemObject::vcpu_restoreApplication},
+ {L"activateApplication", 0, (void*)SystemObject::vcpu_activateApplication},
+ {L"minimizeApplication", 0, (void*)SystemObject::vcpu_minimizeApplication},
+ {L"isDesktopAlphaAvailable", 0, (void*)SystemObject::vcpu_isDesktopAlphaAvailable},
+ {L"isTransparencyAvailable", 0, (void*)SystemObject::vcpu_isTransparencyAvailable},
+//-----
+ {L"integerToString", 1, (void*)SystemObject::vcpu_integerToString},
+ {L"stringToInteger", 1, (void*)SystemObject::vcpu_stringToInteger},
+ {L"floatToString", 2, (void*)SystemObject::vcpu_floatToString},
+ {L"stringToFloat", 1, (void*)SystemObject::vcpu_stringToFloat},
+ {L"integerToTime", 1, (void*)SystemObject::vcpu_integerToTime},
+ {L"integerToLongTime", 1, (void*)SystemObject::vcpu_integerToLongTime},
+ {L"dateToTime", 1, (void*)SystemObject::vcpu_dateToTime},
+ {L"dateToLongTime", 1, (void*)SystemObject::vcpu_dateToLongTime},
+ {L"formatDate", 1, (void*)SystemObject::vcpu_formatDate},
+ {L"formatLongDate", 1, (void*)SystemObject::vcpu_formatLongDate},
+ {L"getDateYear", 1, (void*)SystemObject::vcpu_getDateYear},
+ {L"getDateMonth", 1, (void*)SystemObject::vcpu_getDateMonth},
+ {L"getDateDay", 1, (void*)SystemObject::vcpu_getDateDay},
+ {L"getDateDow", 1, (void*)SystemObject::vcpu_getDateDow},
+ {L"getDateDoy", 1, (void*)SystemObject::vcpu_getDateDoy},
+ {L"getDateHour", 1, (void*)SystemObject::vcpu_getDateHour},
+ {L"getDateMin", 1, (void*)SystemObject::vcpu_getDateMin},
+ {L"getDateSec", 1, (void*)SystemObject::vcpu_getDateSec},
+ {L"getDateDst", 1, (void*)SystemObject::vcpu_getDateDst},
+ {L"getDate", 0, (void*)SystemObject::vcpu_getDate},
+ {L"StrMid", 3, (void*)SystemObject::vcpu_strmid},
+ {L"StrLeft", 2, (void*)SystemObject::vcpu_strleft},
+ {L"StrRight", 2, (void*)SystemObject::vcpu_strright},
+ {L"StrSearch", 2, (void*)SystemObject::vcpu_strsearch},
+ {L"StrLen", 1, (void*)SystemObject::vcpu_strlen},
+ {L"StrUpper", 1, (void*)SystemObject::vcpu_strupper},
+ {L"StrLower", 1, (void*)SystemObject::vcpu_strlower},
+ {L"UrlEncode", 1, (void*)SystemObject::vcpu_urlencode},
+ {L"UrlDecode", 1, (void*)SystemObject::vcpu_urldecode},
+ {L"RemovePath", 1, (void*)SystemObject::vcpu_removepath},
+ {L"GetPath", 1, (void*)SystemObject::vcpu_getpath},
+ {L"GetExtension", 1, (void*)SystemObject::vcpu_getextension},
+ {L"getToken", 3, (void*)SystemObject::vcpu_gettoken},
+//-----
+ {L"sin", 1, (void*)SystemObject::vcpu_sin},
+ {L"cos", 1, (void*)SystemObject::vcpu_cos},
+ {L"tan", 1, (void*)SystemObject::vcpu_tan},
+ {L"asin", 1, (void*)SystemObject::vcpu_asin},
+ {L"acos", 1, (void*)SystemObject::vcpu_acos},
+ {L"atan", 1, (void*)SystemObject::vcpu_atan},
+ {L"atan2", 2, (void*)SystemObject::vcpu_atan2},
+ {L"pow", 2, (void*)SystemObject::vcpu_pow},
+ {L"sqr", 1, (void*)SystemObject::vcpu_sqr},
+ {L"sqrt", 1, (void*)SystemObject::vcpu_sqrt},
+ {L"random", 1, (void*)SystemObject::vcpu_random},
+ {L"integer", 1, (void*)SystemObject::vcpu_integer},
+ {L"frac", 1, (void*)SystemObject::vcpu_frac},
+ {L"ln", 1, (void*)SystemObject::vcpu_log},
+ {L"log10", 1, (void*)SystemObject::vcpu_log10},
+//-----
+ {L"getParam", 0, (void*)SystemObject::vcpu_getParam},
+ {L"getViewportWidth", 0, (void*)SystemObject::vcpu_getViewportWidth},
+ {L"getViewportHeight", 0, (void*)SystemObject::vcpu_getViewportHeight},
+ {L"getViewportLeft", 0, (void*)SystemObject::vcpu_getViewportLeft},
+ {L"getViewportTop", 0, (void*)SystemObject::vcpu_getViewportTop},
+ {L"getViewportWidthFromPoint", 2, (void*)SystemObject::vcpu_getViewportWidthFP},
+ {L"getViewportHeightFromPoint",2, (void*)SystemObject::vcpu_getViewportHeightFP},
+ {L"getViewportLeftFromPoint", 2, (void*)SystemObject::vcpu_getViewportLeftFP},
+ {L"getViewportTopFromPoint", 2, (void*)SystemObject::vcpu_getViewportTopFP},
+ {L"getViewportWidthFromGuiObject", 1, (void*)SystemObject::vcpu_getViewportWidthGO},
+ {L"getViewportHeightFromGuiObject", 1, (void*)SystemObject::vcpu_getViewportHeightGO},
+ {L"getViewportLeftFromGuiObject", 1, (void*)SystemObject::vcpu_getViewportLeftGO},
+ {L"getViewportTopFromGuiObject", 1, (void*)SystemObject::vcpu_getViewportTopGO},
+ {L"onViewPortChanged", 2, (void*)SystemObject::vcpu_onViewPortChanged},
+ {L"debugString", 2, (void*)SystemObject::vcpu_debugString},
+ {L"isObjectValid", 1, (void*)SystemObject::vcpu_isObjectValid},
+ {L"getTimeOfDay", 0, (void*)SystemObject::vcpu_getTimeOfDay},
+ {L"navigateUrl", 1, (void*)SystemObject::vcpu_navigateUrl},
+ {L"navigateUrlBrowser", 1, (void*)SystemObject::vcpu_navigateUrlBrowser},
+ {L"isKeyDown", 1, (void*)SystemObject::vcpu_isKeyDown},
+ {L"setClipboardText", 1, (void*)SystemObject::vcpu_setClipboard},
+ {L"Chr", 1, (void*)SystemObject::vcpu_chr},
+ {L"triggerAction", 3, (void*)SystemObject::vcpu_triggerAction},
+ {L"messageBox", 4, (void*)SystemObject::vcpu_messageBox},
+ {L"setAtom", 2, (void*)SystemObject::vcpu_setAtom},
+ {L"getAtom", 1, (void*)SystemObject::vcpu_getAtom},
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ {L"invokeDebugger", 0, (void*)SystemObject::vcpu_invokeDebugger},
+#endif
+#ifdef WASABI_COMPILE_SKIN
+ {L"newGroup", 1, (void*)SystemObject::vcpu_newGroup},
+ {L"onSetXuiParam", 2, (void*)SystemObject::vcpu_onSetXuiParam},
+ {L"getScriptGroup", 0, (void*)SystemObject::vcpu_getScriptGroup},
+ {L"getSkinName", 0, (void*)SystemObject::vcpu_getSkinName},
+ {L"newGroupAsLayout", 1, (void*)SystemObject::vcpu_newGroupAsLayout},
+ {L"getNumContainers", 0, (void*)SystemObject::vcpu_getNumContainers},
+ {L"enumContainer", 1, (void*)SystemObject::vcpu_enumContainer},
+ {L"onCreateLayout", 1, (void*)SystemObject::vcpu_onCreateLayout},
+ {L"onShowLayout", 1, (void*)SystemObject::vcpu_onShowLayout},
+ {L"onHideLayout", 1, (void*)SystemObject::vcpu_onHideLayout},
+ {L"switchSkin", 1, (void*)SystemObject::vcpu_switchSkin},
+ {L"isLoadingSkin", 0, (void*)SystemObject::vcpu_isLoadingSkin},
+ {L"lockUI", 0, (void*)SystemObject::vcpu_lockUI},
+ {L"unlockUI", 0, (void*)SystemObject::vcpu_unlockUI},
+#endif
+#if defined(WASABI_COMPILE_WNDMGR) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ {
+ L"getContainer", 1, (void*)SystemObject::vcpu_getContainer
+ },
+ {L"newDynamicContainer", 1, (void*)SystemObject::vcpu_newDynamicContainer},
+ {L"onGetCancelComponent", 2, (void*)SystemObject::vcpu_onGetCancelComponent},
+ {L"onLookForComponent", 1, (void*)SystemObject::vcpu_onLookForComponent},
+ {L"isAppActive", 0, (void*)SystemObject::vcpu_isAppActive},
+ {L"showWindow", 3, (void*)SystemObject::vcpu_showWindow},
+ {L"hideWindow", 1, (void*)SystemObject::vcpu_hideWindow},
+ {L"hideNamedWindow", 1, (void*)SystemObject::vcpu_hideNamedWindow},
+ {L"isNamedWindowVisible", 1, (void*)SystemObject::vcpu_isNamedWindowVisible},
+ {L"getCurAppLeft", 0, (void*)SystemObject::vcpu_getCurAppLeft},
+ {L"getCurAppTop", 0, (void*)SystemObject::vcpu_getCurAppTop},
+ {L"getCurAppWidth", 0, (void*)SystemObject::vcpu_getCurAppWidth},
+ {L"getCurAppHeight", 0, (void*)SystemObject::vcpu_getCurAppHeight},
+#endif
+#if defined (WASABI_COMPILE_CONFIG) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ {
+ L"setPrivateString", 3, (void*)SystemObject::vcpu_setPrivateString
+ },
+ {L"setPrivateInt", 3, (void*)SystemObject::vcpu_setPrivateInt},
+ {L"getPrivateString", 3, (void*)SystemObject::vcpu_getPrivateString},
+ {L"getPrivateInt", 3, (void*)SystemObject::vcpu_getPrivateInt},
+ {L"setPublicString", 2, (void*)SystemObject::vcpu_setPublicString},
+ {L"setPublicInt", 2, (void*)SystemObject::vcpu_setPublicInt},
+ {L"getPublicString", 2, (void*)SystemObject::vcpu_getPublicString},
+ {L"getPublicInt", 2, (void*)SystemObject::vcpu_getPublicInt},
+#endif
+#if defined (WASABI_COMPILE_MEDIACORE) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ {
+ L"getPlayItemString", 0, (void*)SystemObject::vcpu_getPlayItemString
+ },
+ {L"getPlayItemLength", 0, (void*)SystemObject::vcpu_getPlayItemLength},
+ {L"getPlayItemMetadataString", 1, (void*)SystemObject::vcpu_getPlayItemMetadataString},
+ {L"getMetadataString", 2, (void*)SystemObject::vcpu_getMetadataString},
+ {L"getPlayItemDisplayTitle", 0, (void*)SystemObject::vcpu_getPlayItemDisplayTitle},
+ {L"getExtFamily", 1, (void*)SystemObject::vcpu_getExtFamily},
+ {L"getDecoderName", 1, (void*)SystemObject::vcpu_getDecoderName},
+ {L"playFile", 1, (void*)SystemObject::vcpu_playFile},
+ {L"enqueueFile", 1, (void*)SystemObject::vcpu_enqueueFile},
+ {L"clearPlaylist", 0, (void*)SystemObject::vcpu_clearPlaylist},
+ {L"onStop", 0, (void*)SystemObject::vcpu_onStop},
+ {L"onPlay", 0, (void*)SystemObject::vcpu_onPlay},
+ {L"onPause", 0, (void*)SystemObject::vcpu_onPause},
+ {L"onResume", 0, (void*)SystemObject::vcpu_onResume},
+ {L"onTitleChange", 1, (void*)SystemObject::vcpu_onTitleChange},
+ {L"onTitle2Change", 1, (void*)SystemObject::vcpu_onTitle2Change},
+ {L"onUrlChange", 1, (void*)SystemObject::vcpu_onUrlChange},
+ {L"onInfoChange", 1, (void*)SystemObject::vcpu_onInfoChange},
+ {L"onStatusMsg", 1, (void*)SystemObject::vcpu_onStatusMsg},
+ {L"getLeftVuMeter", 0, (void*)SystemObject::vcpu_getLeftVuMeter},
+ {L"getRightVuMeter", 0, (void*)SystemObject::vcpu_getRightVuMeter},
+ {L"getVisBand", 2, (void*)SystemObject::vcpu_getVisBand},
+ {L"getVolume", 0, (void*)SystemObject::vcpu_getVolume},
+ {L"setVolume", 1, (void*)SystemObject::vcpu_setVolume},
+ {L"play", 0, (void*)SystemObject::vcpu_play},
+ {L"stop", 0, (void*)SystemObject::vcpu_stop},
+ {L"pause", 0, (void*)SystemObject::vcpu_pause},
+ {L"next", 0, (void*)SystemObject::vcpu_next},
+ {L"previous", 0, (void*)SystemObject::vcpu_previous},
+ {L"eject", 0, (void*)SystemObject::vcpu_eject},
+ {L"seekTo", 1, (void*)SystemObject::vcpu_seekTo},
+ {L"getPosition", 0, (void*)SystemObject::vcpu_getPosition},
+ {L"setEqBand", 2, (void*)SystemObject::vcpu_setEqBand},
+ {L"setEqPreAmp", 1, (void*)SystemObject::vcpu_setEqPreAmp},
+ {L"setEq", 1, (void*)SystemObject::vcpu_setEq},
+ {L"getEqBand", 1, (void*)SystemObject::vcpu_getEqBand},
+ {L"getEqPreAmp", 0, (void*)SystemObject::vcpu_getEqPreAmp},
+ {L"getEq", 0, (void*)SystemObject::vcpu_getEq},
+ {L"onEqBandChanged", 2, (void*)SystemObject::vcpu_onEqBandChanged},
+ {L"onEqFreqChanged", 1, (void*)SystemObject::vcpu_onEqFreqChanged},
+ {L"onEqPreAmpChanged", 1, (void*)SystemObject::vcpu_onEqPreAmpChanged},
+ {L"onEqChanged", 1, (void*)SystemObject::vcpu_onEqChanged},
+ {L"onVolumeChanged", 1, (void*)SystemObject::vcpu_onVolumeChanged},
+ {L"onSeek", 1, (void*)SystemObject::vcpu_onSeeked},
+ {L"getStatus", 0, (void*)SystemObject::vcpu_getStatus},
+ {L"getStatus", 0, (void*)SystemObject::vcpu_getStatus},
+ {L"getSongInfoText", 0, (void*)SystemObject::vcpu_getSongInfoText},
+ {L"getSongInfoTextTranslated", 0, (void*)SystemObject::vcpu_getSongInfoTextTranslated},
+ {L"hasVideoSupport", 0, (void*)SystemObject::vcpu_hasVideoSupport},
+ {L"isVideo", 0, (void*)SystemObject::vcpu_isVideo},
+ {L"isVideoFullscreen", 0, (void*)SystemObject::vcpu_isVideoFullscreen},
+ {L"setVideoFullscreen", 1, (void*)SystemObject::vcpu_setVideoFullscreen},
+ {L"getIdealVideoWidth", 0, (void*)SystemObject::vcpu_getIdealVideoWidth},
+ {L"getIdealVideoHeight", 0, (void*)SystemObject::vcpu_getIdealVideoHeight},
+ {L"getPlaylistIndex", 0, (void*)SystemObject::vcpu_getPlaylistIndex},
+ {L"onShowNotification", 0, (void*)SystemObject::vcpu_onShowNotification},
+ {L"getPlaylistLength", 0, (void*)SystemObject::vcpu_getPlaylistLength},
+ {L"getCurrentTrackRating", 0, (void *)SystemObject::vcpu_getRating},
+ {L"setCurrentTrackRating", 1, (void *)SystemObject::vcpu_setRating},
+#endif
+#if defined(WASABI_COMPILE_COMPONENTS) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ {
+ L"getWac", 1, (void*)SystemObject::vcpu_getWac
+ },
+#endif
+#if defined(WA3COMPATIBILITY) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ {
+ L"ddesend", 3, (void*)SystemObject::vcpu_ddeSend
+ },
+ {L"setMenuTransparency", 1, (void*)SystemObject::vcpu_setMenuTransparency},
+ {L"popMainBrowser", 0, (void*)SystemObject::vcpu_popMb},
+ {L"getMainBrowser", 0, (void*)SystemObject::vcpu_getMainMB},
+ {L"windowMenu", 0, (void*)SystemObject::vcpu_windowMenu},
+ {L"systemMenu", 0, (void*)SystemObject::vcpu_systemMenu},
+#endif
+#if defined (WA3COMPATIBILITY) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ {
+ L"selectFile", 3, (void*)SystemObject::vcpu_selectFile
+ },
+#endif
+ {L"selectFolder", 3, (void*)SystemObject::vcpu_selectFolder},
+ {L"onOpenURL", 1, (void*)SystemObject::vcpu_onOpenURL},
+ {L"getMonitorLeft", 0, (void*)SystemObject::vcpu_getMonitorLeftGO},
+ {L"getMonitorTop", 0, (void*)SystemObject::vcpu_getMonitorTopGO},
+ {L"getMonitorLeftFromPoint", 2, (void*)SystemObject::vcpu_getMonitorLeftFP},
+ {L"getMonitorTopFromPoint", 2, (void*)SystemObject::vcpu_getMonitorTopFP},
+ {L"getMonitorLeftFromGuiObject", 1, (void*)SystemObject::vcpu_getMonitorLeftGO},
+ {L"getMonitorTopFromGuiObject", 1, (void*)SystemObject::vcpu_getMonitorTopGO},
+ {L"getMonitorWidth", 0, (void*)SystemObject::vcpu_getMonitorWidth},
+ {L"getMonitorHeight", 0, (void*)SystemObject::vcpu_getMonitorHeight},
+ {L"getMonitorWidthFromPoint", 2, (void*)SystemObject::vcpu_getMonitorWidthFP},
+ {L"getMonitorHeightFromPoint",2, (void*)SystemObject::vcpu_getMonitorHeightFP},
+ {L"getMonitorWidthFromGuiObject", 1, (void*)SystemObject::vcpu_getMonitorWidthGO},
+ {L"getMonitorHeightFromGuiObject", 1, (void*)SystemObject::vcpu_getMonitorHeightGO},
+ {L"downloadURL", 3, (void*)SystemObject::vcpu_downloadURL},
+ {L"downloadMedia", 4, (void*)SystemObject::vcpu_downloadMedia},
+ {L"onDownloadFinished", 3, (void*)SystemObject::vcpu_onDownloadFinished},
+ {L"getDownloadPath", 0, (void*)SystemObject::vcpu_getDownloadPath},
+ {L"setDownloadPath", 1, (void*)SystemObject::vcpu_setDownloadPath},
+ {L"getAlbumArt", 1, (void*)SystemObject::vcpu_getAlbumArt},
+ {L"isProVersion", 0, (void*)SystemObject::vcpu_isWinampPro}, // ugh, i hate putting this here but ohh well
+ {L"enumEmbedGUID", 1, (void*)SystemObject::vcpu_enumEmbedGUID}, // ugh, i hate putting this here but ohh well
+ {L"getWinampVersion",0, (void*)SystemObject::vcpu_getWinampVersion},
+ {L"getBuildNumber",0, (void*)SystemObject::vcpu_getBuildNumber},
+ {L"getFileSize",1, (void*)SystemObject::vcpu_getFileSize},
+ {L"getString", 2, (void*)SystemObject::vcpu_getString},
+ {L"translate", 1, (void*)SystemObject::vcpu_translate},
+ {L"getLanguageId", 0, (void*)SystemObject::vcpu_getLanguageId}
+};
+// --------------------------------------------------------
+
+
+const wchar_t *SystemScriptObjectController::getClassName()
+{
+ return L"SystemObject";
+}
+
+const wchar_t *SystemScriptObjectController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObject *SystemScriptObjectController::instantiate()
+{
+ return NULL;
+}
+
+void SystemScriptObjectController::destroy(ScriptObject *o)
+{
+ ASSERTALWAYS("don't delete systemobject!");
+}
+
+void *SystemScriptObjectController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void SystemScriptObjectController::deencapsulate(void *o)
+{
+}
+
+int SystemScriptObjectController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *SystemScriptObjectController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID SystemScriptObjectController::getClassGuid()
+{
+ return systemObjectGuid;
+}
+
+int SystemScriptObjectController::getReferenceable()
+{
+ return 0;
+}
+
+int SystemScriptObjectController::getInstantiable()
+{
+ return 0;
+}
+
+#ifndef _NOSTUDIO
+
+SystemObject::SystemObject()
+{
+ getScriptObject()->vcpu_setInterface( systemObjectGuid, ( void * )static_cast<SystemObject *>( this ) );
+ getScriptObject()->vcpu_setClassName( L"System" );
+ getScriptObject()->vcpu_setController( systemController );
+
+ loaded = 0;
+ started_up = 0;
+ scriptVCPUId = -1;
+ isoldformat = 0;
+ parentGroup = NULL;
+
+#ifdef WASABI_COMPILE_SKIN
+ skinpartid = WASABI_API_PALETTE->getSkinPartIterator();
+#else
+ skinpartid = -1;
+#endif
+
+ SOM::registerSystemObject( this );
+
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_addCallback( 0, this );
+#endif
+
+ WASABI_API_SYSCB->syscb_registerCallback( this );
+}
+
+SystemObject::~SystemObject()
+{
+ SOM::unregisterSystemObject( this );
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_delCallback( 0, this );
+#endif
+ WASABI_API_SYSCB->syscb_deregisterCallback( this );
+}
+
+void SystemObject::setScriptId( int id )
+{
+ scriptVCPUId = id;
+}
+
+int SystemObject::getScriptId()
+{
+ return scriptVCPUId;
+}
+
+void SystemObject::setParam( const wchar_t *p )
+{
+#ifdef WASABI_COMPILE_WNDMGR
+ StringW *s = PublicVarManager::translate_nocontext( p );
+ if ( s )
+ param.swap( s );
+ else
+ param = p;
+ delete s;
+#else
+ param = p;
+#endif
+}
+
+void SystemObject::setParentGroup( Group *g )
+{
+ parentGroup = g;
+}
+
+Group *SystemObject::getParentGroup()
+{
+ return parentGroup;
+}
+
+const wchar_t *SystemObject::getParam()
+{
+ return param;
+}
+
+void SystemObject::onLoad()
+{
+ loaded = 1;
+ vcpu_onScriptLoaded( SCRIPT_CALL, getScriptObject() );
+ started_up = 1;
+}
+
+void SystemObject::onUnload()
+{
+ if ( loaded && started_up )
+ vcpu_onScriptUnloading( SCRIPT_CALL, getScriptObject() );
+
+ // that was the script's last chance to delete its stuff, now we need to garbageCollect whatever is left
+ garbageCollect();
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+WindowHolder *SystemObject::getSuitableWindowHolderByGuid( GUID g )
+{
+ wchar_t guidstr[ 256 ] = { 0 };
+ nsGUID::toCharW( g, guidstr );
+ scriptVar v = vcpu_onLookForComponent( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( guidstr ) );
+
+ if ( v.type == SCRIPT_OBJECT )
+ {
+ ScriptObject *ret = GET_SCRIPT_OBJECT( v );
+ if ( ret )
+ {
+ WindowHolder *co = static_cast<WindowHolder *>( ret->vcpu_getInterface( windowHolderGuid ) );
+ return co;
+ }
+ }
+ return NULL;
+}
+
+int SystemObject::onGetCancelComponent( GUID g, int i )
+{
+ wchar_t guidstr[ 256 ] = { 0 };
+ nsGUID::toCharW( g, guidstr );
+ scriptVar v = vcpu_onGetCancelComponent( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( guidstr ), MAKE_SCRIPT_BOOLEAN( i ) );
+
+ if ( v.type != SCRIPT_VOID )
+ return GET_SCRIPT_INT( v );
+
+ return 0;
+}
+
+void SystemObject::onViewPortChanged( int width, int height )
+{
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0; i-- )
+ vcpu_onViewPortChanged( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_INT( width ), MAKE_SCRIPT_INT( height ) );
+}
+
+int SystemObject::onShowNotification()
+{
+ WASABI_API_MAKI->vcpu_resetComplete();
+#if defined(WASABI_COMPILE_MEDIACORE) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0 && !WASABI_API_MAKI->vcpu_getComplete(); i-- )
+ {
+ scriptVar v = vcpu_onShowNotification( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject() );
+ if ( v.type != SCRIPT_VOID )
+ return GET_SCRIPT_INT( v );
+ }
+#endif
+ return 0;
+}
+
+void SystemObject::onCreateLayout( Layout *l )
+{
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0; i-- )
+ vcpu_onCreateLayout( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_OBJECT( l->getGuiObject()->guiobject_getScriptObject() ) );
+}
+
+void SystemObject::onShowLayout( Layout *l )
+{
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0; i-- )
+ vcpu_onShowLayout( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_OBJECT( l->getGuiObject()->guiobject_getScriptObject() ) );
+}
+
+void SystemObject::onHideLayout( Layout *l )
+{
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0; i-- )
+ vcpu_onHideLayout( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_OBJECT( l->getGuiObject()->guiobject_getScriptObject() ) );
+}
+
+int SystemObject::getCurAppRect( RECT *r )
+{
+ ASSERT( r );
+#ifdef WIN32
+ HWND w = GetForegroundWindow();
+ if ( !IsWindowVisible( w ) ) return 0;
+ GetWindowRect( w, r );
+#else
+ DebugString( "portme SystemObject::getCurAppRect\n" );
+#endif
+ return 1;
+}
+
+void SystemObject::onQuit()
+{
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0; i-- )
+ vcpu_onQuit( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject() );
+}
+
+#endif // wndmgr
+
+static bool FilterBrowserUrl( const wchar_t *url )
+{
+ const wchar_t filterNowPlaying[] = L"http://client.winamp.com/nowplaying";
+ size_t urlLength, filterLength;
+
+ if ( NULL == url )
+ return false;
+
+ urlLength = wcslen( url );
+ filterLength = sizeof( filterNowPlaying ) / sizeof( filterNowPlaying[ 0 ] ) - 1;
+ if ( urlLength >= filterLength &&
+ 0 == _wcsnicmp( url, filterNowPlaying, filterLength ) )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void SystemObject::browsercb_onOpenURL( wchar_t *url, bool *override )
+{
+ if ( !*override && false == FilterBrowserUrl( url ) ) // ignore if someone else already overrode
+ {
+ scriptVar v = vcpu_onOpenURL( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( url ) );
+ if ( v.type == SCRIPT_INT )
+ {
+ if ( v.data.idata == 1 )
+ *override = true;
+ }
+ }
+}
+
+scriptVar SystemObject::vcpu_onOpenURL( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, url );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, url );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+void SystemObject::onKeyDown( const wchar_t *s )
+{
+ WASABI_API_MAKI->vcpu_resetComplete();
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0 && !WASABI_API_MAKI->vcpu_getComplete(); i-- )
+ vcpu_onKeyDown( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_STRING( s ) );
+}
+
+void SystemObject::onKeyUp( const wchar_t *s )
+{
+ WASABI_API_MAKI->vcpu_resetComplete();
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0 && !WASABI_API_MAKI->vcpu_getComplete(); i-- )
+ vcpu_onKeyUp( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_STRING( s ) );
+}
+
+int SystemObject::onAccelerator( const wchar_t *action, const wchar_t *section, const wchar_t *key )
+{
+ int r = 0;
+ WASABI_API_MAKI->vcpu_resetComplete();
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0 && !WASABI_API_MAKI->vcpu_getComplete(); i-- )
+ {
+ scriptVar v = vcpu_onAccelerator( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_STRING( action ), MAKE_SCRIPT_STRING( section ), MAKE_SCRIPT_STRING( key ) );
+ if ( SOM::isNumeric( &v ) )
+ r |= GET_SCRIPT_INT( v );
+ }
+ return r;
+}
+
+void SystemObject::onDownloadFinished( const wchar_t *url, boolean success, const wchar_t *filename )
+{
+ for ( int i = SOM::getNumSystemObjects() - 1; i >= 0; i-- )
+ vcpu_onDownloadFinished( SCRIPT_CALL, SOM::getSystemObject( i )->getScriptObject(), MAKE_SCRIPT_STRING( url ), MAKE_SCRIPT_BOOLEAN( success ), MAKE_SCRIPT_STRING( filename ) );
+}
+
+TList < int > *SystemObject::getTypesList()
+{
+ return &typeslist;
+}
+
+void SystemObject::setIsOldFormat( int is )
+{
+ isoldformat = is;
+}
+
+int SystemObject::isOldFormat()
+{
+ return isoldformat;
+}
+#endif
+
+#ifdef WASABI_COMPILE_WND
+int SystemObject::isAppActive()
+{
+#ifdef WIN32
+ HWND w = GetForegroundWindow();
+ wchar_t classname[ 256 ] = L"";
+ GetClassNameW( w, classname, 256 );
+ return ( w == WASABI_API_WND->main_getRootWnd()->gethWnd() || !wcscmp( classname, BASEWNDCLASSNAME ) );
+#else
+ DebugString( "portme SystemObject::isAppActive\n" );
+ return 1;
+#endif
+}
+#endif
+
+void SystemObject::setSkinPartId( int _skinpartid )
+{
+ skinpartid = _skinpartid;
+}
+
+int SystemObject::getSkinPartId()
+{
+ return skinpartid;
+}
+
+void SystemObject::addInstantiatedObject( ScriptObject *obj )
+{
+ ASSERT( !instantiated.haveItem( obj ) );
+ instantiated.addItem( obj );
+}
+
+void SystemObject::removeInstantiatedObject( ScriptObject *obj )
+{
+ int n = instantiated.searchItem( obj );
+ if ( n < 0 ) return; //ASSERT(n >= 0);
+ instantiated.removeByPos( n );
+}
+
+void SystemObject::garbageCollect()
+{
+ foreach( instantiated )
+ ObjectTable::destroy( instantiated.getfor() );
+ endfor
+ instantiated.removeAll();
+}
+
+int SystemObject::isObjectValid( ScriptObject *o )
+{
+ static ScriptObject *cached = NULL;
+ static int cachedn = -1;
+ if ( o == cached && scriptobjects.enumItem( cachedn ) == o ) return 1;
+ int is = scriptobjects.searchItem( o );
+ if ( is >= 0 )
+ {
+ cached = o;
+ cachedn = is;
+ }
+ return ( is > -1 );
+}
+
+void SystemObject::addScriptObject( ScriptObject *o )
+{
+ ASSERT( !scriptobjects.haveItem( o ) );
+ scriptobjects.addItem( o );
+}
+
+void SystemObject::removeScriptObject( ScriptObject *o )
+{
+ int pos = scriptobjects.searchItem( o );
+ if ( pos < 0 ) return;
+ scriptobjects.removeByPos( pos );
+}
+
+#ifdef WASABI_COMPILE_SKIN
+void SystemObject::onSetXuiParam( const wchar_t *param, const wchar_t *value )
+{
+ vcpu_onSetXuiParam( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( param ), MAKE_SCRIPT_STRING( value ) );
+}
+#endif
+
+void SystemObject::navigateUrl( const wchar_t *url )
+{
+#ifdef WA3COMPATIBILITY
+ if ( MainMiniBrowser::getScriptObject() )
+ {
+ MainMiniBrowser::navigateUrl( url );
+ MainMiniBrowser::popMb();
+ }
+ else // no minibrowser container -> launch IE
+ {
+ Std::shellExec( url );
+ }
+#else
+ Wasabi::Std::shellExec( url );
+#endif
+}
+
+void SystemObject::navigateUrlBrowser( const wchar_t *url )
+{
+ wa2.openUrl( url );
+}
+
+scriptVar SystemObject::vcpu_getVersion( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ return MAKE_SCRIPT_DOUBLE( MAKI_RUNTIME_VERSION );
+}
+
+scriptVar SystemObject::vcpu_onScriptLoaded( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SystemObject *so = static_cast<SystemObject *>( o->vcpu_getInterface( systemObjectGuid ) );
+ ASSERT( so != NULL );
+ return WASABI_API_MAKI->maki_triggerEvent( o, DLF_ID, 0, so->scriptVCPUId );
+}
+
+scriptVar SystemObject::vcpu_onScriptUnloading( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SystemObject *so = static_cast<SystemObject *>( o->vcpu_getInterface( systemObjectGuid ) );
+ ASSERT( so != NULL );
+ return WASABI_API_MAKI->maki_triggerEvent( o, DLF_ID, 0, so->scriptVCPUId );
+}
+
+scriptVar SystemObject::vcpu_onQuit( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT0( o );
+}
+
+#ifdef WASABI_COMPILE_SKIN
+scriptVar SystemObject::vcpu_onSetXuiParam( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar param, scriptVar value )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2( o, systemController, param, value );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT2( o, param, value );
+}
+
+scriptVar SystemObject::vcpu_getSkinName( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_STRING( WASABI_API_SKIN->getSkinName() );
+}
+
+scriptVar SystemObject::vcpu_switchSkin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar skinname )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef SWITCH_SKIN
+ SWITCH_SKIN( GET_SCRIPT_STRING( skinname ) );
+#else
+ WASABI_API_SKIN->skin_switchSkin( GET_SCRIPT_STRING( skinname ) );
+#endif
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar SystemObject::vcpu_isLoadingSkin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ int l = 0;
+#ifdef IS_SKIN_STILL_LOADING
+ IS_SKIN_STILL_LOADING( l );
+#endif
+ if ( !l ) return MAKE_SCRIPT_INT( Skin::isLoading() );
+ return MAKE_SCRIPT_INT( l );
+}
+
+scriptVar SystemObject::vcpu_lockUI( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ WASABI_API_SKIN->skin_setLockUI( 1 );
+ RETURN_SCRIPT_NULL;
+}
+
+scriptVar SystemObject::vcpu_unlockUI( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ WASABI_API_SKIN->skin_setLockUI( 0 );
+ RETURN_SCRIPT_NULL;
+}
+
+#endif
+
+scriptVar SystemObject::vcpu_isObjectValid( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar o )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_BOOLEAN( SystemObject::isObjectValid( GET_SCRIPT_OBJECT( o ) ) );
+}
+
+scriptVar SystemObject::vcpu_getTimeOfDay( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ time_t ts = Wasabi::Std::getTimeStamp();
+ struct tm *tm_now;
+ tm_now = localtime( (const time_t *)&ts );
+ uint32_t tcnow = Wasabi::Std::getTickCount();
+ static uint32_t lasttc = 0;
+
+ int v = tm_now->tm_hour * 3600000 + tm_now->tm_min * 60000 + tm_now->tm_sec * 1000;
+
+ // yay milliseconds!
+
+ static int lastv = 0;
+ static int total = 0;
+ int tv = v;
+ if ( v == lastv )
+ {
+ total += tcnow - lasttc;
+ v += total;
+ }
+ else total = 0;
+ lasttc = tcnow;
+ lastv = tv;
+
+ return MAKE_SCRIPT_INT( v );
+}
+
+scriptVar SystemObject::vcpu_navigateUrl( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url )
+{
+ SCRIPT_FUNCTION_INIT;
+ SystemObject::navigateUrl( GET_SCRIPT_STRING( url ) );
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_navigateUrlBrowser( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url )
+{
+ SCRIPT_FUNCTION_INIT;
+ SystemObject::navigateUrlBrowser( GET_SCRIPT_STRING( url ) );
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_isKeyDown( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar vk_code )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( Std::keyDown( GET_SCRIPT_INT( vk_code ) ) );
+}
+
+scriptVar SystemObject::vcpu_setClipboard( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar text )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef _WIN32
+ const wchar_t *source = GET_SCRIPT_STRING( text );
+ DebugStringW( L"%s\n", source );
+ OpenClipboard( 0 );
+ EmptyClipboard();
+ int len = ( wcslen( source ) + 1 );
+ HGLOBAL clipbuffer = GlobalAlloc( GMEM_DDESHARE, sizeof( wchar_t ) * len );
+ wchar_t *buffer = (wchar_t *)GlobalLock( clipbuffer );
+ wcsncpy( buffer, source, len - 1 );
+ GlobalUnlock( clipbuffer );
+ SetClipboardData( CF_UNICODETEXT, clipbuffer );
+ CloseClipboard();
+#else
+ DebugString( "portme SystemObject::vcpu_setClipboard\n" );
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_chr( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar n )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSCPYN( staticStr, StringPrintfW( L"%c", GET_SCRIPT_INT( n ) ), 4096 );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_onAccelerator( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar action, scriptVar section, scriptVar key )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS3( o, systemController, action, section, key );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT3( o, action, section, key );
+}
+
+scriptVar SystemObject::vcpu_triggerAction( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar guiobj, scriptVar actionstr, scriptVar paramstr )
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT( actionstr.type == SCRIPT_STRING );
+ ASSERT( paramstr.type == SCRIPT_STRING );
+ const wchar_t *astr = GET_SCRIPT_STRING( actionstr );
+ const wchar_t *pstr = GET_SCRIPT_STRING( paramstr );
+#ifdef WASABI_COMPILE_WNDMGR
+ ScriptObject *context = guiobj.data.odata;
+ if ( context != NULL )
+ {
+ GuiObject *go = static_cast<GuiObject *>( context->vcpu_getInterface( guiObjectGuid ) );
+ if ( go != NULL )
+ {
+ ifc_window *wc = go->guiobject_getRootWnd();
+ if ( wc != NULL )
+ {
+ ifc_window *lr = wc->getDesktopParent();
+ if ( lr != NULL )
+ {
+ Layout *lay = static_cast<Layout *>( lr->getInterface( layoutGuid ) );
+ if ( lay != NULL )
+ {
+ int ia = WASABI_API_SKIN->parse( astr, L"internal_action" );
+ if ( ia == ACTION_NONE )
+ {
+ ActionEnum ae( astr );
+ svc_action *act = ae.getFirst();
+ if ( act )
+ {
+ act->onAction( astr, pstr, 0, 0, NULL, 0, wc );
+ SvcEnum::release( act );
+ }
+ }
+ else
+ lay->runAction( ia, pstr );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ActionEnum ae( astr );
+ svc_action *act = ae.getFirst();
+ if ( act )
+ {
+ act->onAction( astr, pstr );
+ SvcEnum::release( act );
+ }
+ }
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_getParam( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ SystemObject *o = static_cast<SystemObject *>( object->vcpu_getInterface( systemObjectGuid ) );
+ if ( o ) return MAKE_SCRIPT_STRING( o->getParam() );
+ return MAKE_SCRIPT_STRING( L"" );
+}
+
+#ifdef WASABI_COMPILE_SKIN
+scriptVar SystemObject::vcpu_getScriptGroup( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ SystemObject *o = static_cast<SystemObject *>( object->vcpu_getInterface( systemObjectGuid ) );
+ if ( o )
+ {
+ Group *g = o->getParentGroup();
+ return MAKE_SCRIPT_OBJECT( g ? g->getScriptObject() : NULL );
+ }
+ return MAKE_SCRIPT_OBJECT( NULL );
+}
+
+scriptVar SystemObject::vcpu_newGroup( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar groupname )
+{
+ SCRIPT_FUNCTION_INIT;
+ GuiObject *g = SkinParser::newDynamicGroup( GET_SCRIPT_STRING( groupname ), GROUP_GROUP );
+ if ( g != NULL )
+ {
+ SystemObject *so = static_cast<SystemObject *>( object->vcpu_getInterface( systemObjectGuid ) );
+ so->addInstantiatedObject( g->guiobject_getScriptObject() );
+ }
+ return MAKE_SCRIPT_OBJECT( g ? g->guiobject_getScriptObject() : NULL );
+}
+#endif
+
+scriptVar SystemObject::vcpu_getMousePosX( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt;
+ Wasabi::Std::getMousePos( &pt );
+ return MAKE_SCRIPT_INT( pt.x );
+}
+
+scriptVar SystemObject::vcpu_getMousePosY( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt;
+ Wasabi::Std::getMousePos( &pt );
+ return MAKE_SCRIPT_INT( pt.y );
+}
+
+scriptVar SystemObject::vcpu_minimizeApplication( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef _WIN32
+ ShowWindow( WASABI_API_WND->main_getRootWnd()->gethWnd(), SW_MINIMIZE );
+#else
+ #warning port me
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_activateApplication( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef _WIN32
+ SetForegroundWindow( WASABI_API_WND->main_getRootWnd()->gethWnd() );
+#else
+ #warning port me
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_restoreApplication( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef _WIN32
+ ShowWindow( WASABI_API_WND->main_getRootWnd()->gethWnd(), SW_RESTORE );
+#else
+ #warning port me
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_isDesktopAlphaAvailable( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ extern _bool cfg_uioptions_desktopalpha;
+ return MAKE_SCRIPT_INT( Wasabi::Std::Wnd::isDesktopAlphaAvailable() && cfg_uioptions_desktopalpha.getValueAsInt() );
+#else
+ return MAKE_SCRIPT_INT( Wasabi::Std::Wnd::isDesktopAlphaAvailable() );
+#endif
+}
+
+scriptVar SystemObject::vcpu_isTransparencyAvailable( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( Wasabi::Std::Wnd::isTransparencyAvailable() );
+}
+
+scriptVar SystemObject::vcpu_isMinimized( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef _WIN32
+ return MAKE_SCRIPT_INT( IsIconic( WASABI_API_WND->main_getRootWnd()->gethWnd() ) );
+#else
+ #warning port me
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+// extern String System.translate(String str);
+scriptVar SystemObject::vcpu_translate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSCPYN( translateStr, _( GET_SCRIPT_STRING( str ) ), ( sizeof( translateStr ) / sizeof( *translateStr ) ) );
+ return MAKE_SCRIPT_STRING( translateStr );
+}
+
+// extern String System.getString(String table, Int id);
+scriptVar SystemObject::vcpu_getString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar table, scriptVar id )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *xlat = LocalesManager::GetString( GET_SCRIPT_STRING( table ), GET_SCRIPT_INT( id ) );
+ if ( xlat )
+ return MAKE_SCRIPT_STRING( xlat );
+ else
+ return MAKE_SCRIPT_STRING( L"" );
+}
+
+// extern String System.getString(String table, Int id);
+scriptVar SystemObject::vcpu_getLanguageId( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *langId = WASABI_API_LNG->GetLanguageIdentifier( LANG_IDENT_STR );
+ if ( langId )
+ return MAKE_SCRIPT_STRING( langId );
+ else
+ return MAKE_SCRIPT_STRING( L"" );
+}
+
+scriptVar SystemObject::vcpu_integerToString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar i )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSNPRINTF( staticStr, 4096, L"%d", GET_SCRIPT_INT( i ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_stringToInteger( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar s )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( WTOI( GET_SCRIPT_STRING( s ) ) );
+}
+
+scriptVar SystemObject::vcpu_floatToString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar f, scriptVar digits )
+{
+ SCRIPT_FUNCTION_INIT;
+ // to whoever made this use StringPrintf, you left out the digits param, GRRRRRR!!
+ double v = GET_SCRIPT_DOUBLE( f );
+ StringPrintfW tmp( v );
+ WCSCPYN( staticStr, tmp, ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ wchar_t *p = wcschr( staticStr, '.' );
+ if ( p )
+ {
+ int numdigits = GET_SCRIPT_INT( digits );
+ if ( numdigits > 0 )
+ {
+ int n = numdigits;
+ int curnumdigits = staticStr + wcslen( staticStr ) - ( p + 1 );
+ n -= curnumdigits;
+ if ( n > 0 )
+ {
+ for ( int i = 0; i < n && i < ( sizeof( staticStr ) / sizeof( *staticStr ) ) - 128; i++ )
+ wcscat( staticStr, L"0" );
+ }
+ else if ( n < 0 )
+ {
+ *( p + 1 + numdigits ) = 0;
+ }
+ }
+ else
+ {
+ *p = 0;
+ }
+ }
+ else
+ {
+ int n = GET_SCRIPT_INT( digits );
+ if ( n > 0 )
+ {
+ wcscat( staticStr, L"." );
+ for ( int i = 0; i < n && i < ( sizeof( staticStr ) / sizeof( *staticStr ) ) - 128; i++ )
+ wcscat( staticStr, L"0" );
+ }
+ }
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_stringToFloat( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar s )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_FLOAT( (float)WTOF( GET_SCRIPT_STRING( s ) ) );
+}
+
+scriptVar SystemObject::vcpu_integerToTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ int i = GET_SCRIPT_INT( _i );
+ WCSNPRINTF( staticStr, 4096, L"%d:%02d", i / 60000, i % 60000 / 1000 );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_integerToLongTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ int i = GET_SCRIPT_INT( _i );
+ WCSNPRINTF( staticStr, 4096, L"%d:%02d:%02d", i / 3600000, ( i % 3600000 ) / 60000, i % 60000 / 1000 );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_dateToTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ WCSNPRINTF( staticStr, 4096, L"%d:%02d", t->tm_hour, t->tm_min );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_dateToLongTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ WCSNPRINTF( staticStr, 4096, L"%d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_formatDate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ wcsftime( staticStr, 4096, L"%c", t );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_formatLongDate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ wcsftime( staticStr, 4096, L"%#c", t );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_getDateYear( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_year );
+}
+
+scriptVar SystemObject::vcpu_getDateMonth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_mon );
+}
+
+scriptVar SystemObject::vcpu_getDateDay( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_mday );
+}
+
+scriptVar SystemObject::vcpu_getDateDow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_wday );
+}
+
+scriptVar SystemObject::vcpu_getDateDoy( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_yday );
+}
+
+scriptVar SystemObject::vcpu_getDateHour( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_hour );
+}
+
+scriptVar SystemObject::vcpu_getDateMin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_min );
+}
+
+scriptVar SystemObject::vcpu_getDateSec( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_sec );
+}
+
+scriptVar SystemObject::vcpu_getDateDst( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i )
+{
+ SCRIPT_FUNCTION_INIT;
+ //CUT: int i = GET_SCRIPT_INT(_i);
+ time_t tt = GET_SCRIPT_INT( _i );
+ struct tm *t = localtime( &tt );
+ return MAKE_SCRIPT_INT( t->tm_isdst );
+}
+
+scriptVar SystemObject::vcpu_getDate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ time_t t;
+ time( &t );
+ return MAKE_SCRIPT_INT( (int)t );
+}
+
+scriptVar SystemObject::vcpu_strmid( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str, scriptVar start, scriptVar len )
+{
+ SCRIPT_FUNCTION_INIT;
+ SOM::mid( staticStr, GET_SCRIPT_STRING( str ), MIN( GET_SCRIPT_INT( start ), 4096 ), MIN( GET_SCRIPT_INT( len ), 4096 ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_strleft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str, scriptVar len )
+{
+ SCRIPT_FUNCTION_INIT;
+ SOM::mid( staticStr, GET_SCRIPT_STRING( str ), 0, MIN( GET_SCRIPT_INT( len ), 4096 ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_strright( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str, scriptVar _len )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *str = GET_SCRIPT_STRING( _str );
+ int len = GET_SCRIPT_INT( _len );
+ SOM::mid( staticStr, str, MIN( (int)( wcslen( str ) - len ), 4096 ), MIN( len, 4096 ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_strsearch( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str, scriptVar substr )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *str = GET_SCRIPT_STRING( _str );
+ const wchar_t *p = wcsstr( str, GET_SCRIPT_STRING( substr ) );
+ return MAKE_SCRIPT_INT( p ? p - str : -1 );
+}
+
+scriptVar SystemObject::vcpu_strlen( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( wcslen( GET_SCRIPT_STRING( str ) ) );
+}
+
+scriptVar SystemObject::vcpu_strupper( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSCPYN( staticStr, GET_SCRIPT_STRING( _str ), ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ WCSTOUPPER( staticStr );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_strlower( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSCPYN( staticStr, GET_SCRIPT_STRING( _str ), ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ WCSTOLOWER( staticStr );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_urlencode( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ StringW str( GET_SCRIPT_STRING( _str ) );
+ str = AutoWide( AutoUrl( str ) );
+ *staticStr = 0;
+ if ( !str.isempty() ) WCSCPYN( staticStr, str, ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_urldecode( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ StringW str( GET_SCRIPT_STRING( _str ) );
+ Url::decode( str ); // Martin> I know there might be something nicer than this, but this does at least work
+ *staticStr = 0;
+ if ( !str.isempty() ) WCSCPYN( staticStr, str, ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_removepath( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ PathParserW pp( GET_SCRIPT_STRING( _str ) );
+// ASSERT(pp.getNumStrings() >= 1); // shouldn't happen ever
+ wchar_t *lastString = pp.getLastString();
+ if ( lastString )
+ {
+ WCSCPYN( staticStr, lastString, ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ }
+ else
+ {
+ staticStr[ 0 ] = 0;
+ }
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_getpath( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSCPYN( staticStr, GET_SCRIPT_STRING( _str ), ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+#ifdef _WIN32
+ PathRemoveFileSpecW( staticStr );
+ PathRemoveBackslashW( staticStr );
+#else
+ #warning port me
+#endif
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_getextension( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *pt = Wasabi::Std::extension( GET_SCRIPT_STRING( _str ) );
+ if ( pt != NULL ) WCSCPYN( staticStr, pt, ( sizeof( staticStr ) / sizeof( *staticStr ) ) );
+ else *staticStr = '\0';
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_gettoken( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar tok, scriptVar sep, scriptVar num )
+{
+ SCRIPT_FUNCTION_INIT;
+ wchar_t *p = const_cast<wchar_t *>( GET_SCRIPT_STRING( tok ) );
+ wchar_t *d = const_cast<wchar_t *>( GET_SCRIPT_STRING( sep ) );
+ int i = GET_SCRIPT_INT( num );
+ if ( !d ) return MAKE_SCRIPT_STRING( L"" );
+ if ( !p ) return MAKE_SCRIPT_STRING( L"" );
+ wchar_t c = *d;
+ d = staticStr;
+ int n = 0, ct = 0;
+ while ( p && *p && ct < 4096 )
+ {
+ if ( *p == c )
+ {
+ n++; p++; continue;
+ }
+ if ( n > i ) break;
+ if ( n == i )
+ *d++ = *p;
+ p++;
+ ct++;
+ }
+ *d = 0;
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_sin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::sin( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_cos( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::cos( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_tan( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::tan( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_asin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::asin( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_acos( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::acos( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_atan( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::atan( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_atan2( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar y, scriptVar x )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::atan2( GET_SCRIPT_DOUBLE( y ), GET_SCRIPT_DOUBLE( x ) ) );
+}
+
+scriptVar SystemObject::vcpu_pow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::pow( GET_SCRIPT_DOUBLE( x ), GET_SCRIPT_DOUBLE( y ) ) );
+}
+
+scriptVar SystemObject::vcpu_sqr( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _d )
+{
+ SCRIPT_FUNCTION_INIT;
+ double d = GET_SCRIPT_DOUBLE( _d );
+ return MAKE_SCRIPT_DOUBLE( d * d );
+}
+
+scriptVar SystemObject::vcpu_sqrt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::sqrt( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_log10( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::log10( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+scriptVar SystemObject::vcpu_log( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_DOUBLE( ::log( GET_SCRIPT_DOUBLE( d ) ) );
+}
+
+
+scriptVar SystemObject::vcpu_random( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar m )
+{
+ SCRIPT_FUNCTION_INIT;
+ int m_ = GET_SCRIPT_INT( m );
+ return MAKE_SCRIPT_INT( m_ <= 0 ? 0 : ::rand() % m_ );
+}
+
+scriptVar SystemObject::vcpu_integer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+ // precision will get lost automatically
+ int _v = GET_SCRIPT_INT( v );
+ return MAKE_SCRIPT_INT( _v );
+}
+
+scriptVar SystemObject::vcpu_frac( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+ double _v = GET_SCRIPT_DOUBLE( v ) - GET_SCRIPT_INT( v );
+ return MAKE_SCRIPT_DOUBLE( _v );
+}
+
+scriptVar SystemObject::vcpu_onViewPortChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar width, scriptVar height )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2( o, systemController, width, height );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT2( o, width, height );
+}
+
+scriptVar SystemObject::vcpu_getViewportWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+}
+
+scriptVar SystemObject::vcpu_getViewportHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+}
+
+scriptVar SystemObject::vcpu_getViewportWidthGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle() );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getViewportHeightGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle() );
+
+ // benski> this prevents the window from going "fullscreen" but adds a one-line space at the bottom
+ RECT full = { 0 };
+ Wasabi::Std::getViewport( &full, o->guiobject_getRootWnd()->getOsWindowHandle(), true );
+ if (Wasabi::Std::rectEqual( &full, &r ) )
+ r.bottom--;
+
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getMonitorLeft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.left );
+}
+
+scriptVar SystemObject::vcpu_getMonitorLeftFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.left );
+}
+
+scriptVar SystemObject::vcpu_getMonitorLeftGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle(), 1 );
+ return MAKE_SCRIPT_INT( r.left );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.left );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getMonitorTop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.top );
+}
+
+scriptVar SystemObject::vcpu_getMonitorTopFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.top );
+}
+
+scriptVar SystemObject::vcpu_getMonitorTopGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle(), 1 );
+ return MAKE_SCRIPT_INT( r.top );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.top );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getMonitorWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+}
+
+scriptVar SystemObject::vcpu_getMonitorHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+}
+
+scriptVar SystemObject::vcpu_getMonitorWidthGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle(), 1 );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getMonitorHeightGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle(), true );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getViewportLeft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.left );
+}
+
+scriptVar SystemObject::vcpu_getViewportTop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { 0 };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.top );
+}
+
+scriptVar SystemObject::vcpu_getViewportLeftGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle() );
+ return MAKE_SCRIPT_INT( r.left );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.left );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getViewportTopGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ RECT r = { 0 };
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( obj, guiObjectGuid ) );
+ if ( o )
+ {
+ Wasabi::Std::getViewport( &r, o->guiobject_getRootWnd()->getOsWindowHandle() );
+ return MAKE_SCRIPT_INT( r.top );
+ }
+ else
+ {
+ POINT pt = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.top );
+ }
+ return MAKE_SCRIPT_INT( 0 );
+}
+
+scriptVar SystemObject::vcpu_getViewportWidthFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+}
+
+scriptVar SystemObject::vcpu_getMonitorHeightFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+}
+
+scriptVar SystemObject::vcpu_getMonitorWidthFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt, 1 );
+ return MAKE_SCRIPT_INT( r.right - r.left );
+}
+
+scriptVar SystemObject::vcpu_getViewportHeightFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.bottom - r.top );
+}
+
+scriptVar SystemObject::vcpu_getViewportLeftFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.left );
+}
+
+scriptVar SystemObject::vcpu_getViewportTopFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y )
+{
+ SCRIPT_FUNCTION_INIT;
+ POINT pt = { GET_SCRIPT_INT( x ),GET_SCRIPT_INT( y ) };
+ RECT r = { 0 };
+ Wasabi::Std::getViewport( &r, &pt );
+ return MAKE_SCRIPT_INT( r.top );
+}
+
+scriptVar SystemObject::vcpu_getTickCount( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT(Wasabi::Std::getTickCount() );
+}
+
+scriptVar SystemObject::vcpu_onKeyDown( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1( o, systemController, v );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, v );
+}
+
+scriptVar SystemObject::vcpu_onKeyUp( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1( o, systemController, v );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, v );
+}
+
+scriptVar SystemObject::vcpu_debugString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str, scriptVar severity )
+{
+ SCRIPT_FUNCTION_INIT;
+ DebugStringW( L"%s", GET_SCRIPT_STRING( str ) );
+ WASABI_API_SYSCB->syscb_issueCallback( SysCallback::CONSOLE, ConsoleCallback::DEBUGMESSAGE, GET_SCRIPT_INT( severity ), reinterpret_cast<intptr_t>( GET_SCRIPT_STRING( str ) ) );
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SystemObject::vcpu_messageBox( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar msg, scriptVar title, scriptVar flags, scriptVar nam )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ return MAKE_SCRIPT_INT( WASABI_API_WNDMGR->messageBox( GET_SCRIPT_STRING( msg ), GET_SCRIPT_STRING( title ), GET_SCRIPT_INT( flags ), GET_SCRIPT_STRING( nam ), NULL ) );
+#else
+ return MAKE_SCRIPT_INT( MessageBox( NULL, GET_SCRIPT_STRING( msg ), GET_SCRIPT_STRING( title ), GET_SCRIPT_INT( flags ) ) );
+#endif
+}
+
+scriptVar SystemObject::vcpu_getAtom( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar atomname )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_OBJECT( VCPU::getAtom( GET_SCRIPT_STRING( atomname ) ) );
+}
+
+scriptVar SystemObject::vcpu_setAtom( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar atomname, scriptVar obj )
+{
+ SCRIPT_FUNCTION_INIT;
+ VCPU::setAtom( GET_SCRIPT_STRING( atomname ), GET_SCRIPT_OBJECT( obj ) );
+ RETURN_SCRIPT_VOID;
+}
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+scriptVar SystemObject::vcpu_invokeDebugger( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ WASABI_API_MAKIDEBUG->debugger_createJITD( object->vcpu_getScriptId(), 1 );
+ RETURN_SCRIPT_VOID;
+}
+#endif
+
+#if defined (WASABI_COMPILE_WNDMGR) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+scriptVar SystemObject::vcpu_onCreateLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ PROCESS_HOOKS1( o, systemController, l );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, l );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onShowLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ PROCESS_HOOKS1( o, systemController, l );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, l );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onHideLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ PROCESS_HOOKS1( o, systemController, l );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, l );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getContainer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar contname )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ Container *c = SkinParser::script_getContainer( GET_SCRIPT_STRING( contname ) );
+ return MAKE_SCRIPT_OBJECT( c ? c->getScriptObject() : NULL );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+scriptVar SystemObject::vcpu_newDynamicContainer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar contname )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ Container *c = SkinParser::newDynamicContainer( GET_SCRIPT_STRING( contname ) );
+ return MAKE_SCRIPT_OBJECT( c ? c->getScriptObject() : NULL );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+scriptVar SystemObject::vcpu_newGroupAsLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar groupname )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ Group *g = GroupMgr::instantiate( GET_SCRIPT_STRING( groupname ), GROUP_LAYOUTGROUP );
+ if ( g )
+ {
+ Layout *l = static_cast<Layout *>( g );
+ ifc_window *par = l->getCustomOwner();
+ if ( !par ) par = WASABI_API_WND->main_getRootWnd();
+ g->setAutoResizeAfterInit( 0 );
+ g->setStartHidden( 1 );
+ g->setParent( par );
+
+#ifdef _WIN32
+ g->init( hInstance, par->gethWnd(), TRUE );
+#else
+ #warning port me
+ g->init( 0, par->gethWnd(), TRUE );
+#endif
+ SystemObject *so = SOM::getSystemObjectByScriptId( __vsd );
+ if ( so != NULL ) so->addInstantiatedObject( g->getScriptObject() );
+ }
+ return MAKE_SCRIPT_OBJECT( g ? g->getScriptObject() : NULL );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getNumContainers( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ return MAKE_SCRIPT_INT( SkinParser::getNumContainers() );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+scriptVar SystemObject::vcpu_enumContainer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar n )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ Container *c = SkinParser::enumContainer( GET_SCRIPT_INT( n ) );
+ return MAKE_SCRIPT_OBJECT( c ? c->getScriptObject() : NULL );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onLookForComponent( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar guid )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ PROCESS_HOOKS1( o, systemController, guid );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, guid );
+#else
+ RETURN_SCRIPT_VOID
+#endif
+}
+
+scriptVar SystemObject::vcpu_onGetCancelComponent( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar guid, scriptVar i )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ PROCESS_HOOKS2( o, systemController, guid, i );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT2( o, guid, i );
+#else
+ RETURN_SCRIPT_ZERO
+#endif
+}
+
+scriptVar SystemObject::vcpu_getCurAppLeft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ RECT r = { 0 };
+ int s = getCurAppRect( &r );
+ return MAKE_SCRIPT_INT( s ? r.left : -1 );
+#else
+ RETURN_SCRIPT_ZERO
+#endif
+}
+
+scriptVar SystemObject::vcpu_getCurAppTop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ RECT r = { 0 };
+ int s = getCurAppRect( &r );
+ return MAKE_SCRIPT_INT( s ? r.top : -1 );
+#else
+ RETURN_SCRIPT_ZERO
+#endif
+}
+
+scriptVar SystemObject::vcpu_getCurAppWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ RECT r = { 0 };
+ int s = getCurAppRect( &r );
+ return MAKE_SCRIPT_INT( s ? r.right - r.left : -1 );
+#else
+ RETURN_SCRIPT_ZERO
+#endif
+}
+
+scriptVar SystemObject::vcpu_getCurAppHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ RECT r = { 0 };
+ int s = getCurAppRect( &r );
+ return MAKE_SCRIPT_INT( s ? r.bottom - r.top : -1 );
+#else
+ RETURN_SCRIPT_ZERO
+#endif
+}
+
+scriptVar SystemObject::vcpu_isAppActive( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ return MAKE_SCRIPT_BOOLEAN( isAppActive() );
+#else
+ RETURN_SCRIPT_ZERO
+#endif
+}
+
+scriptVar SystemObject::vcpu_showWindow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar wndguidorgroup, scriptVar prefcontainer, scriptVar transient )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ const wchar_t *s = GET_SCRIPT_STRING( wndguidorgroup );
+ const wchar_t *p = GET_SCRIPT_STRING( prefcontainer );
+ int t = GET_SCRIPT_INT( transient );
+ if ( p != NULL && *p == 0 ) p = NULL;
+ GUID _g = nsGUID::fromCharW( s );
+#ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
+ if ( _g != INVALID_GUID )
+ {
+ int y = 0;
+ ON_CREATE_EXTERNAL_WINDOW_GUID( _g, y );
+ if ( y ) RETURN_SCRIPT_NULL;
+ }
+#endif
+ ifc_window *ret = NULL;
+ if ( _g != INVALID_GUID )
+ ret = WASABI_API_WNDMGR->skinwnd_createByGuid( _g, p, 0, NULL, t );
+ else
+ ret = WASABI_API_WNDMGR->skinwnd_createByGroupId( s, p, 0, NULL, t );
+ if ( ret )
+ {
+ if ( ret->getGuiObject() )
+ {
+ return MAKE_SCRIPT_OBJECT( ret->getGuiObject()->guiobject_getScriptObject() );
+ }
+ }
+#endif
+ RETURN_SCRIPT_NULL;
+}
+
+scriptVar SystemObject::vcpu_hideWindow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar hw )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ GuiObject *o = static_cast<GuiObject *>( GET_SCRIPT_OBJECT_AS( hw, guiObjectGuid ) );
+ if ( o )
+ WASABI_API_WNDMGR->skinwnd_destroy( o->guiobject_getRootWnd() );
+#endif
+ RETURN_SCRIPT_NULL;
+}
+
+scriptVar SystemObject::vcpu_hideNamedWindow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar guidorgroup )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_WNDMGR
+ const wchar_t *s = GET_SCRIPT_STRING( guidorgroup );
+ GUID _g = nsGUID::fromCharW( s );
+ ifc_window *w = NULL;
+ if ( _g != INVALID_GUID )
+ {
+ int n = WASABI_API_WNDMGR->skinwnd_getNumByGuid( _g ); // benski> CUT: int n = skinEmbedder->getNumItems(_g);
+ if ( n > 0 )
+ w = WASABI_API_WNDMGR->skinwnd_enumByGuid( _g, n - 1 ); // benski> CUT: w = skinEmbedder->enumItem(_g, n-1);
+ }
+ else
+ {
+ int n = WASABI_API_WNDMGR->skinwnd_getNumByGroupId( s ); // benski> CUT: int n = skinEmbedder->getNumItems(s);
+ if ( n > 0 )
+ w = WASABI_API_WNDMGR->skinwnd_enumByGroupId( s, n - 1 ); // benski> CUT: w = skinEmbedder->enumItem(s, n-1);
+ }
+ if ( w )
+ {
+ GuiObject *o = w->getGuiObject();
+ if ( o )
+ WASABI_API_WNDMGR->skinwnd_destroy( o->guiobject_getRootWnd() );
+ }
+#endif
+ RETURN_SCRIPT_NULL;
+}
+
+scriptVar SystemObject::vcpu_isNamedWindowVisible( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar guidorgroup )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *s = GET_SCRIPT_STRING( guidorgroup );
+ GUID _g = nsGUID::fromCharW( s );
+ ifc_window *w = NULL;
+ if ( _g != INVALID_GUID )
+ {
+ int n = WASABI_API_WNDMGR->skinwnd_getNumByGuid( _g ); // benski> CUT: int n = skinEmbedder->getNumItems(_g);
+ if ( n > 0 )
+ w = WASABI_API_WNDMGR->skinwnd_enumByGuid( _g, n - 1 ); // benski> CUT: w = skinEmbedder->enumItem(_g, n-1);
+ }
+ else
+ {
+ int n = WASABI_API_WNDMGR->skinwnd_getNumByGroupId( s ); // benski> CUT: int n = skinEmbedder->getNumItems(s);
+ if ( n > 0 )
+ w = WASABI_API_WNDMGR->skinwnd_enumByGroupId( s, n - 1 ); // benski> CUT: w = skinEmbedder->enumItem(s, n-1);
+ }
+ if ( w )
+ {
+ return MAKE_SCRIPT_BOOLEAN( w->isVisible() );
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+#endif // if defined (WASABI_COMPILE_WNDMGR) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+#if defined(WASABI_COMPILE_MEDIACORE) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+scriptVar SystemObject::vcpu_getStatus( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getStatus( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getSongInfoText( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+
+#ifdef GET_SONG_INFO_TEXT
+ const wchar_t *c;
+ GET_SONG_INFO_TEXT( c );
+ WCSCPYN( staticStr, c, 4096 );
+#else
+ *staticStr = 0;
+#pragma CHAT("lone", "bas", "need to get the song info text, the same as would be in a text field with SONGINFO")
+#endif
+ return MAKE_SCRIPT_STRING( staticStr );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getSongInfoTextTranslated( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+
+#ifdef GET_SONG_INFO_TEXT_TRANSLATED
+ const wchar_t *c;
+ GET_SONG_INFO_TEXT_TRANSLATED( c );
+ WCSCPYN( staticStr, c, 4096 );
+#else
+ *staticStr = 0;
+#endif
+ return MAKE_SCRIPT_STRING( staticStr );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+#ifdef GEN_FF
+#include "../../../../Plugins/General/gen_ff/wa2frontend.h"
+#endif
+
+scriptVar SystemObject::vcpu_hasVideoSupport( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ return MAKE_SCRIPT_INT( wa2.hasVideoSupport() );
+#else
+#pragma CHAT("lone", "bas", "how can we ask if the currently playing file is video thru the core objects ?")
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_isVideo( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ return MAKE_SCRIPT_INT( wa2.isPlayingVideo() );
+#else
+#pragma CHAT("lone", "bas", "how can we ask if the currently playing file is video thru the core objects ?")
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_isVideoFullscreen( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ return MAKE_SCRIPT_INT( wa2.isPlayingVideoFullscreen() );
+#else
+#pragma CHAT("lone", "bas", "how can we ask if we are running fullscreen (either vis or video) ?")
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setVideoFullscreen( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ const bool vidfs = GET_SCRIPT_BOOLEAN( v );
+ if ( vidfs )
+ {
+ wa2.sendVidCmd( Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN );
+ }
+ else
+ {
+ wa2.sendVidCmd( Winamp2FrontEnd::WA2_VIDCMD_EXIT_FS );
+ }
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPlaylistIndex( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ return MAKE_SCRIPT_INT( wa2.getCurPlaylistEntry() );
+#else
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( CoreHandle().getCurPlaybackNumber() );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPlaylistLength( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ return MAKE_SCRIPT_INT( wa2.getPlaylistLength() );
+#else
+#ifdef WASABI_COMPILE_MEDIACORE
+ //BU CoreHandle is your friend
+ return MAKE_SCRIPT_INT( CoreHandle().getNumTracks() );
+#else
+ //FG not always, heh
+ RETURN_SCRIPT_ZERO;
+#endif
+#endif
+}
+
+scriptVar SystemObject::vcpu_getIdealVideoHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ int h = -1;
+ wa2.getIdealVideoSize( NULL, &h );
+ return MAKE_SCRIPT_INT( h );
+#else
+#pragma CHAT("lone", "bas", "how can we ask for the ideal video size thru the core objects ?")
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getIdealVideoWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef GEN_FF
+ int w = -1;
+ wa2.getIdealVideoSize( &w, NULL );
+ return MAKE_SCRIPT_INT( w );
+#else
+#pragma CHAT("lone", "bas", "how can we ask for the ideal video size thru the core objects ?")
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onStop( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT0( o );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onShowNotification( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT0( o );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onPlay( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT0( o );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onPause( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT0( o );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onResume( SCRIPT_FUNCTION_PARAMS, ScriptObject *o )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS0( o, systemController );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT0( o );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onTitleChange( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar title )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, title );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, title );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onTitle2Change( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar title )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, title );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, title );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onUrlChange( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar title )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, title );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, title );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onInfoChange( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar info )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, info );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, info );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onStatusMsg( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar info )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, info );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, info );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onEqBandChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar band, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS2( o, systemController, band, val );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT2( o, band, val );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onEqFreqChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, val );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, val );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onEqPreAmpChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, val );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, val );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onEqChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, val );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, val );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_onVolumeChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, val );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, val );
+#else
+ RETURN_SCRIPT_VOID
+#endif
+}
+
+scriptVar SystemObject::vcpu_onSeeked( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ PROCESS_HOOKS1( o, systemController, val );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT1( o, val );
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPlayItemString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ const wchar_t *cur = WASABI_API_MEDIACORE->core_getCurrent( 0 );
+ if ( cur == NULL ) cur = L"";
+ return MAKE_SCRIPT_STRING( cur );
+#else
+ return MAKE_SCRIPT_STRING( L"" );
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPlayItemLength( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getLength( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPlayItemDisplayTitle( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ WCSCPYN( staticStr, WASABI_API_MEDIACORE->core_getTitle( 0 ), 4096 );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_getPlayItemMetadataString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar name )
+{
+ SCRIPT_FUNCTION_INIT;
+#if defined(WASABI_COMPILE_MEDIACORE) & defined(WASABI_COMPILE_METADB)
+ const char *cur = WASABI_API_MEDIACORE->core_getCurrent( 0 );
+ if ( cur == NULL ) return MAKE_SCRIPT_STRING( "" );
+ if ( cur && WASABI_API_METADB->metadb_getMetaData( cur, GET_SCRIPT_STRING( name ), staticStr, ( sizeof( staticStr ) / sizeof( *staticStr ) ) ) <= 0 ) return MAKE_SCRIPT_STRING( "" );
+ return MAKE_SCRIPT_STRING( staticStr );
+#elif defined(WASABI_CUSTOM_MINIDB)
+ WASABI_CUSTOM_MINIDB( GET_SCRIPT_STRING( name ), staticStr, 4096 ); staticStr[ 4095 ] = 0;
+ return MAKE_SCRIPT_STRING( staticStr );
+#elif defined(WASABI_COMPILE_MEDIACORE)
+ STRNCPY( staticStr, WASABI_API_MEDIACORE->core_getCurrent( 0 ), 4095 ); staticStr[ 4095 ] = 0;
+ return MAKE_SCRIPT_STRING( staticStr );
+#endif
+}
+
+scriptVar SystemObject::vcpu_getMetadataString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar filename, scriptVar name )
+{
+ SCRIPT_FUNCTION_INIT;
+ wa2.getMetaData( GET_SCRIPT_STRING( filename ), GET_SCRIPT_STRING( name ), staticStr, 4096 );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_getExtFamily( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ext )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ const wchar_t *ps = GET_SCRIPT_STRING( ext );
+ staticStr[ 0 ] = '\0';
+ if ( ps != NULL )
+ {
+ const wchar_t *f = WASABI_API_MEDIACORE->core_getExtensionFamily( ps );
+ if ( f == NULL ) f = L"";
+ WCSCPYN( staticStr, f, 4096 );
+ }
+ return MAKE_SCRIPT_STRING( staticStr );
+#else
+ return MAKE_SCRIPT_STRING( L"" );
+#endif
+}
+
+scriptVar SystemObject::vcpu_getDecoderName( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ext )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ const wchar_t *ps = GET_SCRIPT_STRING( ext );
+ staticStr[ 0 ] = '\0';
+ if ( ps != NULL )
+ {
+ const wchar_t *f = WASABI_API_MEDIACORE->core_getDecoderName( ps );
+ if ( f == NULL ) f = L"";
+ WCSCPYN( staticStr, f, 4096 );
+ }
+ return MAKE_SCRIPT_STRING( staticStr );
+#else
+ return MAKE_SCRIPT_STRING( L"" );
+#endif
+}
+
+scriptVar SystemObject::vcpu_playFile( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar file )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+#ifdef GEN_FF
+ StringW _file = GET_SCRIPT_STRING( file );
+ const wchar_t *f = _file.getValue();
+ if ( f && *f )
+ {
+ if ( wcsstr( _file, L"://" ) )
+ {
+ wa2.playFile( _file );
+ }
+ else if ( f[ 1 ] != ':' && f[ 0 ] != '\\' && f[ 0 ] != '/' )
+ {
+ PathParserW pp( f );
+ if ( WCSCASEEQLSAFE( pp.enumString( 0 ), L"skins" )
+ && WCSCASEEQLSAFE( pp.enumString( 1 ), WASABI_API_SKIN->getSkinName() ) )
+ {
+ _file = L"";
+ for ( int i = 0; i < pp.getNumStrings() - 2; i++ )
+ {
+ if ( i > 0 ) _file += L"\\";
+ _file += pp.enumString( i + 2 );
+ }
+ }
+ _file = StringPathCombine( WASABI_API_SKIN->getSkinPath(), _file );
+ if ( !WACCESS( _file, 0 ) ) // avoid clearing playlist if file not found
+ wa2.playFile( _file );
+ }
+ }
+#else
+ svc_player *sp = SvcEnumByGuid<svc_player>();
+ if ( sp ) sp->openFile( GET_SCRIPT_STRING( file ) );
+ WASABI_API_SVC->service_release( sp );
+#endif
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_enqueueFile( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar file )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+#ifdef GEN_FF
+ StringW _file = GET_SCRIPT_STRING( file );
+ const wchar_t *f = _file.getValue();
+ if ( f && *f )
+ {
+ if ( wcsstr( _file, L"://" ) )
+ {
+ wa2.enqueueFile( _file );
+ }
+ else if ( f[ 1 ] != ':' && f[ 0 ] != '\\' && f[ 0 ] != '/' )
+ {
+ PathParserW pp( f );
+ if ( WCSCASEEQLSAFE( pp.enumString( 0 ), L"skins" )
+ && WCSCASEEQLSAFE( pp.enumString( 1 ), WASABI_API_SKIN->getSkinName() ) )
+ {
+ _file = L"";
+ for ( int i = 0; i < pp.getNumStrings() - 2; i++ )
+ {
+ if ( i > 0 ) _file += L"\\";
+ _file += pp.enumString( i + 2 );
+ }
+ }
+ _file = StringPathCombine( WASABI_API_SKIN->getSkinPath(), _file );
+ wa2.enqueueFile( _file );
+ }
+ }
+#else
+ svc_player *sp = SvcEnumByGuid<svc_player>();
+ if ( sp ) sp->openFile( GET_SCRIPT_STRING( file ) );
+ WASABI_API_SVC->service_release( sp );
+#endif
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_clearPlaylist( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ wa2.clearPlaylist();
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SystemObject::vcpu_getLeftVuMeter( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getLeftVuMeter( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getVisBand( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar chan, scriptVar band )
+{
+ {
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ unsigned char visdata[ 576 * 2 * 2 ] = { 0 };
+ int ret = WASABI_API_MEDIACORE->core_getVisData( 0, &visdata, sizeof( visdata ) );
+ if ( !ret ) MEMSET( visdata, 0, sizeof( visdata ) );
+ int b = MIN( MAX( 0, GET_SCRIPT_INT( band ) ), 74 );
+ int a = MIN( MAX( 0, GET_SCRIPT_INT( chan ) ), 1 );
+ return MAKE_SCRIPT_INT( MIN( 255, visdata[ 576 * a + b ] * 16 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+ }
+}
+
+scriptVar SystemObject::vcpu_getRightVuMeter( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getRightVuMeter( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getVolume( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getVolume( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setVolume( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_setVolume( 0, GET_SCRIPT_INT( v ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_play( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_userButton( 0, UserButton::PLAY );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_stop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_userButton( 0, UserButton::STOP );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_pause( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_userButton( 0, UserButton::PAUSE );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_next( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_userButton( 0, UserButton::NEXT );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_previous( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_userButton( 0, UserButton::PREV );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_eject( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+#ifdef GEN_FF
+ wa2.openFileDialog( WASABI_API_WND->main_getRootWnd()->gethWnd() );
+#else
+ svc_player *sp = SvcEnumByGuid<svc_player>();
+ sp->openFiles();
+ WASABI_API_SVC->service_release( sp );
+#endif
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_seekTo( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar to )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_setPosition( 0, GET_SCRIPT_INT( to ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setEqBand( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar band, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_setEqBand( 0, MAX( 0, MIN( 9, GET_SCRIPT_INT( band ) ) ), GET_SCRIPT_INT( val ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setEqPreAmp( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_setEqPreamp( 0, GET_SCRIPT_INT( v ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setEq( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_setEqStatus( 0, GET_SCRIPT_INT( v ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPosition( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getPosition( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getEqBand( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar band )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getEqBand( 0, MAX( 0, MIN( 9, GET_SCRIPT_INT( band ) ) ) ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getEqPreAmp( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getEqPreamp( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getEq( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getEqStatus( 0 ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+#endif // #if defined(WASABI_COMPILE_MEDIACORE) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+#if defined(WASABI_COMPILE_COMPONENTS) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+scriptVar SystemObject::vcpu_getWac( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar guid )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_COMPONENTS
+ WACObject *wo = SOM::getWACObject( GET_SCRIPT_STRING( guid ) );
+ return MAKE_SCRIPT_OBJECT( wo ? wo->getScriptObject() : NULL );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+#endif // if defined(WASABI_COMPILE_COMPONENTS) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+#if defined(WASABI_COMPILE_CONFIG) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+scriptVar SystemObject::vcpu_setPrivateString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar str )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ WCSNPRINTF( staticStr, 4096, L"%s_%s", GET_SCRIPT_STRING( section ), GET_SCRIPT_STRING( item ) );
+ WASABI_API_CONFIG->setStringPrivate( staticStr, GET_SCRIPT_STRING( str ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setPrivateInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ WCSNPRINTF( staticStr, 4096, L"%s_%s", GET_SCRIPT_STRING( section ), GET_SCRIPT_STRING( item ) );
+ WASABI_API_CONFIG->setIntPrivate( staticStr, GET_SCRIPT_INT( val ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPrivateString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar defstr )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ wchar_t t[ 4096 ] = { 0 };
+ StringCchPrintfW( t, 4096, L"%s_%s", GET_SCRIPT_STRING( section ), GET_SCRIPT_STRING( item ) );
+ WASABI_API_CONFIG->getStringPrivate( t, staticStr, 4095, GET_SCRIPT_STRING( defstr ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+#else
+ return MAKE_SCRIPT_STRING( L"" );
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPrivateInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar defval )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ wchar_t t[ 4096 ] = { 0 };
+ StringCchPrintfW( t, 4096, L"%s_%s", GET_SCRIPT_STRING( section ), GET_SCRIPT_STRING( item ) );
+ return MAKE_SCRIPT_INT( WASABI_API_CONFIG->getIntPrivate( t, GET_SCRIPT_INT( defval ) ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setPublicString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar str )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->setStringPrivate( GET_SCRIPT_STRING( item ), GET_SCRIPT_STRING( str ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setPublicInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar val )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->setIntPrivate( GET_SCRIPT_STRING( item ), GET_SCRIPT_INT( val ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPublicString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar defstr )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->getStringPrivate( GET_SCRIPT_STRING( item ), staticStr, 4095, GET_SCRIPT_STRING( defstr ) );
+ return MAKE_SCRIPT_STRING( staticStr );
+#else
+ return MAKE_SCRIPT_STRING( L"" );
+#endif
+}
+
+scriptVar SystemObject::vcpu_getPublicInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar defval )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_CONFIG
+ return MAKE_SCRIPT_INT( WASABI_API_CONFIG->getIntPrivate( GET_SCRIPT_STRING( item ), GET_SCRIPT_INT( defval ) ) );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+#endif // #if defined(WASABI_COMPILE_CONFIG) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+#if defined (WA3COMPATIBILITY) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+
+scriptVar SystemObject::vcpu_ddeSend( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar ddetarget, scriptVar cmd, scriptVar minInterval )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WA3COMPATIBILITY
+ DdeCom::sendCommand( GET_SCRIPT_STRING( ddetarget ), GET_SCRIPT_STRING( cmd ), GET_SCRIPT_INT( minInterval ) );
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_popMb( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WA3COMPATIBILITY
+ MainMiniBrowser::popMb();
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_getMainMB( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WA3COMPATIBILITY
+ return MAKE_SCRIPT_OBJECT( MainMiniBrowser::getScriptObject() );
+#else
+ RETURN_SCRIPT_NULL;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setMenuTransparency( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar a )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WA3COMPATIBILITY
+ WASABI_API_CONFIG->setIntPublic( "Popup alpha", GET_SCRIPT_INT( a ) );
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_windowMenu( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WA3COMPATIBILITY
+ Main::thingerContextMenu( NULL );
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_systemMenu( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WA3COMPATIBILITY
+ Main::appContextMenu( NULL, FALSE, FALSE );
+#endif
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SystemObject::vcpu_selectFile( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar extlist, scriptVar id, scriptVar prevfn )
+{
+ SCRIPT_FUNCTION_INIT;
+ SelectFile sf( WASABI_API_WND->main_getRootWnd() );
+ sf.setIdent( GET_SCRIPT_STRING( id ) );
+ StringW ff = GET_SCRIPT_STRING( prevfn );
+ if ( !ff.isempty() )
+ {
+ wchar_t *p = const_cast<wchar_t *>(Wasabi::Std::filename( ff ) );
+ if ( p != NULL ) *p = 0;
+ sf.setDefaultDir( ff );
+ }
+ StringW exts = GET_SCRIPT_STRING( extlist );
+ if ( exts.isempty() )
+ exts = L"All files(*.*)|*.*||";
+ exts.changeChar( '|', '\0' );
+ int r = sf.runSelector( L"files", FALSE, exts );
+ StringW t;
+ if ( !r || sf.getNumFiles() < 1 )
+ {
+ t = GET_SCRIPT_STRING( prevfn );
+ }
+ else
+ {
+ t = sf.enumFilename( 0 );
+ }
+ WCSCPYN( staticStr, t, 4096 );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+#endif
+
+const wchar_t *dldir;
+
+BOOL CALLBACK browseEnumProc( HWND hwnd, LPARAM lParam )
+{
+ wchar_t cl[ 32 ] = { 0 };
+ GetClassName( hwnd, cl, ARRAYSIZE( cl ) );
+ if ( !lstrcmpi( cl, WC_TREEVIEW ) )
+ {
+ PostMessage( hwnd, TVM_ENSUREVISIBLE, 0, (LPARAM)TreeView_GetSelection( hwnd ) );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int CALLBACK BrowseCallbackProcX( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
+{
+ switch ( uMsg )
+ {
+ case BFFM_INITIALIZED:
+ {
+ const wchar_t *wnd_title = (wchar_t *)lpData;
+ //if(wnd_title) wnd_title = _(wnd_title);
+ if ( WCSICMP( _( wnd_title ), L"" ) ) SetWindowTextW( hwnd, _( wnd_title ) );
+ SendMessageW( hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)dldir );
+
+ // this is not nice but it fixes the selection not working correctly on all OSes
+ EnumChildWindows( hwnd, browseEnumProc, 0 );
+ }
+ return 0;
+ }
+ return 0;
+}
+
+void Shell_Free( void *p )
+{
+ IMalloc *m;
+ SHGetMalloc( &m );
+ m->Free( p );
+}
+
+scriptVar SystemObject::vcpu_selectFolder( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar title, scriptVar info, scriptVar defPath )
+{
+ SCRIPT_FUNCTION_INIT;
+
+ dldir = defPath.data.sdata;
+
+ BROWSEINFOW bi = { 0 };
+ bi.hwndOwner = WASABI_API_WND->main_getRootWnd()->gethWnd();
+ bi.lpszTitle = _( info.data.sdata ); // Info Text
+ bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
+ bi.lpfn = BrowseCallbackProcX;
+ bi.lParam = (LPARAM)title.data.sdata; // Window Title
+
+ ITEMIDLIST *idlist = SHBrowseForFolderW( &bi );
+ if ( idlist )
+ {
+ SHGetPathFromIDListW( idlist, staticStr );
+ Shell_Free( idlist );
+
+ return MAKE_SCRIPT_STRING( staticStr );
+ }
+
+ return MAKE_SCRIPT_STRING( L"" );
+}
+
+#ifdef WASABI_COMPILE_MEDIACORE
+
+int SystemObject::corecb_onVolumeChange( int newvol )
+{
+ vcpu_onVolumeChanged( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT( newvol ) );
+ return 0;
+}
+
+int SystemObject::corecb_onEQStatusChange( int newval )
+{
+ vcpu_onEqChanged( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT( newval ) );
+ return 0;
+}
+
+int SystemObject::corecb_onEQPreampChange( int newval )
+{
+ vcpu_onEqPreAmpChanged( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT( newval ) );
+ return 0;
+}
+
+int SystemObject::corecb_onEQBandChange( int band, int newval )
+{
+ vcpu_onEqBandChanged( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT( band ), MAKE_SCRIPT_INT( newval ) );
+ return 0;
+}
+
+int SystemObject::corecb_onEQFreqChange( int newval )
+{
+ vcpu_onEqFreqChanged( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT( newval ) );
+ return 0;
+}
+
+int SystemObject::corecb_onStarted()
+{
+ vcpu_onPlay( SCRIPT_CALL, getScriptObject() );
+ return 0;
+}
+
+int SystemObject::corecb_onStopped()
+{
+ vcpu_onStop( SCRIPT_CALL, getScriptObject() );
+ return 0;
+}
+
+int SystemObject::corecb_onPaused()
+{
+ vcpu_onPause( SCRIPT_CALL, getScriptObject() );
+ return 0;
+}
+
+int SystemObject::corecb_onUnpaused()
+{
+ vcpu_onResume( SCRIPT_CALL, getScriptObject() );
+ return 0;
+}
+
+int SystemObject::corecb_onSeeked( int newpos )
+{
+ vcpu_onSeeked( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT( newpos ) );
+ return 0;
+}
+
+int SystemObject::corecb_onTitleChange( const wchar_t *title )
+{
+ vcpu_onTitleChange( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( title ) );
+ return 0;
+}
+
+int SystemObject::corecb_onTitle2Change( const wchar_t *title )
+{
+ vcpu_onTitle2Change( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( title ) );
+ return 0;
+}
+
+int SystemObject::corecb_onUrlChange( const wchar_t *url )
+{
+ vcpu_onUrlChange( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( url ) );
+ return 0;
+}
+
+int SystemObject::corecb_onInfoChange( const wchar_t *info )
+{
+ vcpu_onInfoChange( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( info ) );
+ return 0;
+}
+
+int SystemObject::corecb_onStatusMsg( const wchar_t *info )
+{
+ vcpu_onStatusMsg( SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING( info ) );
+ return 0;
+}
+#endif
+
+scriptVar SystemObject::vcpu_getRating( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ return MAKE_SCRIPT_INT( WASABI_API_MEDIACORE->core_getRating() );
+#else
+ RETURN_SCRIPT_ZERO;
+#endif
+}
+
+scriptVar SystemObject::vcpu_setRating( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v )
+{
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_setRating( GET_SCRIPT_INT( v ) );
+ return MAKE_SCRIPT_VOID();
+#else
+ RETURN_SCRIPT_VOID;
+#endif
+}
+
+scriptVar SystemObject::vcpu_getDownloadPath( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ wa2.getDownloadPath( staticStr );
+ return MAKE_SCRIPT_STRING( staticStr );
+}
+
+scriptVar SystemObject::vcpu_setDownloadPath( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar new_path )
+{
+ SCRIPT_FUNCTION_INIT;
+ wa2.setDownloadPath( new_path.data.sdata );
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SystemObject::vcpu_downloadURL( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url, scriptVar filename, scriptVar title )
+{
+ SCRIPT_FUNCTION_INIT;
+ wa2.DownloadFile( AutoChar( GET_SCRIPT_STRING( url ) ) );
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SystemObject::vcpu_downloadMedia( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url, scriptVar filepath, scriptVar storeInMl, scriptVar notifyDownloadsList )
+{
+ SCRIPT_FUNCTION_INIT;
+ wa2.DownloadFile( AutoChar( GET_SCRIPT_STRING( url ) ), GET_SCRIPT_STRING( filepath ), GET_SCRIPT_BOOLEAN( storeInMl ), GET_SCRIPT_BOOLEAN( notifyDownloadsList ) );
+ return MAKE_SCRIPT_VOID();
+}
+
+scriptVar SystemObject::vcpu_onDownloadFinished( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar success, scriptVar filename )
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS3( o, systemController, url, success, filename );
+ SCRIPT_FUNCTION_CHECKABORTEVENT_SYS( o );
+ SCRIPT_EXEC_EVENT3( o, url, success, filename );
+}
+
+scriptVar SystemObject::vcpu_getAlbumArt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar filename )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( !!wa2.GetAlbumArt( GET_SCRIPT_STRING( filename ) ) );
+}
+
+scriptVar SystemObject::vcpu_isWinampPro( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( !!wa2.IsWinampPro() );
+}
+
+static PtrList<StringW> embed_guids;
+
+static int embed_guid_enumProc( embedWindowState *ws, struct embedEnumStruct *param )
+{
+ if ( ws->flags & EMBED_FLAGS_GUID )
+ {
+ wchar_t guid[ 39 ] = { 0 };
+ nsGUID::toCharW( GET_EMBED_GUID( ws ), guid );
+ embed_guids.addItem( new StringW( guid ) );
+ }
+ return 0;
+}
+scriptVar SystemObject::vcpu_enumEmbedGUID( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _index )
+{
+ SCRIPT_FUNCTION_INIT;
+ int index = GET_SCRIPT_INT( _index );
+ if ( index == 0 ) // make the table
+ {
+ embed_guids.deleteAll();
+ embedEnumStruct param;
+ param.user_data = 0;
+ param.enumProc = embed_guid_enumProc;
+ SendMessageW( wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&param, IPC_EMBED_ENUM );
+ }
+ if ( index >= 0 && index < embed_guids.getNumItems() )
+ return MAKE_SCRIPT_STRING( embed_guids[ index ]->getValue() );
+
+ return MAKE_SCRIPT_STRING( L"" );
+}
+
+scriptVar SystemObject::vcpu_getWinampVersion( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+/** This would have been the code to return a double.
+ double r = atof(wa2.getVersion());
+ return MAKE_SCRIPT_DOUBLE(r);
+*/
+ return MAKE_SCRIPT_STRING( applicationApi->main_getVersionNumString() );
+}
+
+scriptVar SystemObject::vcpu_getBuildNumber( SCRIPT_FUNCTION_PARAMS, ScriptObject *object )
+{
+ SCRIPT_FUNCTION_INIT;
+ return MAKE_SCRIPT_INT( applicationApi->main_getBuildNumber() );
+}
+
+scriptVar SystemObject::vcpu_getFileSize( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _file )
+{
+ SCRIPT_FUNCTION_INIT;
+ const wchar_t *file = GET_SCRIPT_STRING( _file );
+ if ( file == NULL ) // make the table
+ {
+ return MAKE_SCRIPT_INT( 0 );
+ }
+ /*fileApi->fileOpen(file, 0);
+ int size = fileApi->fileGetFileSize();
+ fileApi->fileClose(;*/
+ OSFILETYPE in = WFOPEN( file, WF_READONLY_BINARY );
+ if ( in == OPEN_FAILED ) return MAKE_SCRIPT_INT( 0 );
+ int size = (int)FGETSIZE( in );
+ FCLOSE( in );
+ return MAKE_SCRIPT_INT( size );
+}
+
+wchar_t SystemObject::staticStr[ 4096 ] = { 0 };
+wchar_t SystemObject::translateStr[ 4096 ] = { 0 };
+PtrList < ScriptObject > SystemObject::scriptobjects;
+
+// END VCPU
+
+// ---------------------------------------------------------------
+// -- END SCRIPT -------------------------------------------------
+// --------------------------------------------------------------- \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/systemobj.h b/Src/Wasabi/api/script/objects/systemobj.h
new file mode 100644
index 00000000..4b388692
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/systemobj.h
@@ -0,0 +1,397 @@
+#ifndef _SYSTEMOBJ_H
+#define _SYSTEMOBJ_H
+
+#include <api/script/script.h>
+#include <api/script/objects/rootobj.h>
+#include <api/script/objects/timer.h>
+#ifdef WASABI_COMPILE_MEDIACORE
+#include <api/syscb/callbacks/corecbi.h>
+#endif
+#include <api/syscb/callbacks/browsercbi.h>
+#include <bfc/string/bfcstring.h>
+
+#ifdef WASABI_COMPILE_WNDMGR
+class WindowHolder;
+#endif
+
+// {D6F50F64-93FA-49b7-93F1-BA66EFAE3E98}
+static const GUID systemObjectGuid =
+{ 0xd6f50f64, 0x93fa, 0x49b7, { 0x93, 0xf1, 0xba, 0x66, 0xef, 0xae, 0x3e, 0x98 } };
+
+class SystemScriptObjectController : public ScriptObjectControllerI {
+ public:
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return rootScriptObjectController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual int getInstantiable();
+ virtual int getReferenceable();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern SystemScriptObjectController *systemController;
+
+class Group;
+
+#ifdef WASABI_COMPILE_WNDMGR
+class Layout;
+class Container;
+class WindowHolder;
+#endif
+
+#ifdef WASABI_COMPILE_COMPONENTS
+class WACObject;
+#endif
+
+#define SYSTEMOBJECT_SCRIPTPARENT RootObjectInstance
+
+#ifdef WASABI_COMPILE_MEDIACORE
+#define SYSTEMOBJECT_PARENT SYSTEMOBJECT_SCRIPTPARENT, public CoreCallbackI
+#else
+#define SYSTEMOBJECT_PARENT SYSTEMOBJECT_SCRIPTPARENT
+#endif
+
+class SystemObject : public SYSTEMOBJECT_PARENT, public BrowserCallbackI {
+ public:
+ SystemObject();
+ virtual ~SystemObject();
+ void setScriptId(int id);
+ int getScriptId();
+ void setTimer(int delay);
+ void setParam(const wchar_t *p);
+ void setParentGroup(Group *g);
+ Group *getParentGroup();
+ const wchar_t *getParam();
+ virtual void onLoad();
+ virtual void onUnload();
+ virtual int isLoaded() { return loaded; }
+#ifdef WASABI_COMPILE_WNDMGR
+ WindowHolder *getSuitableWindowHolderByGuid(GUID g);
+ int onGetCancelComponent(GUID g, int i);
+ static void onCreateLayout(Layout *l);
+ static void onShowLayout(Layout *l);
+ static void onHideLayout(Layout *l);
+ static int getCurAppRect(RECT *r);
+#endif
+ static void onQuit();
+ static void onKeyDown(const wchar_t *s);
+ static void onKeyUp(const wchar_t *s);
+ static int onAccelerator(const wchar_t *action, const wchar_t *section, const wchar_t *key);
+ TList < int > *getTypesList();
+ void setIsOldFormat(int is);
+ int isOldFormat();
+ static int isAppActive();
+
+ static void onViewPortChanged(int width, int height);
+ static int onShowNotification();
+ static void onDownloadFinished(const wchar_t * url, boolean success, const wchar_t * filename);
+
+ static PtrList < ScriptObject > *getAllScriptObjects() { return &scriptobjects; }
+ void setSkinPartId(int _skinpartid);
+ int getSkinPartId();
+
+ void addInstantiatedObject(ScriptObject *obj);
+ void removeInstantiatedObject(ScriptObject *obj);
+ void garbageCollect();
+
+ static int isObjectValid(ScriptObject *o);
+ static void addScriptObject(ScriptObject *o);
+ static void removeScriptObject(ScriptObject *o);
+
+#ifdef WASABI_COMPILE_SKIN
+ void onSetXuiParam(const wchar_t *param, const wchar_t *value);
+#endif
+
+ const wchar_t *getFilename() { return filename; }
+ void setFilename(const wchar_t *file) { filename = file; }
+ static void navigateUrl(const wchar_t *url);
+ static void navigateUrlBrowser(const wchar_t *url);
+
+ // called by vcpu
+ static scriptVar vcpu_getVersion( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onScriptLoaded( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onScriptUnloading( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onQuit( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+#ifdef WASABI_COMPILE_SKIN
+ static scriptVar vcpu_onSetXuiParam( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar param, scriptVar value);
+ static scriptVar vcpu_getSkinName( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_switchSkin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar skinname);
+ static scriptVar vcpu_isLoadingSkin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_lockUI( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_unlockUI( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+#endif
+ static scriptVar vcpu_isObjectValid( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar o);
+ static scriptVar vcpu_getTimeOfDay( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_navigateUrl( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url);
+ static scriptVar vcpu_navigateUrlBrowser( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url);
+ static scriptVar vcpu_isKeyDown( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar vk_code);
+ static scriptVar vcpu_setClipboard( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar text);
+ static scriptVar vcpu_chr( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar n);
+ static scriptVar vcpu_onAccelerator( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar action, scriptVar section, scriptVar key);
+ static scriptVar vcpu_triggerAction( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar guiobj, scriptVar actionstr, scriptVar paramstr);
+ static scriptVar vcpu_getParam( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+#ifdef WASABI_COMPILE_SKIN
+ static scriptVar vcpu_getScriptGroup( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_newGroup( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar groupname);
+#endif
+ static scriptVar vcpu_getMousePosX( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getMousePosY( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_isMinimized( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_isDesktopAlphaAvailable( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_isTransparencyAvailable( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_minimizeApplication( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_restoreApplication( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_activateApplication( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_integerToString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar i);
+ static scriptVar vcpu_stringToInteger( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar s);
+ static scriptVar vcpu_floatToString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar f, scriptVar digits);
+ static scriptVar vcpu_stringToFloat( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar s);
+ static scriptVar vcpu_integerToTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_integerToLongTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_dateToTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_dateToLongTime( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_formatDate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_formatLongDate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateYear( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateMonth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateDay( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateDow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateDoy( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateHour( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateMin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateSec( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDateDst( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _i);
+ static scriptVar vcpu_getDate( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_strmid( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str, scriptVar start, scriptVar len);
+ static scriptVar vcpu_strleft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str, scriptVar len);
+ static scriptVar vcpu_strright( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str, scriptVar _len);
+ static scriptVar vcpu_strsearch( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str, scriptVar substr);
+ static scriptVar vcpu_strlen( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str);
+ static scriptVar vcpu_strupper( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_strlower( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_urlencode( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_urldecode( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_removepath( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_getpath( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_getextension( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _str);
+ static scriptVar vcpu_gettoken( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar tok, scriptVar sep, scriptVar num);
+ static scriptVar vcpu_sin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_cos( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_tan( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_asin( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_acos( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_atan( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_atan2( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar y, scriptVar x);
+ static scriptVar vcpu_pow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_sqr( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar _d);
+ static scriptVar vcpu_sqrt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar d);
+ static scriptVar vcpu_random( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar m);
+ static scriptVar vcpu_integer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_frac( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_log( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_log10( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_getMonitorLeft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getMonitorTop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getMonitorWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getMonitorHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getMonitorLeftFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getMonitorTopFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getMonitorLeftGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getMonitorTopGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getMonitorWidthFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getMonitorHeightFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getMonitorWidthGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getMonitorHeightGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_onViewPortChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar width, scriptVar height);
+ static scriptVar vcpu_getViewportWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getViewportHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getViewportWidthGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getViewportHeightGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getViewportLeft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getViewportTop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getViewportLeftGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getViewportTopGO( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar obj);
+ static scriptVar vcpu_getViewportWidthFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getViewportHeightFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getViewportLeftFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getViewportTopFP( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar x, scriptVar y);
+ static scriptVar vcpu_getTickCount( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_onKeyDown( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar vcpu_onKeyUp( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar vcpu_debugString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str, scriptVar severity);
+ static scriptVar vcpu_messageBox( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar msg, scriptVar title, scriptVar flags, scriptVar nam);
+ static scriptVar vcpu_getAtom( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar atomname);
+ static scriptVar vcpu_setAtom( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar atomname, scriptVar obj);
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ static scriptVar vcpu_invokeDebugger( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+#endif
+#if defined (WASABI_COMPILE_WNDMGR) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ static scriptVar vcpu_onCreateLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar vcpu_onShowLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar vcpu_onHideLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar vcpu_getContainer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar contname);
+ static scriptVar vcpu_newDynamicContainer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar contname);
+ static scriptVar vcpu_newGroupAsLayout( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar groupname);
+ static scriptVar vcpu_getNumContainers( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_enumContainer( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar n);
+ static scriptVar vcpu_onLookForComponent( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar guid);
+ static scriptVar vcpu_onGetCancelComponent( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar guid, scriptVar i);
+ static scriptVar vcpu_getCurAppLeft( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getCurAppTop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getCurAppWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getCurAppHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_isAppActive( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_showWindow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar wndguidorgroup, scriptVar prefcontainer, scriptVar transient);
+ static scriptVar vcpu_hideWindow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar container);
+ static scriptVar vcpu_hideNamedWindow( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar wndguidorgroup);
+ static scriptVar vcpu_isNamedWindowVisible( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar wndguidorgroup);
+#endif
+#if defined(WASABI_COMPILE_MEDIACORE) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ static scriptVar vcpu_getStatus( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_onStop( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onPlay( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onPause( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onResume( SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar vcpu_onTitleChange( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar title);
+ static scriptVar vcpu_onTitle2Change( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar title);
+ static scriptVar vcpu_onUrlChange( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar title);
+ static scriptVar vcpu_onInfoChange( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar info);
+ static scriptVar vcpu_onStatusMsg( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar info);
+ static scriptVar vcpu_onEqBandChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar band, scriptVar val);
+ static scriptVar vcpu_onEqFreqChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static scriptVar vcpu_onEqPreAmpChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static scriptVar vcpu_onEqChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static scriptVar vcpu_onVolumeChanged( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static scriptVar vcpu_onSeeked( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static scriptVar vcpu_getPlayItemDisplayTitle( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getPlayItemString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getPlayItemLength( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getPlayItemMetadataString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar name);
+ static scriptVar vcpu_getMetadataString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar filename, scriptVar name);
+ static scriptVar vcpu_getExtFamily( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ext);
+ static scriptVar vcpu_getDecoderName( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ext);
+ static scriptVar vcpu_playFile( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar file);
+ static scriptVar vcpu_enqueueFile( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar file);
+ static scriptVar vcpu_clearPlaylist( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getLeftVuMeter( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getRightVuMeter( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getVisBand( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar chan, scriptVar band);
+ static scriptVar vcpu_getVolume( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_setVolume( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_play( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_stop( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_pause( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_next( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_previous( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_eject( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_seekTo( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar to);
+ static scriptVar vcpu_setEqBand( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar band, scriptVar val);
+ static scriptVar vcpu_setEqPreAmp( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_setEq( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+ static scriptVar vcpu_getPosition( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getEqBand( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar band);
+ static scriptVar vcpu_getEqPreAmp( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getEq( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_hasVideoSupport( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_isVideo( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_isVideoFullscreen( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_setVideoFullscreen( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar val);
+ static scriptVar vcpu_getIdealVideoWidth( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getIdealVideoHeight( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getPlaylistLength( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getPlaylistIndex( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_onShowNotification( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getSongInfoText( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getSongInfoTextTranslated( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+#endif
+#if defined(WASABI_COMPILE_COMPONENTS) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ static scriptVar vcpu_getWac( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar guid);
+#endif
+#if defined (WASABI_COMPILE_CONFIG) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ static scriptVar vcpu_setPrivateString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar str);
+ static scriptVar vcpu_setPrivateInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar val);
+ static scriptVar vcpu_getPrivateString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar defstr);
+ static scriptVar vcpu_getPrivateInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar section, scriptVar item, scriptVar defval);
+ static scriptVar vcpu_setPublicString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar str);
+ static scriptVar vcpu_setPublicInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar val);
+ static scriptVar vcpu_getPublicString( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar defstr);
+ static scriptVar vcpu_getPublicInt( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar item, scriptVar defval);
+#endif
+#if defined (WA3COMPATIBILITY) || defined(WASABI_SCRIPT_SYSTEMOBJECT_WA3COMPATIBLE)
+ static scriptVar vcpu_ddeSend( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar ddetarget, scriptVar cmd, scriptVar minInterval);
+ static scriptVar vcpu_popMb( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getMainMB( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_setMenuTransparency( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar a);
+ static scriptVar vcpu_windowMenu( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_systemMenu( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+#endif
+ static scriptVar vcpu_selectFile( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar extlist, scriptVar id, scriptVar prevfn);
+ static scriptVar vcpu_selectFolder( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar title, scriptVar info, scriptVar defpath);
+
+ static scriptVar vcpu_getRating( SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_setRating ( SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar v);
+
+#ifdef WASABI_COMPILE_MEDIACORE
+ // core callbacks
+ virtual int corecb_onVolumeChange(int newvol);
+ virtual int corecb_onEQStatusChange(int newval);
+ virtual int corecb_onEQPreampChange(int newval);
+ virtual int corecb_onEQBandChange(int band, int newval);
+ virtual int corecb_onEQFreqChange(int newval);
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+ virtual int corecb_onPaused();
+ virtual int corecb_onUnpaused();
+ virtual int corecb_onSeeked(int newpos);
+ virtual int corecb_onTitleChange(const wchar_t *title);
+ virtual int corecb_onTitle2Change(const wchar_t *title);
+ virtual int corecb_onUrlChange(const wchar_t *url);
+ virtual int corecb_onInfoChange(const wchar_t *info);
+ virtual int corecb_onStatusMsg(const wchar_t *info);
+#endif
+
+ virtual void browsercb_onOpenURL(wchar_t *url, bool *override);
+ static scriptVar vcpu_onOpenURL( SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+
+ static scriptVar vcpu_downloadURL(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url,scriptVar filename,scriptVar title);
+ static scriptVar vcpu_downloadMedia(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url, scriptVar filepath, scriptVar storeInMl, scriptVar notifyDownloadsList);
+ static scriptVar vcpu_onDownloadFinished(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar url,scriptVar success, scriptVar filename);
+ static scriptVar vcpu_getDownloadPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_setDownloadPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar new_path);
+ static scriptVar vcpu_getAlbumArt(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar filename);
+ static scriptVar vcpu_isWinampPro(SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_enumEmbedGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar index);
+ static scriptVar vcpu_getWinampVersion(SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getBuildNumber(SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+ static scriptVar vcpu_getFileSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar file);
+ static scriptVar vcpu_translate(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar str);
+ static scriptVar vcpu_getString(SCRIPT_FUNCTION_PARAMS, ScriptObject *object, scriptVar table, scriptVar id);
+ static scriptVar vcpu_getLanguageId(SCRIPT_FUNCTION_PARAMS, ScriptObject *object);
+
+ private:
+ int scriptVCPUId;
+ StringW param;
+ static wchar_t staticStr[4096];
+ static wchar_t translateStr[4096];
+ TList < int > typeslist;
+ int isoldformat;
+ Group * parentGroup;
+ int skinpartid;
+ static PtrList < ScriptObject > scriptobjects;
+ PtrList < ScriptObject > instantiated;
+ int loaded;
+ int started_up;
+ StringW filename;
+
+ public:
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/objects/timer.cpp b/Src/Wasabi/api/script/objects/timer.cpp
new file mode 100644
index 00000000..36449940
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/timer.cpp
@@ -0,0 +1,165 @@
+#include <precomp.h>
+#include "timer.h"
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/rootobject.h>
+//#include <api/wac/main.h>//CUT!!
+//#include <api/timer/genwnd.h> //CUT!!
+
+STimer::STimer() {
+ getScriptObject()->vcpu_setInterface(timerGuid, (void *)static_cast<STimer *>(this));
+ getScriptObject()->vcpu_setClassName(L"Timer");
+ getScriptObject()->vcpu_setController(timerController);
+ delay = 1000;
+ started = 0;
+}
+
+STimer::~STimer() {
+}
+
+void STimer::setDelay(int d) {
+ delay = d;
+ if (started)
+ timerclient_setTimer(STIMER_ID, getDelay());
+}
+
+int STimer::getDelay(void) {
+ return delay;
+}
+
+void STimer::start(void) {
+ if (started) { stop(); }
+ timerclient_setTimer(STIMER_ID, getDelay());
+ started = 1;
+}
+
+void STimer::stop(void) {
+ if (!started) return;
+ timerclient_killTimer(STIMER_ID);
+ started = 0;
+}
+
+void STimer::onTimer(void)
+{
+ if (started)
+ {
+ script_onTimer(SCRIPT_CALL, getScriptObject());
+ }
+}
+
+void STimer::timerclient_timerCallback(int id)
+{
+ if (id == STIMER_ID)
+ onTimer();
+}
+
+int STimer::isRunning() {
+ return started;
+}
+
+TimerScriptController _timerController;
+TimerScriptController *timerController=&_timerController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct TimerScriptController::exportedFunction[] = {
+ {L"setDelay", 1, (void*)STimer::script_setDelay },
+ {L"getDelay", 0, (void*)STimer::script_getDelay },
+ {L"start", 0, (void*)STimer::script_start },
+ {L"stop", 0, (void*)STimer::script_stop },
+ {L"onTimer", 0, (void*)STimer::script_onTimer },
+ {L"isRunning",0, (void*)STimer::script_isRunning },
+ {L"getSkipped",0, (void*)STimer::script_getSkipped },
+};
+// --------------------------------------------------------
+
+const wchar_t *TimerScriptController::getClassName() {
+ return L"Timer";
+}
+
+const wchar_t *TimerScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *TimerScriptController::getAncestorController() {
+ return rootScriptObjectController;
+}
+
+ScriptObject *TimerScriptController::instantiate() {
+ STimer *s = new STimer;
+ ASSERT(s != NULL);
+ return s->getScriptObject();
+}
+
+void TimerScriptController::destroy(ScriptObject *o) {
+ STimer *s = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ ASSERT(s != NULL);
+ delete s;
+}
+
+void *TimerScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for timer yet
+}
+
+void TimerScriptController::deencapsulate(void *o) {
+}
+
+int TimerScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *TimerScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID TimerScriptController::getClassGuid() {
+ return timerGuid;
+}
+
+scriptVar STimer::script_onTimer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, timerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar STimer::script_setDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar d) {
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&d));
+ STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ if (t) t->setDelay(SOM::makeInt(&d));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar STimer::script_getDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ if (t) return MAKE_SCRIPT_INT(t->getDelay());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar STimer::script_start(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ if (t) t->start();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar STimer::script_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ if (t) t->stop();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar STimer::script_isRunning(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ if (t) return MAKE_SCRIPT_BOOLEAN(t->isRunning());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar STimer::script_getSkipped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
+ if (t) return MAKE_SCRIPT_INT(t->timerclient_getSkipped());
+ RETURN_SCRIPT_ZERO;
+}
diff --git a/Src/Wasabi/api/script/objects/timer.h b/Src/Wasabi/api/script/objects/timer.h
new file mode 100644
index 00000000..5506a20a
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/timer.h
@@ -0,0 +1,77 @@
+//PORTABLE
+#ifndef _STIMER_H
+#define _STIMER_H
+
+#include <api/wnd/basewnd.h>
+#include <api/script/objects/rootobject.h>
+#include <api/script/objects/rootobj.h>
+
+#include <api/timer/timerclient.h>
+
+#define STIMER_PARENT RootObjectInstance
+
+// {5D0C5BB6-7DE1-4b1f-A70F-8D1659941941}
+static const GUID timerGuid =
+{ 0x5d0c5bb6, 0x7de1, 0x4b1f, { 0xa7, 0xf, 0x8d, 0x16, 0x59, 0x94, 0x19, 0x41 } };
+
+class TimerScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern TimerScriptController *timerController;
+
+
+#ifndef _NOSTUDIO
+
+#define STIMER_ID 2481
+
+class STimer : public STIMER_PARENT, public TimerClientDI {
+public:
+ STimer();
+ virtual ~STimer();
+
+ void start(void);
+ void stop(void);
+ int getDelay(void);
+ void setDelay(int d);
+ void onTimer(void);
+ int isRunning();
+
+ void timerclient_timerCallback(int id);
+
+private:
+ int delay;
+ int started;
+
+#else
+class STimer : public STIMER_SCRIPTPARENT {
+#endif
+
+public:
+
+ static scriptVar script_onTimer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar d);
+ static scriptVar script_getDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_start(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_isRunning(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getSkipped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/objects/wacobj.cpp b/Src/Wasabi/api/script/objects/wacobj.cpp
new file mode 100644
index 00000000..6abba5bc
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/wacobj.cpp
@@ -0,0 +1,161 @@
+#include <precomp.h>
+#include <bfc/wasabi_std.h>
+#include <bfc/nsguid.h>
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/wacobj.h>
+
+#ifdef _WASABIRUNTIME
+#include <api/api.h>
+#include <api/wac/compon.h>
+#endif
+
+WacScriptController _wacController;
+WacScriptController *wacController = &_wacController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct WacScriptController::exportedFunction[] = {
+ {L"getGUID", 1, (void*)WACObject::script_getGUID },
+ {L"getName", 1, (void*)WACObject::script_getName },
+ {L"onNotify", 3, (void*)WACObject::script_vcpu_onNotify },
+
+// DEPRECATED! DO NOTHING
+ {L"sendCommand", 4, (void*)WACObject::script_vcpu_dummy4},
+ {L"show", 0, (void*)WACObject::script_vcpu_dummy0},
+ {L"hide", 0, (void*)WACObject::script_vcpu_dummy0},
+ {L"isVisible", 0, (void*)WACObject::script_vcpu_dummy0},
+ {L"onShow", 0, (void*)WACObject::script_vcpu_dummy0},
+ {L"onHide", 0, (void*)WACObject::script_vcpu_dummy0},
+ {L"setStatusBar", 1, (void*)WACObject::script_vcpu_dummy1},
+ {L"getStatusBar", 0, (void*)WACObject::script_vcpu_dummy0},
+};
+// --------------------------------------------------------
+
+const wchar_t *WacScriptController::getClassName() {
+ return L"Wac";
+}
+
+const wchar_t *WacScriptController::getAncestorClassName() {
+ return L"Object";
+}
+
+ScriptObjectController *WacScriptController::getAncestorController() { return rootScriptObjectController; }
+
+int WacScriptController::getInstantiable() {
+ return 0;
+}
+
+int WacScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *WacScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID WacScriptController::getClassGuid() {
+ return wacGuid;
+}
+
+ScriptObject *WacScriptController::instantiate() {
+ return NULL;
+}
+
+void WacScriptController::destroy(ScriptObject *o) {
+}
+
+void *WacScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for wacobject yet
+}
+
+void WacScriptController::deencapsulate(void *o ) {
+}
+
+WACObject::WACObject() {
+ getScriptObject()->vcpu_setInterface(wacGuid, (void *)static_cast<WACObject *>(this));
+ getScriptObject()->vcpu_setClassName(L"Wac");
+ getScriptObject()->vcpu_setController(wacController);
+ wacobjs.addItem(this);
+}
+
+WACObject::~WACObject() {
+ wacobjs.delItem(this);
+}
+
+void WACObject::setGUID(GUID g) {
+ myGUID = g;
+}
+
+GUID WACObject::getGUID(void) {
+ return myGUID;
+}
+
+int WACObject::onScriptNotify(const wchar_t *s, int i1, int i2)
+{
+ scriptVar _i1 = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_i1, i1);
+ scriptVar _i2 = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_i2, i2);
+ scriptVar _str = SOM::makeVar(SCRIPT_STRING);
+ SOM::assign(&_str, (wchar_t *)s);
+ script_vcpu_onNotify(SCRIPT_CALL, getScriptObject(), _str, _i1, _i2);
+ return 1;
+}
+
+int WACObject::notifyScripts(WaComponent *comp, const wchar_t *s, int i1, int i2)
+{
+ for (int i=0;i<wacobjs.getNumItems();i++)
+ {
+ GUID g = comp->getGUID();
+ if (!MEMCMP(&g, &wacobjs.enumItem(i)->myGUID, sizeof(GUID)))
+ return wacobjs.enumItem(i)->onScriptNotify(s, i1, i2);
+ }
+ return 0;
+}
+
+scriptVar WACObject::script_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ static wchar_t guid[nsGUID::GUID_STRLEN+1];
+ WACObject *wo = static_cast<WACObject *>(o->vcpu_getInterface(wacGuid));
+ *guid=0;
+ if (wo)
+ nsGUID::toCharW(wo->myGUID, guid);
+ return MAKE_SCRIPT_STRING(guid);
+}
+
+scriptVar WACObject::script_getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+#ifdef WASABI_COMPILE_COMPONENTS
+ WACObject *wo = static_cast<WACObject *>(o->vcpu_getInterface(wacGuid));
+ if (wo) return MAKE_SCRIPT_STRING(WASABI_API_COMPONENT->getComponentName(wo->myGUID));
+#endif
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar WACObject::script_vcpu_onNotify(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str, scriptVar i1, scriptVar i2) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS3(o, wacController, str, i1, i2);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, str, i1, i2);
+}
+
+scriptVar WACObject::script_vcpu_dummy4(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a, scriptVar b, scriptVar c, scriptVar d) {
+ SCRIPT_FUNCTION_INIT;
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar WACObject::script_vcpu_dummy1(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT;
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar WACObject::script_vcpu_dummy0(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ RETURN_SCRIPT_ZERO;
+}
+
+
+PtrList<WACObject> WACObject::wacobjs;
+
diff --git a/Src/Wasabi/api/script/objects/wacobj.h b/Src/Wasabi/api/script/objects/wacobj.h
new file mode 100644
index 00000000..44cf2d3e
--- /dev/null
+++ b/Src/Wasabi/api/script/objects/wacobj.h
@@ -0,0 +1,75 @@
+#ifndef _WACOBJ_H
+#define _WACOBJ_H
+
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/script/objects/guiobj.h>
+#include <bfc/ptrlist.h>
+#include <api/wac/wac.h>
+
+// {00C074A0-FEA2-49a0-BE8D-FABBDB161640}
+static const GUID wacGuid =
+{ 0xc074a0, 0xfea2, 0x49a0, { 0xbe, 0x8d, 0xfa, 0xbb, 0xdb, 0x16, 0x16, 0x40 } };
+
+#define WACOBJECT_SCRIPTPARENT RootObjectInstance
+
+class WacScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual int getInstantiable();
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern WacScriptController *wacController;
+
+#include <api/wnd/virtualwnd.h>
+
+class WACObject : public WACOBJECT_SCRIPTPARENT {
+
+public:
+ WACObject();
+ virtual ~WACObject();
+
+ void setGUID(GUID g);
+ GUID getGUID(void);
+
+ int onScriptNotify(const wchar_t *s, int i1, int i2);
+
+ // VCPU
+ static scriptVar script_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onNotify(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str, scriptVar i1, scriptVar i2);
+
+ static scriptVar script_vcpu_dummy4(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a, scriptVar b, scriptVar c, scriptVar d);
+ static scriptVar script_vcpu_dummy1(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_dummy0(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ // End VCPU
+
+ static int notifyScripts(WaComponent *comp, const wchar_t *s, int i1, int i2);
+
+ GUID myGUID;
+
+private:
+
+ static PtrList<WACObject> wacobjs;
+
+public:
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/script/objecttable.cpp b/Src/Wasabi/api/script/objecttable.cpp
new file mode 100644
index 00000000..0f1f6149
--- /dev/null
+++ b/Src/Wasabi/api/script/objecttable.cpp
@@ -0,0 +1,748 @@
+#include <precomp.h>
+#include <api/script/objecttable.h>
+
+#ifndef _NOSTUDIO
+#include <api/service/svcs/svc_scriptobji.h>
+#include <api/script/scriptobj.h>
+#include <api/script/vcputypes.h>
+#include <api/script/objects/systemobj.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/rootobject.h>
+#include <api/script/objects/guiobj.h>
+#include <api/skin/widgets/group.h>
+
+#ifdef WASABI_WIDGETS_LAYER
+#include <api/skin/widgets/layer.h>
+#endif
+
+#ifdef WASABI_WIDGETS_ANIMLAYER
+#include <api/skin/widgets/animlayer.h>
+#endif
+
+#include <AlbumArt.h>
+
+#ifdef WASABI_WIDGETS_BUTTON
+#include <api/skin/widgets/button.h>
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+#ifdef WASABI_WIDGETS_WNDHOLDER
+#include <api/wndmgr/container.h>
+#endif
+#include <api/wndmgr/layout.h>
+#endif // wndmgr
+
+#ifdef WASABI_WIDGETS_EDIT
+#include <api/skin/widgets/edit.h>
+#endif
+
+#ifdef WASABI_WIDGETS_SLIDER
+#include <api/skin/widgets/pslider.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MEDIAVIS
+#include <api/skin/widgets/sa.h>
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+
+#ifdef WASABI_WIDGETS_MEDIAEQCURVE
+#include <api/skin/widgets/seqvis.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MEDIASTATUS
+#include <api/skin/widgets/sstatus.h>
+#endif
+
+#endif // mediacore
+
+#ifdef WASABI_WIDGETS_TEXT
+#include <api/skin/widgets/text.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TGBUTTON
+#include <api/skin/widgets/tgbutton.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TITLEBAR
+#include <api/skin/widgets/title.h>
+#endif
+
+#ifdef WASABI_SCRIPTOBJECTS_POPUP
+#include <api/script/objects/spopup.h>
+#endif
+
+#ifdef WASABI_SCRIPTOBJECTS_MAP
+#include <api/script/objects/smap.h>
+#endif
+
+#ifdef WASABI_WIDGETS_GROUPLIST
+#include <api/skin/widgets/grouplist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_COMPBUCK
+#include <api/skin/widgets/compbuck2.h>
+#endif
+
+#ifdef WASABI_SCRIPTOBJECTS_WAC
+#include <api/script/objects/wacobj.h>
+#endif
+
+#ifdef WASABI_SCRIPTOBJECTS_LIST
+#include <api/script/objects/slist.h>
+#endif
+
+
+#ifdef WASABI_SCRIPTOBJECTS_BITLIST
+#include <api/script/objects/sbitlist.h>
+#endif
+
+#ifdef WASABI_SCRIPTOBJECTS_REGION
+#include <api/script/objects/sregion.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MOUSEREDIR
+#include <api/skin/widgets/mouseredir.h>
+#endif
+
+#ifdef WASABI_WIDGETS_BROWSER
+#include <api/skin/widgets/mb/xuibrowser.h>
+#endif
+
+#ifdef WASABI_WIDGETS_QUERYLIST
+#include <api/skin/widgets/db/xuiquerylist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_FILTERLIST
+#include <api/skin/widgets/db/xuifilterlist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_WNDHOLDER
+#include <api/skin/widgets/xuiwndholder.h>
+#endif
+
+#ifdef WASABI_WIDGETS_DROPDOWNLIST
+#include <api/skin/widgets/dropdownlist.h>
+#endif
+
+#ifdef WASABI_SCRIPTOBJECTS_EMBEDDEDXUI
+#include <api/wnd/wndclass/embeddedxui.h>
+#endif
+
+#ifdef WASABI_WIDGETS_LAYOUTSTATUS
+#include <api/skin/widgets/xuistatus.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TABSHEET
+#include <api/skin/widgets/xuitabsheet.h>
+#endif
+
+#ifdef WASABI_WIDGETS_LIST
+#include <api/skin/widgets/xuilist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TREE
+#include <api/skin/widgets/xuitree.h>
+#endif
+
+#ifdef WASABI_WIDGETS_CHECKBOX
+#include <api/skin/widgets/xuicheckbox.h>
+#endif
+
+#include <api/skin/widgets/xuiframe.h>
+
+//Martin> This fixes Wa5 Menu Xml Object is not instanciable via maki - silly bug
+#include <api/skin/widgets/xuimenuso.h>
+
+//fileIO
+#include <api/script/objects/sfile.h>
+#include <api/script/objects/sxmldoc.h>
+
+//ColorMgr
+#include <api/script/objects/scolormgr.h>
+#include <api/script/objects/scolor.h>
+#include <api/script/objects/sgammaset.h>
+#include <api/script/objects/sgammagroup.h>
+
+#include <api/script/objects/sapplication.h>
+#include <api/script/objects/sprivate.h>
+
+#include <api/script/vcpu.h>
+
+#include <bfc/ptrlist.h>
+
+#include <api/service/svc_enum.h>
+#include <api/service/service.h>
+#include <api/service/services.h>
+
+void ObjectTable::start() {
+ registerClass(rootScriptObjectController);
+ registerClass(systemController);
+#ifdef WASABI_COMPILE_SKIN
+ registerClass(guiController);
+ registerClass(groupController);
+#ifdef WASABI_SCRIPTOBJECTS_EMBEDDEDXUI
+ registerClass(embeddedXuiController);
+#endif
+#ifdef WASABI_WIDGETS_LAYER
+ registerClass(layerController);
+#endif
+#ifdef WASABI_WIDGETS_ANIMLAYER
+ registerClass(animlayerController);
+#endif
+ registerClass(albumartController);
+#ifdef WASABI_WIDGETS_BUTTON
+ registerClass(buttonController);
+#endif
+#ifdef WASABI_WIDGETS_TGBUTTON
+ registerClass(tgbuttonController);
+#endif
+#ifdef WASABI_WIDGETS_COMPBUCK
+ registerClass(cbucketController);
+#endif
+#ifdef WASABI_COMPILE_WNDMGR
+ registerClass(containerController);
+ registerClass(layoutController);
+#endif
+#ifdef WASABI_WIDGETS_EDIT
+ registerClass(editController);
+#endif
+#ifdef WASABI_WIDGETS_SLIDER
+ registerClass(sliderController);
+#endif
+#ifdef WASABI_WIDGETS_MEDIAVIS
+ registerClass(visController);
+#endif
+#ifdef WASABI_COMPILE_MEDIACORE
+#ifdef WASABI_WIDGETS_MEDIAEQCURVE
+ registerClass(eqvisController);
+#endif
+#ifdef WASABI_WIDGETS_MEDIASTATUS
+ registerClass(statusController);
+#endif
+#endif // mediacore
+#ifdef WASABI_WIDGETS_TEXT
+ registerClass(textController);
+#endif
+ registerClass(frameController);
+#ifdef WASABI_WIDGETS_TITLEBAR
+ registerClass(titleController);
+#endif
+#ifdef WASABI_SCRIPTOBJECTS_POPUP
+ registerClass(popupController);
+#endif
+#ifdef WASABI_SCRIPTOBJECTS_WAC
+ registerClass(wacController);
+#endif
+#endif
+#ifdef WASABI_SCRIPTOBJECTS_LIST
+ registerClass(listController);
+#endif
+#ifdef WASABI_SCRIPTOBJECTS_BITLIST
+ registerClass(bitlistController);
+#endif
+#ifdef WASABI_SCRIPTOBJECTS_REGION
+ registerClass(regionController);
+#endif
+#ifdef WASABI_SCRIPTOBJECTS_MAP
+ registerClass(mapController);
+#endif
+#ifdef WASABI_COMPILE_SKIN
+#ifdef WASABI_WIDGETS_GROUPLIST
+ registerClass(grouplistController);
+#endif
+#ifdef WASABI_WIDGETS_MOUSEREDIR
+ registerClass(mouseredirController);
+#endif
+#ifdef WASABI_COMPILE_CONFIG
+ registerClass(cfgGroupController);
+#endif
+#ifdef WASABI_WIDGETS_BROWSER
+ registerClass(browserController);
+#endif
+#ifdef WASABI_WIDGETS_QUERYLIST
+ registerClass(queryListController);
+#endif
+#ifdef WASABI_WIDGETS_FILTERLIST
+ registerClass(filterListController);
+#endif
+#ifdef WASABI_COMPILE_WNDMGR
+#ifdef WASABI_WIDGETS_WNDHOLDER
+ registerClass(windowHolderController);
+#endif
+#endif // wndmgr
+#ifdef WASABI_WIDGETS_DROPDOWNLIST
+ registerClass(dropDownListController);
+#endif
+#ifdef WASABI_WIDGETS_LAYOUTSTATUS
+ registerClass(layoutStatusController);
+#endif
+#ifdef WASABI_WIDGETS_TABSHEET
+ registerClass(tabsheetController);
+#endif
+#ifdef WASABI_WIDGETS_LIST
+ registerClass(guiListController);
+#endif
+#ifdef WASABI_WIDGETS_TREE
+ registerClass(guiTreeController);
+ registerClass(treeItemController);
+#endif
+#ifdef WASABI_WIDGETS_CHECKBOX
+ registerClass(checkBoxController);
+#endif
+#endif
+
+ registerClass(fileController);
+ registerClass(xmlDocController);
+ registerClass(applicationController);
+ registerClass(SPrivateController);
+ registerClass(xuiMenuScriptController);
+ registerClass(colorMgrController);
+ registerClass(colorController);
+ registerClass(gammasetController);
+ registerClass(gammagroupController);
+}
+
+void ObjectTable::shutdown() {
+ for (int i=0;i<classes.getNumItems();i++) {
+ class_entry *e = classes[i];
+ unlinkClass(e);
+ FREE((char *)e->classname);
+ }
+ classes.deleteAll();
+ VCPU::resetDlf();
+ externalloaded = 0;
+}
+
+// unload external classes
+void ObjectTable::unloadExternalClasses() {
+ for (int i=0;i<classes.getNumItems();i++) {
+ if (classes.enumItem(i)->external) {
+ class_entry *ce = classes.enumItem(i);
+ unlinkClass(ce);
+ classes.removeByPos(i);
+ i--;
+ }
+ }
+ classidx = classes.getNumItems();
+ externalloaded = 0;
+}
+
+void ObjectTable::unlinkClass(class_entry *e) {
+ if (e->sf != NULL && !WASABI_API_SVC->service_isvalid(WaSvc::SCRIPTOBJECT, e->sf)) return;
+ ScriptObjectController *c = e->controller;
+ const function_descriptor_struct *ds = c->getExportedFunctions();
+ for (int j=0;j<c->getNumFunctions();j++) {
+ VCPU::DLF_reset(ds[j].physical_ptr, ds[j].nparams);
+ }
+}
+
+void ObjectTable::loadExternalClasses() {
+ if (externalloaded) return;
+ externalloaded = 1;
+ ExternalScriptObjectEnum soe ;
+ svc_scriptObject *obj = soe.getFirst();
+ while (obj) {
+ obj->onRegisterClasses(rootScriptObjectController);
+ int g=0;
+ while (1) {
+ ScriptObjectController *o = obj->getController(g);
+ if (!o) break;
+ //DebugString(StringPrintf("Registering script class %s\n", o->getClassName()));
+ ObjectTable::registerClass(o, soe.getLastFactory());
+ g++;
+ }
+ WASABI_API_SVC->service_release(obj);
+ obj = soe.getNext();
+ }
+}
+
+
+// returns classid. ancestorclass = 0 = Object
+int ObjectTable::registerClass(ScriptObjectController *c, waServiceFactory *sf) {
+ ASSERT(c != NULL);
+
+ c->onRegisterClass(rootScriptObjectController);
+
+ const wchar_t *classname = c->getClassName();
+ const wchar_t *ancestorclassname = c->getAncestorClassName();
+ GUID g = c->getClassGuid();
+
+ if (getClassFromName(classname) > -1) {
+ ASSERTPR(0, StringPrintf("duplicate script class name %S", classname));
+#ifdef _WIN32
+ ExitProcess(0);
+#else
+ exit(0);
+#endif
+ }
+ if (getClassFromGuid(g) > -1) {
+ ASSERTPR(0, "duplicate script class guid");
+#ifdef _WIN32
+ ExitProcess(0);
+#else
+ exit(0);
+#endif
+ }
+
+ int ancestorclassid = -1;
+ if (ancestorclassname != NULL)
+ ancestorclassid = getClassFromName(ancestorclassname);
+
+ class_entry * en = new class_entry;
+ en->classid = CLASS_ID_BASE + classidx++;
+ c->setClassId(en->classid);
+ c->setAncestorClassId(ancestorclassid);
+ en->classname = WCSDUP(classname);
+ en->controller = c;
+ en->classGuid = g;
+ en->ancestorclassid = ancestorclassid;
+ en->instantiable = c->getInstantiable();
+ en->referenceable = c->getReferenceable();
+ en->external = sf != NULL;
+ en->sf = sf;
+ classes.addItem(en);
+ dlfAddClassRef(c, NULL); // FG> fucko
+ return classes.getNumItems()-1;
+}
+
+int ObjectTable::addrefDLF(VCPUdlfEntry *dlf, int id) {
+
+ int classid = dlf->basetype;
+
+ while (classid) {
+
+ class_entry *e = getClassEntry(classid);
+ if (!e) return 0;
+ function_descriptor_struct *s = (function_descriptor_struct *)e->controller->getExportedFunctions();
+
+ for (int i=0;i<e->controller->getNumFunctions();i++, s++) {
+ if (!WCSICMP(s->function_name, dlf->functionName)) {
+ int xid = VCPU::getDLFFromPointer(s->physical_ptr, s->nparams);
+ if (xid != -1) {
+ dlf->DLFid = xid;
+ dlf->ptr = s->physical_ptr;
+ dlf->nparams = s->nparams;
+ VCPU::DLF_addref(s->physical_ptr, s->nparams);
+ return 0;
+ }
+ dlf->DLFid = id;
+ dlf->ptr = s->physical_ptr;
+ dlf->nparams = s->nparams;
+ VCPU::setupDLFFunction(s->physical_ptr, s->nparams, id, dlf);
+ VCPU::DLF_addref(s->physical_ptr, s->nparams);
+ return 1;
+ }
+ }
+
+ classid = e->controller->getAncestorClassId();
+ }
+ return 0;
+}
+
+void ObjectTable::delrefDLF(VCPUdlfEntry *dlf) {
+ int classid = dlf->basetype;
+
+ while (classid) {
+
+ class_entry *e = getClassEntry(classid);
+ if (!e) return;
+ function_descriptor_struct *s = (function_descriptor_struct *)e->controller->getExportedFunctions();
+
+ for (int i=0;i<e->controller->getNumFunctions();i++, s++) {
+ if (!WCSICMP(s->function_name, dlf->functionName)) {
+ VCPU::DLF_remref(s->physical_ptr, s->nparams);
+ return;
+ }
+ }
+ classid = e->controller->getAncestorClassId();
+ }
+}
+
+void ObjectTable::resetDLF(VCPUdlfEntry *dlf) {
+ int classid = dlf->basetype;
+
+ while (classid) {
+
+ class_entry *e = getClassEntry(classid);
+ if (!e) return;
+ function_descriptor_struct *s = (function_descriptor_struct *)e->controller->getExportedFunctions();
+
+ for (int i=0;i<e->controller->getNumFunctions();i++, s++) {
+ if (!WCSICMP(s->function_name, dlf->functionName)) {
+ VCPU::DLF_reset(s->physical_ptr, s->nparams);
+ return;
+ }
+ }
+ classid = e->controller->getAncestorClassId();
+ }
+}
+
+int ObjectTable::getClassFromName(const wchar_t *classname) {
+ for (int i=0;i<classes.getNumItems();i++) {
+ if (classes[i] && !WCSICMP(classname, classes[i]->classname)) {
+ return classes.enumItem(i)->classid;
+ }
+ }
+ return -1;
+}
+
+int ObjectTable::getClassFromGuid(GUID g) {
+ GUID t;
+ for (int i=0;i<classes.getNumItems();i++) {
+ t = classes.enumItem(i)->classGuid;
+ if (g == t)
+ return classes.enumItem(i)->classid;
+ }
+ return -1;
+}
+
+const wchar_t *ObjectTable::getClassName(int classid) {
+ class_entry *e =getClassEntry(classid);
+ if (!e) return NULL;
+ return e->classname;
+}
+
+int ObjectTable::isExternal(int classid) {
+ for (int i=0;i<classes.getNumItems();i++)
+ if (classes.enumItem(i)->classid == classid)
+ return 1;
+ return 0;
+}
+
+int ObjectTable::getNumGuids() {
+ return classes.getNumItems();
+}
+
+GUID ObjectTable::enumGuid(int i) {
+ return classes.enumItem(i)->classGuid;
+}
+
+const wchar_t *ObjectTable::enumClassName(int n) {
+ return classes.enumItem(n)->classname;
+}
+
+int ObjectTable::getClassEntryIdx(int classid) {
+ for (int i=0;i<classes.getNumItems();i++)
+ if (classes[i]->classid == classid)
+ return i;
+ return -1;
+}
+
+int ObjectTable::isDescendant(int class1, int classid) {
+
+ if (classid < CLASS_ID_BASE) return 0;
+ if (class1 < CLASS_ID_BASE) return 0;
+
+ class_entry *e = getClassEntry(classid);
+ //CUT: class_entry *_e = getClassEntry(class1);
+
+ while (e) {
+ if (class1 == classid) return 1;
+ e = getClassEntry(e->ancestorclassid);
+ if (e) classid = e->classid;
+ }
+ return 0;
+}
+
+int ObjectTable::isClassInstantiable(int classid) {
+ class_entry *e =getClassEntry(classid);
+ if (!e) return 0;
+ return e->instantiable;
+}
+
+int ObjectTable::isClassReferenceable(int classid) {
+ class_entry *e =getClassEntry(classid);
+ if (!e) return 0;
+ return e->referenceable;
+}
+
+ScriptObject *ObjectTable::instantiate(int classid) {
+ class_entry *e = getClassEntry(classid);
+ if (!e) return NULL;
+ ScriptObject *o = e->controller->instantiate();
+ return o;
+}
+
+void *ObjectTable::encapsulate(int classid, ScriptObject *o) {
+ class_entry *e = getClassEntry(classid);
+ if (!e) return NULL;
+ void *itf = e->controller->encapsulate(o);
+ if (itf)
+ o->vcpu_setInterface(e->classGuid, itf);
+ return itf;
+}
+
+void ObjectTable::destroy(ScriptObject *o) {
+ if (!o) return;
+ class_entry *e = getClassEntry(getClassFromName(o->vcpu_getClassName()));
+ if (!e) return;
+ e->controller->destroy(o);
+}
+
+void ObjectTable::deencapsulate(int classid, void *o) {
+ class_entry *e = getClassEntry(classid);
+ if (!e) return;
+ e->controller->deencapsulate(o);
+}
+
+const wchar_t *ObjectTable::getFunction(int dlfid, int *n, ScriptObjectController **p)
+{
+ VCPUdlfEntry *e = VCPU::getGlobalDlfEntry(dlfid);
+ if (p) *p = getClassEntry(e->basetype)->controller;
+ if (n) *n = e->nparams;
+ return e->functionName;
+}
+
+scriptVar ObjectTable::callFunction(ScriptObject *obj, int dlfid, scriptVar **params) {
+ VCPUdlfEntry *e = VCPU::getGlobalDlfEntry(dlfid);
+ VCPU::push(MAKE_SCRIPT_OBJECT(obj));
+ for (int i=e->nparams-1;i>=0;i--)
+ VCPU::push(*params[i]);
+ return VCPU::callDLF(e, -1);
+}
+
+int ObjectTable::dlfAddRef(ScriptObjectController *o, const wchar_t *function_name, void *host)
+{
+ ScriptObjectController *_o = o;
+ while (_o) {
+ const function_descriptor_struct *s = _o->getExportedFunctions();
+ for (int i=0;i<_o->getNumFunctions();i++) {
+ if (!WCSICMP(function_name, s[i].function_name)) {
+ return dlfAddRef(_o, i, host);
+ }
+ }
+ // function not found, see if ancestor has it
+ _o = _o->getAncestorController();
+ }
+ ASSERTALWAYS(StringPrintf("Function %s not found in %s class object hierarchy", function_name, o->getClassName()));
+ return -1;
+}
+
+int ObjectTable::dlfAddRef(ScriptObjectController *o, int i, void *host) {
+ const function_descriptor_struct *s = o->getExportedFunctions();
+ int id = VCPU::getDLFFromPointer(s[i].physical_ptr, s[i].nparams);
+ if (id < 0) { // not yet set
+ // allocate new vcpudlfentry and insert it in vcpu
+ id = VCPU::newDlf();
+ VCPUdlfEntry e;
+ e.basetype = o->getClassId();
+ e.DLFid = id;
+// DebugString(" s = %08X\n", s);
+// DebugString(" s[i] = %08X\n", s[i]);
+ ASSERT(s != NULL);
+ e.functionName = const_cast<wchar_t *>(s[i].function_name);
+// DebugString(" %s\n", e.functionName);
+ e.nparams = s[i].nparams;
+ e.ptr = s[i].physical_ptr;
+ e.scriptId = -1;
+ VCPU::setupDLFFunction(e.ptr, e.nparams, id, &e);
+ }
+ VCPU::DLF_addref(s[i].physical_ptr, s[i].nparams);
+ if (host != NULL) {
+ hostrefstruct *r = new hostrefstruct;
+ r->host = host;
+ r->nargs = s[i].nparams;
+ r->ptr = s[i].physical_ptr;
+ hostrefs.addItem(r);
+ }
+ return id;
+}
+
+void ObjectTable::dlfAddClassRef(ScriptObjectController *o, void *host) {
+// while (o) {
+ //CUT: const function_descriptor_struct *s = o->getExportedFunctions();
+ for (int i=0;i<o->getNumFunctions();i++) {
+ dlfAddRef(o, i, host);
+ }
+// o = o->getAncestorController();
+// }
+}
+
+
+void ObjectTable::dlfRemRef(void *host) {
+ for (int i=0;i<hostrefs.getNumItems();i++) {
+ hostrefstruct *r = hostrefs.enumItem(i);
+ if (r->host == host) {
+ //VCPU::DLF_remref(r->ptr, r->nargs); // TODO: re-enable after fixup
+ delete r;
+ hostrefs.removeByPos(i);
+ i--;
+ }
+ }
+}
+
+int ObjectTable::checkScript(SystemObject *o) {
+ TList<int> *l = o->getTypesList();
+ if (!l) return 0;
+ for (int i=0;i<l->getNumItems();i++) {
+ if (l->enumItem(i) == -1) {
+//#ifdef WASABI_COMPILE_WNDMGR
+// WASABI_API_WNDMGR->messageBox("Error while loading a script, a component is missing", "Oops", 0, "", NULL);
+//#else
+// MessageBox(NULL, "Error while loading a script, a component is missing", "Oops", 0);
+//#endif
+// return 0;
+ } else {
+
+ }
+ }
+ return 1;
+}
+
+ScriptObjectController *ObjectTable::getController(GUID g) {
+ int i = getClassFromGuid(g);
+ if (i == -1) return NULL;
+ class_entry *e = getClassEntry(i);
+ if (e)
+ return e->controller;
+ return NULL;
+}
+
+class_entry *ObjectTable::getClassEntry(int classid) {
+ for (int i=0;i<classes.getNumItems();i++)
+ if (classes[i]->classid == classid)
+ return classes[i];
+ return NULL;
+}
+
+#ifdef _NOSTUDIO
+
+int ObjectTable::validateMember(int classid, char *member, ControlBlock *parms, int *ret) {
+ ControlBlock *p = parms;
+ int r=0;
+ for (int i=0;i<classes.getNumItems();i++)
+ if (classes.enumItem(i)->classid == classid) {
+ const function_descriptor_struct *s = classes.enumItem(i)->controller->getExportedFunctions();
+ for (int j=0;j<classes.enumItem(i)->controller->getNumFunctions();j++) {
+ if (STRCASEEQL(s->function_name, member)) {
+ if (s->nparams == 0 && parms)
+ wrongParametersNumber(member, s->nparams);
+ for (int k=0;k<s->nparams&&!r;k++) {
+ int b = s->param[k];
+ if (p == NULL) {
+ wrongParametersNumber(member, s->nparams);
+ }
+ if (!::isDescendant(p, b)) {
+ wrongParameterType(k, member, (char *)getClassName(p->getBaseClass()), (char *)getClassName(classid));
+ }
+ p = p->getNext();
+ }
+ *ret = tempExternalToInternal(s->return_type);
+ return 1;
+ }
+ s++;
+ }
+ }
+ return 0;
+}
+
+#endif
+
+//-----
+
+PtrList < class_entry > ObjectTable::classes;
+PtrList < hostrefstruct > ObjectTable::hostrefs;
+int ObjectTable::classidx = 0;
+int ObjectTable::externalloaded = 0;
+#endif
diff --git a/Src/Wasabi/api/script/objecttable.h b/Src/Wasabi/api/script/objecttable.h
new file mode 100644
index 00000000..d0ab4c38
--- /dev/null
+++ b/Src/Wasabi/api/script/objecttable.h
@@ -0,0 +1,144 @@
+#ifndef __OBJECTTABLE
+#define __OBJECTTABLE
+
+#ifdef __cplusplus
+
+#include <wasabicfg.h>
+
+#include <bfc/ptrlist.h>
+class ScriptObjectController;
+
+#ifdef _NOSTUDIO
+//CUT #include "../../scriptcompiler/compiler.h"
+//CUT #include "../../scriptcompiler/ctrlblock.h"
+#endif
+
+#endif
+
+#include <api/script/vcputypes.h>
+
+#define CLASS_ID_BASE 0x100
+
+
+#define MAKE_NEW_OBJECT(class, objclass) \
+ case class: \
+ s = new objclass; \
+ objclass::instantiate((objclass *)s); \
+ break;
+
+// For type names table
+typedef struct {
+ wchar_t *name;
+ int type;
+ int instantiable;
+ int referenceable;
+} typenames;
+
+// This is the table that link type names as they are
+// recognized in scripts to actual basic types.
+
+// Non instantiable means you can't do v = new <type>
+// Non referenceable means you can't do <type> v;
+// Not a ref means content is not a reference to an object but rather the actual
+// content itself
+// * special case for strings which is a ref to a char *, but not an object
+#define DEFINE_TYPES \
+typenames types[] = { \
+ {L"", SCRIPT_VOID, 0, 0}, /* Non instantiable, non referenceable */ \
+ {L"Event", SCRIPT_EVENT, 0, 0}, /* Non instantiable, non referenceable */ \
+ {L"Int", SCRIPT_INT, 0, 1}, /* Not a ref */ \
+ {L"Float", SCRIPT_FLOAT, 0, 1}, /* Not a ref */ \
+ {L"Double", SCRIPT_DOUBLE, 0, 1}, /* Not a ref */ \
+ {L"Boolean", SCRIPT_BOOLEAN, 0, 1}, /* Not a ref */ \
+ {L"String", SCRIPT_STRING, 0, 1}, /* Not a ref (* special case) */ \
+ {L"Any", SCRIPT_ANY, 0, 1}, /* Non instantiable, non referenceable */ \
+}; \
+int ntypes = sizeof(types)/sizeof(typenames);
+
+extern typenames types[];
+extern int ntypes;
+
+#define SVC_CLASS_BASE 1024
+
+#ifdef __cplusplus
+
+class class_entry {
+public:
+ const wchar_t *classname;
+ int classid;
+ int ancestorclassid;
+ ScriptObjectController *controller;
+ GUID classGuid;
+ int instantiable;
+ int referenceable;
+ int external;
+ waServiceFactory *sf;
+};
+
+typedef struct {
+ void *ptr;
+ int nargs;
+ void *host;
+} hostrefstruct;
+
+class SystemObject;
+
+class ObjectTable {
+
+ public :
+
+ static void start(); // initialize tables, internal objects...
+ static void shutdown(); // free tables
+ static void unloadExternalClasses(); // unload external classes
+ static void loadExternalClasses(); // reload external classes
+
+ static int registerClass(ScriptObjectController *c, waServiceFactory *sf = NULL); // returns classid. ancestorclass = 0 = Object
+
+// static void instantiate(ScriptObject *o, int classid);
+ static int addrefDLF(VCPUdlfEntry *dlf, int id);
+ static void delrefDLF(VCPUdlfEntry *dlf);
+ static void resetDLF(VCPUdlfEntry *dlf);
+
+ static int getClassFromName(const wchar_t *classname);
+ static int getClassFromGuid(GUID g);
+ static const wchar_t *getClassName(int classid);
+ static int isExternal(int classid);
+ static int getNumGuids();
+ static GUID enumGuid(int i);
+ static const wchar_t *enumClassName(int n);
+ static int getClassEntryIdx(int classid);
+ static int isDescendant(int class1, int classid);
+ static int isClassInstantiable(int classid);
+ static int isClassReferenceable(int classid);
+ static ScriptObject *instantiate(int classid);
+ static void *encapsulate(int classid, ScriptObject *o);
+ static void destroy(ScriptObject *o);
+ static void deencapsulate(int classid, void *o);
+ static const wchar_t *getFunction(int dlfid, int *n, ScriptObjectController **p);
+ static scriptVar callFunction(ScriptObject *obj, int dlfid, scriptVar **params);
+ static int dlfAddRef(ScriptObjectController *o, const wchar_t *function_name, void *host);
+ static int dlfAddRef(ScriptObjectController *o, int i, void *host);
+ static void dlfAddClassRef(ScriptObjectController *o, void *host);
+ static void dlfRemRef(void *host);
+ static int checkScript(SystemObject *o);
+ static ScriptObjectController *getController(GUID g);
+ static class_entry *getClassEntry(int classid);
+ static void unlinkClass(class_entry *e);
+
+#ifdef _NOSTUDIO
+ static int validateMember(int classid, wchar_t *member, ControlBlock *parms, int *ret);
+#endif
+
+ private:
+
+ static PtrList < class_entry > classes;
+ static PtrList < hostrefstruct > hostrefs;
+ static int classidx;
+ static int externalloaded;
+};
+
+#endif
+
+#endif
+
+
diff --git a/Src/Wasabi/api/script/opcodes.h b/Src/Wasabi/api/script/opcodes.h
new file mode 100644
index 00000000..bedaf3be
--- /dev/null
+++ b/Src/Wasabi/api/script/opcodes.h
@@ -0,0 +1,64 @@
+#ifndef __OPCODES_H
+#define __OPCODES_H
+
+
+#define OPCODE_NOP 0x00
+
+#define OPCODE_PUSH 0x01
+#define OPCODE_POPI 0x02
+#define OPCODE_POP 0x03
+
+#define OPCODE_CMPEQ 0x08
+#define OPCODE_CMPNE 0x09
+#define OPCODE_CMPA 0x0A
+#define OPCODE_CMPAE 0x0B
+#define OPCODE_CMPB 0x0C
+#define OPCODE_CMPBE 0x0D
+
+#define OPCODE_JIZ 0x10
+#define OPCODE_JNZ 0x11
+#define OPCODE_JMP 0x12
+
+#define OPCODE_CALLM 0x18
+#define OPCODE_CALLC 0x19
+
+#define OPCODE_RET 0x20
+#define OPCODE_RETF 0x21
+
+#define OPCODE_CMPLT 0x28
+
+#define OPCODE_SET 0x30
+
+#define OPCODE_INCS 0x38
+#define OPCODE_DECS 0x39
+#define OPCODE_INCP 0x3A
+#define OPCODE_DECP 0x3B
+
+#define OPCODE_ADD 0x40
+#define OPCODE_SUB 0x41
+#define OPCODE_MUL 0x42
+#define OPCODE_DIV 0x43
+#define OPCODE_MOD 0x44
+
+#define OPCODE_AND 0x48
+#define OPCODE_OR 0x49
+#define OPCODE_NOT 0x4A
+#define OPCODE_BNOT 0x4B
+#define OPCODE_NEG 0x4C
+#define OPCODE_XOR 0x4D
+
+#define OPCODE_LAND 0x50
+#define OPCODE_LOR 0x51
+
+#define OPCODE_SHL 0x58
+#define OPCODE_SHR 0x59
+
+#define OPCODE_NEW 0x60
+#define OPCODE_DELETE 0x61
+
+#define OPCODE_UMV 0x68
+#define OPCODE_UMC 0x69
+
+#define OPCODE_CALLM2 0x70
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/script.cpp b/Src/Wasabi/api/script/script.cpp
new file mode 100644
index 00000000..4d0df190
--- /dev/null
+++ b/Src/Wasabi/api/script/script.cpp
@@ -0,0 +1,269 @@
+#include <precomp.h>
+#include <time.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/systemobj.h>
+#include <api/script/vcpu.h>
+#include <api/wndmgr/msgbox.h>
+#include <api/script/guru.h>
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/skin.h>
+#endif
+#include <bfc/string/bfcstring.h>
+#ifdef WASABI_COMPILE_COMPONENTS
+#include <api/wac/main.h>//CUT!!
+#endif
+#include <api/skin/widgets/group.h>
+#include <api/script/objecttable.h>
+#include <api/application/wkc.h>
+
+extern StringW g_resourcepath;
+
+// insert the given script in the virtual machine
+int Script::addScript(const wchar_t *path, const wchar_t *filename, const wchar_t *id)
+{
+ static int reentering = 0;
+ static int redisplay = 0;
+
+ StringPathCombine fpn(path, filename);
+
+ wchar_t olddir[WA_MAX_PATH] = {0};
+ Wasabi::Std::getCurDir(olddir, WA_MAX_PATH);
+ Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath());
+ OSFILETYPE fp = WFOPEN(fpn, WF_READONLY_BINARY, NO_FILEREADERS);
+ Wasabi::Std::setCurDir(olddir);
+#ifdef WASABI_COMPILE_SKIN
+ if (fp == OPEN_FAILED)
+ {
+ fpn = StringPathCombine(Skin::getDefaultSkinPath(), filename);
+ Wasabi::Std::getCurDir(olddir, WA_MAX_PATH);
+ Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath());
+ fp = WFOPEN(fpn, WF_READONLY_BINARY, NO_FILEREADERS);
+ Wasabi::Std::setCurDir(olddir);
+#endif
+ if (fp == OPEN_FAILED)
+ {
+ if (reentering == 1)
+ {
+ redisplay = 1;
+ return -1;
+ }
+ reentering = 1;
+#ifdef WANT_WASABI_API_WNDMGR
+ WASABI_API_SKIN->messageBox(StringPrintf("Could not load script \'%s%s\'\r\n\r\nPress \'OK\' to continue.", path, filename), "Skin Warning", MSGBOX_OK, NULL, NULL);
+#else
+ Wasabi::Std::messageBox(StringPrintfW(L"Could not load script \'%s%s\'\r\n\r\nPress \'OK\' to continue.", path, filename), L"Skin Warning", 0);
+#endif
+ if (redisplay)
+ {
+#ifdef WANT_WASABI_API_WNDMGR
+ WASABI_API_WND->appdeactivation_setbypass(1);
+#endif
+ Wasabi::Std::messageBox(StringPrintfW(L"Could not load script \'%s%s\'\r\n\r\nPress \'OK\' to continue.", path, filename), L"Skin Warning", 0);
+#ifdef WANT_WASABI_API_WNDMGR
+ WASABI_API_WND->appdeactivation_setbypass(0);
+#endif
+ redisplay = 0;
+ }
+ reentering = 0;
+ return -1;
+ }
+#ifdef WASABI_COMPILE_SKIN
+ }
+#endif
+
+ int size = (int)FGETSIZE(fp);
+
+ void *scriptBlock = MALLOC(size);
+ FREAD(scriptBlock, size, 1, fp);
+ FCLOSE(fp);
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ WasabiKernelController *wkc = Main::getKernelController();
+ if (wkc && !wkc->testScript(fpn, scriptBlock, size)) return -1;
+#endif
+
+ int vcpuid = VCPU::assignNewScriptId();
+
+ SystemObject *system = new SystemObject();
+ system->setScriptId(vcpuid);
+ system->setFilename(filename);
+
+ int r = VCPU::addScript(scriptBlock, size, vcpuid);
+
+ if (r != vcpuid)
+ {
+ FREE(scriptBlock);
+ delete system;
+ return -1;
+ }
+
+ scriptEntry *e = new scriptEntry;
+ e->scriptBlock = scriptBlock;
+ e->vcpuId = vcpuid;
+
+ scriptslist.addItem(e);
+
+ if (!ObjectTable::checkScript(system))
+ {
+ unloadScript(vcpuid);
+ return -1;
+ }
+
+ return vcpuid;
+}
+
+// unload the given script
+void Script::unloadScript(int id)
+{
+ for (int i=0;i<scriptslist.getNumItems();i++) {
+ if (scriptslist.enumItem(i)->vcpuId == id) {
+ VCPU::removeScript(id);
+ FREE(scriptslist.enumItem(i)->scriptBlock);
+ delete scriptslist.enumItem(i);
+ scriptslist.removeByPos(i);
+ }
+ }
+ if (scriptslist.getNumItems() == 0) scriptslist.removeAll(); // disable fortify warning
+}
+
+// unload ALL scripts
+void Script::unloadAllScripts()
+{
+ while (scriptslist.getNumItems()>0)
+ {
+ int n = scriptslist.getNumItems()-1;
+ VCPU::removeScript(scriptslist.enumItem(n)->vcpuId);
+ FREE(scriptslist.enumItem(n)->scriptBlock);
+ delete scriptslist.enumItem(n);
+ scriptslist.removeByPos(n);
+ }
+ scriptslist.removeAll(); // disable fortify warning
+}
+
+PtrList <scriptEntry> Script::scriptslist;
+
+int Script::codeToSeverity(int code, wchar_t *t, int len)
+{
+ switch (code)
+ {
+ case GURU_INVALIDHEADER:
+ case GURU_OLDFORMAT:
+ wcsncpy(t, L"Ignoring script", len);
+ return 5;
+ case GURU_DIVBYZERO:
+ wcsncpy(t, L"Returning 0", len);
+ return 4;
+ case GURU_NEWFAILED:
+ wcsncpy(t, L"Returning NULL", len);
+ return 4;
+ case GURU_NULLCALLED:
+ wcsncpy(t, L"Ignoring call", len);
+ return 4;
+ case GURU_INCOMPATIBLEOBJECT:
+ wcsncpy(t, L"Assigning NULL", len);
+ return 4;
+ default:
+ wcsncpy(t, L"Internal error", len);
+ return 9;
+ }
+}
+
+void Script::guruMeditation(SystemObject *script, int code, const wchar_t *pub, int intinfo) {
+
+ wchar_t t[256] = {0}, u[256] = {0};
+ codeToSeverity(code, u, 256);
+ if (pub)
+ WCSNPRINTF(t, 256, L"guru: %s - #%04X.%04X%04X", pub, code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF);
+ else
+ WCSNPRINTF(t, 256, L"guru: #%04X.%04X%04X", pub, code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF);
+ if (*u) {
+ wcscat(t, L" - ");
+ wcscat(t, u);
+ }
+ DebugStringW(L"%s\n", t);
+
+ time_t now;
+ time(&now);
+ struct tm *lt = localtime(&now);
+#ifdef _WIN32
+ wchar_t *p = _wasctime(lt);
+#else
+#warning port me
+ wchar_t *p = L"port me";
+#endif
+ if (p && *p) p[wcslen(p)-1]=0;
+
+ FILE *fout = _wfopen(StringPathCombine(WASABI_API_APP->path_getUserSettingsPath(), L"guru.log"), WF_APPEND_RW);
+ if (fout)
+ {
+ StringPrintfW z(L"%s (%s/%s) - ", p, WASABI_API_SKIN->getSkinName(),script->getFilename());
+ if (*u)
+ {
+ z.cat(u);
+ z.cat(L" - ");
+ }
+ StringPrintfW log(L"%s#%04X.%04X%04X.%d%s%s\n", z.getValue(), code, (intinfo & 0xFFFF), VCPU::VIP & 0xFFFF, VCPU::VSD, pub?L" ":L"", pub?pub:L"");
+ fputws(log.getValue(), fout);
+ fclose(fout);
+ }
+
+ Guru::spawn(script, code, pub, intinfo);
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+// WASABI_API_MAKIDEBUG->debugger_createJITD(script->getScriptId(), 1);
+// debugApi->debugger_trace();
+#endif
+}
+
+void Script::setScriptParam(int id, const wchar_t *p)
+{
+ SystemObject *s = SOM::getSystemObjectByScriptId(id);
+ if (s) s->setParam(p);
+}
+
+void Script::setParentGroup(int id, Group *g)
+{
+ SystemObject *s = SOM::getSystemObjectByScriptId(id);
+ if (s) s->setParentGroup(g);
+}
+
+void Script::setSkinPartId(int id, int skinpartid)
+{
+ SystemObject *s = SOM::getSystemObjectByScriptId(id);
+ if (s) s->setSkinPartId(skinpartid);
+}
+
+int Script::varIdToGlobal(int id, int script)
+{
+ return id + VCPU::varBase(script);
+}
+
+int Script::getNumEventsLinked()
+{
+ return VCPU::eventsTable.getNumItems();
+}
+
+int Script::getLinkedEventParams(int num, int *dlfid, int *scriptid, int *varid)
+{
+ VCPUeventEntry *e = VCPU::eventsTable.enumItem(num);
+ if (dlfid) *dlfid = e->DLFid;
+ if (scriptid) *scriptid = e->scriptId;
+ if (varid) *varid = e->varId;
+ return num;
+}
+
+int Script::getCacheCount()
+{
+ return VCPU::getCacheCount();
+}
+
+int Script::getUserAncestor(int varid, int scriptid)
+{
+ return VCPU::getUserAncestor(varid, scriptid);
+}
+
+int Script::isValidScriptId(int id)
+{
+ return VCPU::isValidScriptId(id);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/script/script.h b/Src/Wasabi/api/script/script.h
new file mode 100644
index 00000000..8f6e5986
--- /dev/null
+++ b/Src/Wasabi/api/script/script.h
@@ -0,0 +1,86 @@
+#ifndef __SCRIPT_H
+#define __SCRIPT_H
+
+#include <bfc/ptrlist.h>
+#include <api/script/vcputypes.h>
+
+class String;
+
+#define GURU_POPEMPTYSTACK 0
+#define GURU_INVALIDHEADER 1
+#define GURU_INVALIDFUNCINDLF 2
+#define GURU_INVALIDFUNCBT 3
+#define GURU_INVALIDVARBT 4
+#define GURU_INVALIDEVENTDLF 5
+#define GURU_INVALIDEVENTADDR 6
+#define GURU_INVALIDEVENTVAR 7
+#define GURU_INVALIDSCRIPTID 8
+#define GURU_DLFSETUPFAILED 9
+#define GURU_SETNONINTERNAL 10
+#define GURU_INCSNONNUM 11
+#define GURU_DECSNONNUM 12
+#define GURU_INCPNONNUM 13
+#define GURU_DECPNONNUM 14
+#define GURU_OBJECTADD 15
+#define GURU_SUBNONNUM 16
+#define GURU_MULNONNUM 17
+#define GURU_DIVNONNUM 18
+#define GURU_DIVBYZERO 19
+#define GURU_MODNONNUM 20
+#define GURU_NEGNONNUM 21
+#define GURU_BNOTNONNUM 22
+#define GURU_SHLNONNUM 23
+#define GURU_SHRNONNUM 24
+#define GURU_XORNONNUM 25
+#define GURU_ANDNONNUM 26
+#define GURU_NEWFAILED 27
+#define GURU_NULLCALLED 28
+#define GURU_OLDFORMAT 29
+#define GURU_INVALIDPEEKSTACK 30
+#define GURU_INVALIDOLDID 31
+#define GURU_INCOMPATIBLEOBJECT 32
+#define GURU_EXCEPTION 33
+#define GURU_FUTUREFORMAT 34
+
+// This is our virtual machine basic type. Reducing of expression will use this
+// type. We will not malloc or new it, but we'll pass it on the stack for speed
+// and stability. 8 bytes should be ok for our stack. This way we won't have to
+// maintain lists on dynamically allocated computation values, and we won't have
+// to cleanup if some error (divide by zero ?) occurs in the middle of a
+// statement. String values are an exception since sdata will point to dynamic
+// data, but since every step of the virtual machine reducing strings will free
+// that data, cleanup will be automatic
+
+typedef struct {
+ void *scriptBlock;
+ int vcpuId; // id of script in virtual CPU. will be used later for unloading
+} scriptEntry;
+
+class Group;
+class SystemObject;
+
+class Script
+{
+public:
+ static int addScript(const wchar_t *path, const wchar_t *filename, const wchar_t *id);
+ static void unloadScript(int id);
+ static void unloadAllScripts();
+ static void guruMeditation(SystemObject *script, int code, const wchar_t *pub=NULL, int intinfo=0);
+ static void setScriptParam(int id, const wchar_t *p);
+ static int varIdToGlobal(int id, int script);
+ static int getNumEventsLinked();
+ static int getLinkedEventParams(int num, int *dlfid, int *scriptid, int *varid);
+ static int getCacheCount();
+ static int getUserAncestor(int varid, int scriptid);
+ static int isValidScriptId(int id);
+ static void setParentGroup(int id, Group *g);
+ static void setSkinPartId(int id, int skinpartid);
+ static int getNumScripts() { return scriptslist.getNumItems(); }
+
+ static PtrList <scriptEntry> scriptslist;
+
+private:
+ static int codeToSeverity(int code, wchar_t *t, int len);
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/scriptguid.h b/Src/Wasabi/api/script/scriptguid.h
new file mode 100644
index 00000000..33035118
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptguid.h
@@ -0,0 +1,143 @@
+#ifndef __SCRIPTGUID_H
+#define __SCRIPTGUID_H
+
+#include <bfc/nsguid.h>
+
+// {C61F6050-6C0C-4b3b-B429-ACEAD0A51B11}
+const GUID scriptObjectGuid =
+{ 0xc61f6050, 0x6c0c, 0x4b3b, { 0xb4, 0x29, 0xac, 0xea, 0xd0, 0xa5, 0x1b, 0x11 } };
+
+// {51654971-0D87-4a51-91E3-A6B53235F3E7}
+const GUID rootObjectGuid =
+{ 0x51654971, 0x0d87, 0x4a51, { 0x91, 0xe3, 0xa6, 0xb5, 0x32, 0x35, 0xf3, 0xe7 } };
+
+// {4EE3E199-C636-4bec-97CD-78BC9C8628B0}
+const GUID guiObjectGuid =
+{ 0x4ee3e199, 0xc636, 0x4bec, { 0x97, 0xcd, 0x78, 0xbc, 0x9c, 0x86, 0x28, 0xb0 } };
+
+// {45BE95E5-2072-4191-935C-BB5FF9F117FD}
+const GUID groupGuid =
+{ 0x45be95e5, 0x2072, 0x4191, { 0x93, 0x5c, 0xbb, 0x5f, 0xf9, 0xf1, 0x17, 0xfd } };
+
+// {698EDDCD-8F1E-4fec-9B12-F944F909FF45}
+const GUID buttonGuid =
+{ 0x698eddcd, 0x8f1e, 0x4fec, { 0x9b, 0x12, 0xf9, 0x44, 0xf9, 0x9, 0xff, 0x45 } };
+
+// {FB508805-53D0-4f74-A62D-A1A8EF2B242C}
+const GUID xmlObjectGuid =
+{ 0xfb508805, 0x53d0, 0x4f74, { 0xa6, 0x2d, 0xa1, 0xa8, 0xef, 0x2b, 0x24, 0x2c } };
+
+// {EFAA8672-310E-41fa-B7DC-85A9525BCB4B}
+const GUID textGuid =
+{ 0xefaa8672, 0x310e, 0x41fa, { 0xb7, 0xdc, 0x85, 0xa9, 0x52, 0x5b, 0xcb, 0x4b } };
+
+// {A8C2200D-51EB-4b2a-BA7F-5D4BC65D4C71}
+const GUID browserGuid =
+{ 0xa8c2200d, 0x51eb, 0x4b2a, { 0xba, 0x7f, 0x5d, 0x4b, 0xc6, 0x5d, 0x4c, 0x71 } };
+
+//// {0B099223-4EB3-4780-9937-6D210372F2CF}
+const GUID listGuid =
+{ 0xb099223, 0x4eb3, 0x4780, { 0x99, 0x37, 0x6d, 0x21, 0x3, 0x72, 0xf2, 0xcf } };
+
+// {CDCB785D-81F2-4253-8F05-61B872283CFA}
+const GUID queryListGuid =
+{ 0xcdcb785d, 0x81f2, 0x4253, { 0x8f, 0x5, 0x61, 0xb8, 0x72, 0x28, 0x3c, 0xfa } };
+
+// {8A6D2485-47F7-4204-9448-7C9656F42DEE}
+const GUID filterListGuid =
+{ 0x8a6d2485, 0x47f7, 0x4204, { 0x94, 0x48, 0x7c, 0x96, 0x56, 0xf4, 0x2d, 0xee } };
+
+// {403ABCC0-6F22-4bd6-8BA4-10C829932547}
+const GUID windowHolderGuid =
+{ 0x403abcc0, 0x6f22, 0x4bd6, { 0x8b, 0xa4, 0x10, 0xc8, 0x29, 0x93, 0x25, 0x47 } };
+
+// {36D59B71-03FD-4af8-9795-0502B7DB267A}
+const GUID dropDownListGuid =
+{ 0x36d59b71, 0x3fd, 0x4af8, { 0x97, 0x95, 0x5, 0x2, 0xb7, 0xdb, 0x26, 0x7a } };
+
+// {0808797D-3EE9-4e12-B88B-4E6274984FDF}
+static const GUID formObjectGuid =
+{ 0x808797d, 0x3ee9, 0x4e12, { 0xb8, 0x8b, 0x4e, 0x62, 0x74, 0x98, 0x4f, 0xdf } };
+
+// {47D73EEF-2A8E-4593-AF70-45A9CFDBB329}
+const GUID pathPickerGuid =
+{ 0x47d73eef, 0x2a8e, 0x4593, { 0xaf, 0x70, 0x45, 0xa9, 0xcf, 0xdb, 0xb3, 0x29 } };
+
+// {7FD5F210-ACC4-48df-A6A0-5451576CDC76}
+const GUID layoutStatusGuid =
+{ 0x7fd5f210, 0xacc4, 0x48df, { 0xa6, 0xa0, 0x54, 0x51, 0x57, 0x6c, 0xdc, 0x76 } };
+
+// {64E4BBFA-81F4-49d9-B0C0-A85B2EC3BCFD}
+const GUID editGuid =
+{ 0x64e4bbfa, 0x81f4, 0x49d9, { 0xb0, 0xc0, 0xa8, 0x5b, 0x2e, 0xc3, 0xbc, 0xfd } };
+
+// {E90DC47B-840D-4ae7-B02C-040BD275F7FC}
+const GUID containerGuid =
+{ 0xe90dc47b, 0x840d, 0x4ae7, { 0xb0, 0x2c, 0x4, 0xb, 0xd2, 0x75, 0xf7, 0xfc } };
+
+// {60906D4E-537E-482e-B004-CC9461885672}
+const GUID layoutGuid =
+{ 0x60906d4e, 0x537e, 0x482e, { 0xb0, 0x4, 0xcc, 0x94, 0x61, 0x88, 0x56, 0x72 } };
+
+// {B4DCCFFF-81FE-4bcc-961B-720FD5BE0FFF}
+const GUID toggleButtonGuid =
+{ 0xb4dccfff, 0x81fe, 0x4bcc, { 0x96, 0x1b, 0x72, 0xf, 0xd5, 0xbe, 0xf, 0xff } };
+
+// {62B65E3F-375E-408d-8DEA-76814AB91B77}
+const GUID sliderGuid =
+{ 0x62b65e3f, 0x375e, 0x408d, { 0x8d, 0xea, 0x76, 0x81, 0x4a, 0xb9, 0x1b, 0x77 } };
+
+// {A8F61649-AA6C-46d1-9415-0AE491999E25}
+static const GUID tabSheetGuid =
+{ 0xa8f61649, 0xaa6c, 0x46d1, { 0x94, 0x15, 0xa, 0xe4, 0x91, 0x99, 0x9e, 0x25 } };
+
+// {1819D795-7A6F-4f2a-8A4D-7DB3EEA90911}
+static const GUID embeddedXuiGuid =
+{ 0x1819d795, 0x7a6f, 0x4f2a, { 0x8a, 0x4d, 0x7d, 0xb3, 0xee, 0xa9, 0x9, 0x11 } };
+
+// {B5BAA535-05B3-4dcb-ADC1-E618D28F6896}
+static const GUID tabsheetGuid =
+{ 0xb5baa535, 0x5b3, 0x4dcb, { 0xad, 0xc1, 0xe6, 0x18, 0xd2, 0x8f, 0x68, 0x96 } };
+
+// {6129FEC1-DAB7-4d51-9165-01CA0C1B70DB}
+static const GUID guilistGuid =
+{ 0x6129fec1, 0xdab7, 0x4d51, { 0x91, 0x65, 0x1, 0xca, 0xc, 0x1b, 0x70, 0xdb } };
+// {6129FEC1-DAB7-4d51-9165-01CA0C1B70DB}
+static const GUID guiListGuid =
+{ 0x6129fec1, 0xdab7, 0x4d51, { 0x91, 0x65, 0x1, 0xca, 0xc, 0x1b, 0x70, 0xdb } };
+
+// {D59514F7-ED36-45e8-980F-3F4EA0522CD9}
+static const GUID guitreeGuid =
+{ 0xd59514f7, 0xed36, 0x45e8, { 0x98, 0xf, 0x3f, 0x4e, 0xa0, 0x52, 0x2c, 0xd9 } };
+// {D59514F7-ED36-45e8-980F-3F4EA0522CD9}
+static const GUID guiTreeGuid =
+{ 0xd59514f7, 0xed36, 0x45e8, { 0x98, 0xf, 0x3f, 0x4e, 0xa0, 0x52, 0x2c, 0xd9 } };
+
+// {9B3B4B82-667A-420e-8FFC-794115809C02}
+static const GUID treeitemGuid =
+{ 0x9b3b4b82, 0x667a, 0x420e, { 0x8f, 0xfc, 0x79, 0x41, 0x15, 0x80, 0x9c, 0x2 } };
+// {9B3B4B82-667A-420e-8FFC-794115809C02}
+static const GUID treeItemGuid =
+{ 0x9b3b4b82, 0x667a, 0x420e, { 0x8f, 0xfc, 0x79, 0x41, 0x15, 0x80, 0x9c, 0x2 } };
+
+// {1D8631C8-80D0-4792-9F98-BD5D36B49136}
+static const GUID menuButtonGuid =
+{ 0x1d8631c8, 0x80d0, 0x4792, { 0x9f, 0x98, 0xbd, 0x5d, 0x36, 0xb4, 0x91, 0x36 } };
+
+// {C0492857-5E28-43b7-97EC-86278A646491}
+static const GUID menuButtonSurfaceGuid =
+{ 0xc0492857, 0x5e28, 0x43b7, { 0x97, 0xec, 0x86, 0x27, 0x8a, 0x64, 0x64, 0x91 } };
+
+// {C7ED3199-5319-4798-9863-60B15A298CAA}
+static const GUID checkBoxGuid =
+{ 0xc7ed3199, 0x5319, 0x4798, { 0x98, 0x63, 0x60, 0xb1, 0x5a, 0x29, 0x8c, 0xaa } };
+
+// {01E28CE1-B059-11d5-979F-E4DE6F51760A}
+static const GUID groupListGuid =
+{ 0x1e28ce1, 0xb059, 0x11d5, { 0x97, 0x9f, 0xe4, 0xde, 0x6f, 0x51, 0x76, 0xa } };
+
+// {E2BBC14D-84F6-4173-BDB3-B2EB2F665550}
+static const GUID scriptFrameGuid =
+{ 0xe2bbc14d, 0x84f6, 0x4173, { 0xbd, 0xb3, 0xb2, 0xeb, 0x2f, 0x66, 0x55, 0x50 } };
+
+#endif
diff --git a/Src/Wasabi/api/script/scriptmgr.cpp b/Src/Wasabi/api/script/scriptmgr.cpp
new file mode 100644
index 00000000..2ae3f0ec
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptmgr.cpp
@@ -0,0 +1,602 @@
+#include <precomp.h>
+#include <bfc/wasabi_std.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/systemobj.h>
+#include <api/script/vcpu.h>
+#include <api/skin/skinparse.h>
+#include <api/script/objecttable.h>
+#ifdef WASABI_COMPILE_WND
+#include <api/wnd/wndtrack.h>
+#endif
+
+#ifdef WASABI_COMPILE_COMPONENTS
+PtrList<WACObject> comps;
+#endif
+
+extern GUID baseGUID;
+
+ScriptObjectManager::ScriptObjectManager() {
+ ASSERTPR(!inited, "don't create 2 scriptobjectmanager, you dumbass");
+ inited=1;
+#ifdef WASABI_COMPILE_COMPONENTS
+ for (int i=0;i<api->getNumComponents();i++) {
+ GUID g = api->getComponentGUID(i);
+ WACObject *c = new WACObject();
+ c->setGUID(g);
+ comps.addItem(c);
+ }
+ WACObject *m = new WACObject();
+ m->setGUID(baseGUID);
+ comps.addItem(m);
+#endif
+}
+
+ScriptObjectManager::~ScriptObjectManager() {
+ inited=0;
+#ifdef WASABI_COMPILE_COMPONENTS
+ comps.deleteAll();
+#endif
+}
+
+// Create a variable of specified type
+scriptVar ScriptObjectManager::makeVar(int type)
+{
+ scriptVar v;
+ v.type = type;
+ v.data.ddata = 0;
+ return v;
+}
+
+// Create a variable of specified type and assigns an object to it
+scriptVar ScriptObjectManager::makeVar(int type, ScriptObject *o)
+{
+ scriptVar v = makeVar(type);
+ v.data.odata = o;
+ return v;
+}
+
+// Assigns a char* to a String variable. Frees old value if necessary
+void ScriptObjectManager::assign(scriptVar *v, const wchar_t *str)
+{
+ ASSERT(v != NULL);
+ ASSERT(v->type == SCRIPT_STRING); // Compiler discarded
+ if (v->data.sdata) FREE((wchar_t *)v->data.sdata);
+ if ((int)str > 65536) {
+ v->data.sdata = WCSDUP(str);
+ VCPU::addStatementString(const_cast<wchar_t *>(v->data.sdata));
+ } else
+ v->data.sdata = NULL;
+}
+
+// Assigns an int to an int, float or double variable.
+void ScriptObjectManager::assign(scriptVar *v, int i) {
+ ASSERT(v != NULL);
+ switch (v->type) {
+ case SCRIPT_FLOAT:
+ assign(v, (float)i);
+ return;
+ case SCRIPT_DOUBLE:
+ assign(v, (double)i);
+ return;
+ case SCRIPT_INT:
+ case SCRIPT_BOOLEAN:
+ v->data.idata = i;
+ return;
+ case SCRIPT_STRING:
+ assign(v, StringPrintfW(L"%d", i));
+ return;
+ default:
+ assign(v, (ScriptObject*)NULL);
+ return;
+ }
+}
+
+// Assigns a float to an int, float or double variable.
+void ScriptObjectManager::assign(scriptVar *v, float f) {
+ ASSERT(v != NULL);
+ switch (v->type) {
+ case SCRIPT_INT:
+ case SCRIPT_BOOLEAN:
+ assign(v, (int)f);
+ return;
+ case SCRIPT_DOUBLE:
+ assign(v, (double)f);
+ return;
+ case SCRIPT_FLOAT:
+ v->data.fdata = f;
+ return;
+ case SCRIPT_STRING:
+ {
+ wchar_t t[96] = {0};
+ WCSNPRINTF(t, 96, L"%f", f);
+ assign(v, t);
+ return;
+ }
+ default:
+ assign(v, (ScriptObject*)NULL);
+ return;
+ }
+}
+
+// Assigns a double to an int, float or double variable.
+void ScriptObjectManager::assign(scriptVar *v, double d) {
+ ASSERT(v != NULL);
+ switch (v->type) {
+ case SCRIPT_INT:
+ case SCRIPT_BOOLEAN:
+ assign(v, (int)d);
+ return;
+ case SCRIPT_FLOAT:
+ assign(v, (float)d);
+ return;
+ case SCRIPT_DOUBLE:
+ v->data.ddata = d;
+ return;
+ case SCRIPT_STRING:
+ {
+ wchar_t t[96] = {0};
+ WCSNPRINTF(t, 96, L"%e", d);
+ assign(v, t);
+ return;
+ }
+ default:
+ assign(v, (ScriptObject*)NULL);
+ return;
+ }
+}
+
+// Assigns a object to an object variable, handles hierarchy.
+void ScriptObjectManager::assign(scriptVar *v, ScriptObject *o) {
+ ASSERT(v != NULL);
+ // TODO: temporarily assert descendancy
+ v->data.odata = o;
+}
+
+
+// Assigns a numerical scriptVar to another numerical scriptVar
+// or an object to another object
+// Autocasts
+void ScriptObjectManager::assign(scriptVar *v1, scriptVar *v2) {
+ ASSERT(v1 != NULL);
+ ASSERT(v2 != NULL);
+ switch (v1->type) {
+ case SCRIPT_INT:
+ assign(v1, SOM::makeInt(v2));
+ break;
+ case SCRIPT_FLOAT:
+ assign(v1, SOM::makeFloat(v2));
+ break;
+ case SCRIPT_DOUBLE:
+ assign(v1, SOM::makeDouble(v2));
+ break;
+ case SCRIPT_STRING:
+ assign(v1, v2->data.sdata);
+ break;
+ case SCRIPT_BOOLEAN:
+ assign(v1, SOM::makeBoolean(v2));
+ break;
+ default:
+ assign(v1, v2->data.odata);
+ break;
+ }
+}
+
+void ScriptObjectManager::assignPersistent(scriptVar *v1, scriptVar *v2) {
+ ASSERT(v1 != NULL);
+ ASSERT(v2 != NULL);
+ switch (v1->type) {
+ case SCRIPT_INT:
+ assign(v1, SOM::makeInt(v2));
+ break;
+ case SCRIPT_FLOAT:
+ assign(v1, SOM::makeFloat(v2));
+ break;
+ case SCRIPT_DOUBLE:
+ assign(v1, SOM::makeDouble(v2));
+ break;
+ case SCRIPT_STRING:
+ persistentstrassign(v1, v2->data.sdata);
+ break;
+ case SCRIPT_BOOLEAN:
+ assign(v1, SOM::makeBoolean(v2));
+ break;
+ default:
+ assign(v1, v2->data.odata);
+ break;
+ }
+}
+
+void ScriptObjectManager::strflatassign(scriptVar *v, const wchar_t *str)
+{
+ ASSERT(v != NULL);
+ ASSERT(v->type == SCRIPT_STRING); // Compiler discarded
+ if (v->data.sdata) FREE((wchar_t *)v->data.sdata);
+ if ((int)str > 65536)
+ v->data.sdata = (wchar_t *)str;
+ else
+ v->data.sdata = NULL;
+}
+
+void ScriptObjectManager::persistentstrassign(scriptVar *v, const wchar_t *str) {
+ ASSERT(v != NULL);
+ ASSERT(v->type == SCRIPT_STRING); // Compiler discarded
+ if (v->data.sdata) FREE((wchar_t *)v->data.sdata);
+ if ((int)str > 65536)
+ v->data.sdata = WCSDUP(str);
+ else
+ v->data.sdata = NULL;
+}
+
+// comparision functions
+int ScriptObjectManager::compEq(scriptVar *v1, scriptVar *v2) {
+ int r;
+ switch (v1->type) {
+ case SCRIPT_INT:
+ r = v1->data.idata == makeInt(v2);
+ break;
+ case SCRIPT_FLOAT:
+ r = v1->data.fdata == makeFloat(v2);
+ break;
+ case SCRIPT_DOUBLE:
+ r = v1->data.ddata == makeDouble(v2);
+ break;
+ case SCRIPT_BOOLEAN:
+ r = ((v1->data.idata == 0) ? 0 : 1) == ((makeBoolean(v2) == 0) ? 0 : 1);
+ break;
+ case SCRIPT_STRING:
+ if (v1->data.sdata && v2->data.sdata)
+ {
+ r = !wcscmp(v1->data.sdata, v2->data.sdata);
+ break;
+ }
+ // pass through
+ default: // any object, reference has to match
+ r = v1->data.odata == v2->data.odata;
+ break;
+ }
+ return r;
+}
+
+int ScriptObjectManager::compNeq(scriptVar *v1, scriptVar *v2) {
+ int r;
+ switch (v1->type) {
+ case SCRIPT_INT:
+ r = v1->data.idata != makeInt(v2);
+ break;
+ case SCRIPT_FLOAT:
+ r = v1->data.fdata != makeFloat(v2);
+ break;
+ case SCRIPT_DOUBLE:
+ r = v1->data.ddata != makeDouble(v2);
+ break;
+ case SCRIPT_BOOLEAN:
+ r = ((v1->data.idata == 0) ? 0 : 1) != ((makeBoolean(v2) == 0) ? 0 : 1);
+ break;
+ case SCRIPT_STRING:
+ if (v1->data.sdata && v2->data.sdata)
+ r = (wcscmp(v1->data.sdata, v2->data.sdata) != 0) ? 1 : 0;
+ else
+ r = 0;
+ break;
+ default:
+ r = v1->data.odata != v2->data.odata;
+ break;
+ }
+ return r;
+}
+
+int ScriptObjectManager::compA(scriptVar *v1, scriptVar *v2) {
+ int r;
+ switch (v1->type) {
+ case SCRIPT_BOOLEAN:
+ r = ((v1->data.idata == 0) ? 0 : 1) > ((makeBoolean(v2) == 0) ? 0 : 1);
+ break;
+ case SCRIPT_INT:
+ r = v1->data.idata > makeInt(v2);
+ break;
+ case SCRIPT_FLOAT:
+ r = v1->data.fdata > makeFloat(v2);
+ break;
+ case SCRIPT_DOUBLE:
+ r = v1->data.ddata > makeDouble(v2);
+ break;
+ case SCRIPT_STRING:
+ r = (wcscmp(v1->data.sdata, v2->data.sdata) > 0) ? 1 : 0;
+ break;
+ default:
+ r = 0;
+ break;
+ }
+ return r;
+}
+
+int ScriptObjectManager::compAe(scriptVar *v1, scriptVar *v2) {
+ int r;
+ switch (v1->type) {
+ case SCRIPT_BOOLEAN:
+ r = ((v1->data.idata == 0) ? 0 : 1) >= ((makeBoolean(v2) == 0) ? 0 : 1);
+ break;
+ case SCRIPT_INT:
+ r = v1->data.idata >= makeInt(v2);
+ break;
+ case SCRIPT_FLOAT:
+ r = v1->data.fdata >= makeFloat(v2);
+ break;
+ case SCRIPT_DOUBLE:
+ r = v1->data.ddata >= makeDouble(v2);
+ break;
+ case SCRIPT_STRING:
+ r = (wcscmp(v1->data.sdata, v2->data.sdata) >= 0) ? 1 : 0;
+ break;
+ default:
+ r = 0;
+ break;
+ }
+ return r;
+}
+
+int ScriptObjectManager::compB(scriptVar *v1, scriptVar *v2) {
+ int r;
+ switch (v1->type) {
+ case SCRIPT_BOOLEAN:
+ r = ((v1->data.idata == 0) ? 0 : 1) < ((makeBoolean(v2) == 0) ? 0 : 1);
+ break;
+ case SCRIPT_INT:
+ r = v1->data.idata < makeInt(v2);
+ break;
+ case SCRIPT_FLOAT:
+ r = v1->data.fdata < makeFloat(v2);
+ break;
+ case SCRIPT_DOUBLE:
+ r = v1->data.ddata < makeDouble(v2);
+ break;
+ case SCRIPT_STRING:
+ r = (wcscmp(v1->data.sdata, v2->data.sdata) < 0) ? 1 : 0;
+ break;
+ default:
+ r = 0;
+ break;
+ }
+ return r;
+}
+
+int ScriptObjectManager::compBe(scriptVar *v1, scriptVar *v2) {
+ int r;
+ switch (v1->type) {
+ case SCRIPT_BOOLEAN:
+ r = ((v1->data.idata == 0) ? 0 : 1) <= ((makeBoolean(v2) == 0) ? 0 : 1);
+ break;
+ case SCRIPT_INT:
+ r = v1->data.idata <= makeInt(v2);
+ break;
+ case SCRIPT_FLOAT:
+ r = v1->data.fdata <= makeFloat(v2);
+ break;
+ case SCRIPT_DOUBLE:
+ r = v1->data.ddata <= makeDouble(v2);
+ break;
+ case SCRIPT_STRING:
+ r = (wcscmp(v1->data.sdata, v2->data.sdata) <= 0) ? 1 : 0;
+ break;
+ default:
+ r = 0;
+ break;
+ }
+ return r;
+}
+
+void ScriptObjectManager::mid(wchar_t *dest, const wchar_t *str, int s, int l) {
+ if (str == NULL) return;
+ int rl = wcslen(str);
+ if (l == 0) return;
+ if (s >= rl) return;
+ if (s+l > rl || l == -1) l = rl-s;
+ WCSCPYN(dest, str+s, l+1);
+}
+
+int ScriptObjectManager::makeInt(scriptVar *v) {
+ switch (v->type) {
+ case SCRIPT_INT:
+ return v->data.idata;
+ case SCRIPT_FLOAT:
+ return (int)v->data.fdata;
+ case SCRIPT_DOUBLE:
+ return (int)v->data.ddata;
+ case SCRIPT_BOOLEAN:
+ return (v->data.idata == 0) ? 0 : 1;
+ case SCRIPT_STRING:
+ return WTOI(v->data.sdata);
+ default:
+ return 0;
+ }
+}
+
+float ScriptObjectManager::makeFloat(scriptVar *v) {
+ switch (v->type) {
+ case SCRIPT_INT:
+ return (float)v->data.idata;
+ case SCRIPT_FLOAT:
+ return v->data.fdata;
+ case SCRIPT_DOUBLE:
+ return (float)v->data.ddata;
+ case SCRIPT_BOOLEAN:
+ return (float)((v->data.idata == 0) ? 0 : 1);
+ case SCRIPT_STRING:
+ return (float)WTOF(v->data.sdata);
+ default:
+ return 0.0f;
+ }
+}
+
+double ScriptObjectManager::makeDouble(scriptVar *v) {
+ switch (v->type) {
+ case SCRIPT_VOID:
+ return 0;
+ case SCRIPT_INT:
+ return (double)v->data.idata;
+ case SCRIPT_FLOAT:
+ return (double)v->data.fdata;
+ case SCRIPT_DOUBLE:
+ return v->data.ddata;
+ case SCRIPT_BOOLEAN:
+ return (double)((v->data.idata == 0) ? 0 : 1);
+ case SCRIPT_STRING:
+ return WTOF(v->data.sdata);
+ default:
+ return 0.0;
+ }
+}
+
+bool ScriptObjectManager::makeBoolean(scriptVar *v) {
+ switch (v->type) {
+ case SCRIPT_INT:
+ case SCRIPT_BOOLEAN:
+ return (v->data.idata == 0) ? 0 : 1;
+ case SCRIPT_FLOAT:
+ return (v->data.fdata == 0) ? 0 : 1;
+ case SCRIPT_DOUBLE:
+ return (v->data.ddata == 0) ? 0 : 1;
+ case SCRIPT_STRING: {
+ StringW s = v->data.sdata;
+ if (s.iscaseequal(L"false") || s.iscaseequal(L"f"))
+ return 0;
+ if (s.iscaseequal(L"true") || s.iscaseequal(L"t"))
+ return 1;
+ return (WTOI(s.getValue()) != 0);
+ }
+ default:
+ return (v->data.odata != NULL) ? 1 : 0;
+ }
+}
+
+int ScriptObjectManager::isNumeric(scriptVar *s) {
+ return isNumericType(s->type);
+}
+
+int ScriptObjectManager::isString(scriptVar *s) {
+ return (s->type == SCRIPT_STRING);
+}
+
+int ScriptObjectManager::isVoid(scriptVar *s) {
+ return (s->type == SCRIPT_VOID);
+}
+
+int ScriptObjectManager::isObject(scriptVar *s) {
+ return (s->type == SCRIPT_OBJECT);
+}
+
+int ScriptObjectManager::isNumericType(int t) {
+ return (t == SCRIPT_INT || t == SCRIPT_BOOLEAN || t == SCRIPT_FLOAT || t == SCRIPT_DOUBLE);
+}
+
+#ifdef WASABI_COMPILE_COMPONENTS
+WACObject *ScriptObjectManager::getWACObject(const char *guid) {
+ GUID cg;
+ //BU: let me use guid:avs please :)
+ cg = *SkinParser::getComponentGuid(guid);
+ return getWACObject(cg);
+}
+
+WACObject *ScriptObjectManager::getWACObject(GUID cg) {
+ for (int i=0;i<comps.getNumItems();i++) {
+ GUID dg = comps[i]->getGUID();
+ if (!MEMCMP(&dg,&cg,sizeof(GUID)))
+ return comps[i];
+ }
+ return NULL;
+}
+#endif
+
+SystemObject *ScriptObjectManager::getSystemObject(int n) {
+ return syslist.enumItem(n);
+}
+
+SystemObject *ScriptObjectManager::getSystemObjectByScriptId(int id) {
+ static int lasti = -1;
+ static SystemObject *lasto = NULL;
+ if (lasti == id && syslist.haveItem(lasto)) return lasto;
+ for (int i=0;i<syslist.getNumItems();i++) {
+ if (syslist.enumItem(i)->getScriptId() == id) {
+ lasto = syslist.enumItem(i);
+ lasti = id;
+ return lasto;
+ }
+ }
+ return NULL;
+}
+
+void ScriptObjectManager::registerSystemObject(SystemObject *o) {
+ syslist.addItem(o);
+}
+
+void ScriptObjectManager::unregisterSystemObject(SystemObject *o) {
+ syslist.removeItem(o);
+}
+
+int SOM::getNumSystemObjects() {
+ return syslist.getNumItems();
+}
+
+SystemObject *SOM::enumSystemObject(int n) {
+ return syslist.enumItem(n);
+}
+
+int ScriptObjectManager::typeCheck(VCPUscriptVar *v, int fail) {
+ ASSERT(v);
+ ASSERT(v->v.data.odata);
+ int type = v->v.type;
+ while (type >= 0x10000) {
+ int id = VCPU::varBase(v->scriptId) + (type - 0x10000);
+ VCPUscriptVar *vc = VCPU::variablesTable.enumItem(id);
+ type = vc->v.type;
+ }
+ int otype = ObjectTable::getClassFromName(v->v.data.odata->vcpu_getClassName());
+ ASSERT(otype >= 0);
+ if (ObjectTable::isDescendant(type, otype)) return 1;
+ if (fail)
+ Script::guruMeditation(getSystemObject(v->scriptId), GURU_INCOMPATIBLEOBJECT, L"VAR/OBJECT CLASS MISMATCH", v->varId);
+ return 0;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+WindowHolder *ScriptObjectManager::getSuitableWindowHolderFromScript(GUID g) {
+ for (int i=0;i<getNumSystemObjects();i++) {
+ SystemObject *o = enumSystemObject(i);
+ WindowHolder *so = o->getSuitableWindowHolderByGuid(g);
+ if (so) return so;
+ }
+ return NULL;
+}
+
+int ScriptObjectManager::checkAbortShowHideWindow(GUID g, int visible) {
+ for (int i=0;i<getNumSystemObjects();i++) {
+ SystemObject *o = enumSystemObject(i);
+ int r = o->onGetCancelComponent(g, visible);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+#endif
+
+#ifdef WASABI_COMPILE_WND
+ScriptObject *ScriptObjectManager::findObject(const wchar_t *name)
+{
+ for (int i=0;i<windowTracker->getNumAllWindows();i++)
+ {
+ ScriptObject *so = static_cast<ScriptObject *>(windowTracker->enumAllWindows(i)->getInterface(scriptObjectGuid));
+ if (!so) continue;
+ GuiObject *go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
+ if (!go) continue;
+ if (WCSCASEEQLSAFE(go->guiobject_getId(), name))
+ return so;
+ }
+ return NULL;
+}
+#endif
+
+SystemObject * ScriptObjectManager::system;
+PtrList < SystemObject > ScriptObjectManager::syslist;
+
+int ScriptObjectManager::inited = 0;
diff --git a/Src/Wasabi/api/script/scriptmgr.h b/Src/Wasabi/api/script/scriptmgr.h
new file mode 100644
index 00000000..45b4775e
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptmgr.h
@@ -0,0 +1,81 @@
+#ifndef _SCRIPT_H
+#define _SCRIPT_H
+
+#include <api/script/objects/systemobj.h>
+#ifdef WASABI_COMPILE_CONFIG
+#include <api/script/objects/wacobj.h>
+#endif
+
+#define SOM ScriptObjectManager
+
+// This class should ONLY contain generic functions which don't have to be duplicated for each script layer !
+// This is why this is (mostly) a static class. Please DO NOT add anything which relates to function pointers,
+// variable tables, etc.
+
+
+class ScriptObjectManager {
+public:
+ ScriptObjectManager();
+ ~ScriptObjectManager();
+
+ static scriptVar makeVar(int type);
+ static scriptVar makeVar(int type, ScriptObject *o);
+ static void assign(scriptVar *v, const wchar_t *str);
+ static void assign(scriptVar *v, int i);
+ static void assign(scriptVar *v, float f);
+ static void assign(scriptVar *v, double d);
+ static void assign(scriptVar *v, ScriptObject *o);
+ static void assign(scriptVar *v1, scriptVar *v2);
+ static void assignPersistent(scriptVar *v1, scriptVar *v2);
+ static void strflatassign(scriptVar *v, const wchar_t *str);
+ static void persistentstrassign(scriptVar *v, const wchar_t *str);
+
+ static int compEq(scriptVar *v1, scriptVar *v2);
+ static int compNeq(scriptVar *v1, scriptVar *v2);
+ static int compA(scriptVar *v1, scriptVar *v2);
+ static int compAe(scriptVar *v1, scriptVar *v2);
+ static int compB(scriptVar *v1, scriptVar *v2);
+ static int compBe(scriptVar *v1, scriptVar *v2);
+
+ static void mid(wchar_t *dest, const wchar_t *str, int s, int l);
+
+ static int makeInt(scriptVar *v);
+ static float makeFloat(scriptVar *v);
+ static double makeDouble(scriptVar *v);
+ static bool makeBoolean(scriptVar *v);
+ static int isNumeric(scriptVar *s);
+ static int isString(scriptVar *s);
+ static int isVoid(scriptVar *s);
+ static int isObject(scriptVar *s);
+ static int isNumericType(int t);
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ static WACObject *getWACObject(const wchar_t *guid);
+ static WACObject *getWACObject(GUID cg);
+#endif
+ static SystemObject *getSystemObject(int n);
+ static SystemObject *getSystemObjectByScriptId(int id);
+
+ static void registerSystemObject(SystemObject *o);
+ static void unregisterSystemObject(SystemObject *o);
+ static int getNumSystemObjects();
+ static SystemObject *enumSystemObject(int n);
+ static int typeCheck(VCPUscriptVar *v, int fail = 1);
+ static WindowHolder *getSuitableWindowHolderFromScript(GUID g);
+ static int checkAbortShowHideWindow(GUID g, int visible);
+#ifdef WASABI_COMPILE_WND
+ static ScriptObject *findObject(const wchar_t *name);
+#endif
+
+private:
+
+ static SystemObject * system;
+ static PtrList < SystemObject > syslist;
+ static int inited;
+};
+
+#ifdef WASABI_COMPILE_COMPONENTS
+extern PtrList<WACObject> comps;
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/script/scriptobj.cpp b/Src/Wasabi/api/script/scriptobj.cpp
new file mode 100644
index 00000000..397d15bc
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobj.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:09:17 2003]
+//
+// File : scriptobj.cpp
+// Class : ScriptObject
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "scriptobj.h"
+
+
diff --git a/Src/Wasabi/api/script/scriptobj.h b/Src/Wasabi/api/script/scriptobj.h
new file mode 100644
index 00000000..8286bfb9
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobj.h
@@ -0,0 +1,139 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:09:17 2003]
+//
+// File : scriptobj.h
+// Class : ScriptObject
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __SCRIPTOBJECT_H
+#define __SCRIPTOBJECT_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+class ScriptHook;
+class ScriptObject;
+class ScriptObjectController;
+
+enum {
+ INTERFACE_GENERICVOIDPTR=0,
+ INTERFACE_SCRIPTOBJECT,
+};
+
+// ----------------------------------------------------------------------------
+
+class ScriptObject: public Dispatchable {
+ protected:
+ ScriptObject() {}
+ ~ScriptObject() {}
+ public:
+ void *vcpu_getInterface(GUID g, int *interfacetype = NULL);
+ void *vcpu_getInterfaceObject(GUID g, ScriptObject **o);
+ int vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent);
+ void vcpu_removeAssignedVariable(int var, int id);
+ void vcpu_addAssignedVariable(int var, int scriptid);
+ const wchar_t *vcpu_getClassName();
+ ScriptObjectController *vcpu_getController();
+ int vcpu_getScriptId();
+ void vcpu_setScriptId(int i);
+ int vcpu_getMember(const wchar_t *id, int scriptid, int rettype);
+ void vcpu_delMembers(int scriptid);
+ void vcpu_setInterface(GUID g, void *v, int interfacetype = INTERFACE_SCRIPTOBJECT);
+ void vcpu_setClassName(const wchar_t *name);
+ void vcpu_setController(ScriptObjectController *c);
+ void vcpu_init();
+
+ protected:
+ enum {
+ SCRIPTOBJECT_VCPU_GETINTERFACE = 50,
+ SCRIPTOBJECT_VCPU_GETINTERFACEOBJECT = 60,
+ SCRIPTOBJECT_VCPU_GETASSIGNEDVARIABLE = 100,
+ SCRIPTOBJECT_VCPU_REMOVEASSIGNEDVARIABLE = 200,
+ SCRIPTOBJECT_VCPU_ADDASSIGNEDVARIABLE = 300,
+ SCRIPTOBJECT_VCPU_GETCLASSNAME = 400,
+ SCRIPTOBJECT_VCPU_GETCONTROLLER = 500,
+ SCRIPTOBJECT_VCPU_ADDCLASSHOOK = 600,
+ SCRIPTOBJECT_VCPU_ADDOBJECTHOOK = 700,
+ SCRIPTOBJECT_VCPU_GETSCRIPTID = 800,
+ SCRIPTOBJECT_VCPU_SETSCRIPTID = 900,
+ SCRIPTOBJECT_VCPU_GETMEMBER = 1000,
+ SCRIPTOBJECT_VCPU_DELMEMBERS = 1100,
+ SCRIPTOBJECT_VCPU_SETINTERFACE = 1200,
+ SCRIPTOBJECT_VCPU_SETCLASSNAME = 1300,
+ SCRIPTOBJECT_VCPU_SETCONTROLLER = 1400,
+ SCRIPTOBJECT_VCPU_INIT = 1500,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline void *ScriptObject::vcpu_getInterface(GUID g, int *interfacetype) {
+ void *__retval = _call(SCRIPTOBJECT_VCPU_GETINTERFACE, (void *)NULL, g, interfacetype);
+ return __retval;
+}
+
+inline void *ScriptObject::vcpu_getInterfaceObject(GUID g, ScriptObject **o) {
+ void *__retval = _call(SCRIPTOBJECT_VCPU_GETINTERFACEOBJECT, (void *)NULL, g, o);
+ return __retval;
+}
+
+inline int ScriptObject::vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent) {
+ int __retval = _call(SCRIPTOBJECT_VCPU_GETASSIGNEDVARIABLE, (int)0, start, scriptid, functionId, next, globalevententry, inheritedevent);
+ return __retval;
+}
+
+inline void ScriptObject::vcpu_removeAssignedVariable(int var, int id) {
+ _voidcall(SCRIPTOBJECT_VCPU_REMOVEASSIGNEDVARIABLE, var, id);
+}
+
+inline void ScriptObject::vcpu_addAssignedVariable(int var, int scriptid) {
+ _voidcall(SCRIPTOBJECT_VCPU_ADDASSIGNEDVARIABLE, var, scriptid);
+}
+
+inline const wchar_t *ScriptObject::vcpu_getClassName() {
+ return _call(SCRIPTOBJECT_VCPU_GETCLASSNAME, (const wchar_t *)0);
+}
+
+inline ScriptObjectController *ScriptObject::vcpu_getController() {
+ ScriptObjectController *__retval = _call(SCRIPTOBJECT_VCPU_GETCONTROLLER, (ScriptObjectController *)NULL);
+ return __retval;
+}
+
+inline int ScriptObject::vcpu_getScriptId() {
+ int __retval = _call(SCRIPTOBJECT_VCPU_GETSCRIPTID, (int)0);
+ return __retval;
+}
+
+inline void ScriptObject::vcpu_setScriptId(int i) {
+ _voidcall(SCRIPTOBJECT_VCPU_SETSCRIPTID, i);
+}
+
+inline int ScriptObject::vcpu_getMember(const wchar_t *id, int scriptid, int rettype) {
+ int __retval = _call(SCRIPTOBJECT_VCPU_GETMEMBER, (int)0, id, scriptid, rettype);
+ return __retval;
+}
+
+inline void ScriptObject::vcpu_delMembers(int scriptid) {
+ _voidcall(SCRIPTOBJECT_VCPU_DELMEMBERS, scriptid);
+}
+
+inline void ScriptObject::vcpu_setInterface(GUID g, void *v, int interfacetype) {
+ _voidcall(SCRIPTOBJECT_VCPU_SETINTERFACE, g, v, interfacetype);
+}
+
+inline void ScriptObject::vcpu_setClassName(const wchar_t *name) {
+ _voidcall(SCRIPTOBJECT_VCPU_SETCLASSNAME, name);
+}
+
+inline void ScriptObject::vcpu_setController(ScriptObjectController *c) {
+ _voidcall(SCRIPTOBJECT_VCPU_SETCONTROLLER, c);
+}
+
+inline void ScriptObject::vcpu_init() {
+ _voidcall(SCRIPTOBJECT_VCPU_INIT);
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __SCRIPTOBJECT_H
diff --git a/Src/Wasabi/api/script/scriptobji.cpp b/Src/Wasabi/api/script/scriptobji.cpp
new file mode 100644
index 00000000..f9cbef46
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobji.cpp
@@ -0,0 +1,305 @@
+#include "api.h"
+#include <api/script/scriptobji.h>
+#include <api/script/objcontroller.h>
+#include <api/script/scriptguid.h>
+
+ScriptObjectI::ScriptObjectI(const wchar_t *class_name, ScriptObjectController *object_controller)
+{
+ classname = class_name;
+ controller = object_controller;
+ cache_count = -1;
+ membercachegid = -1;
+ membercachesid = -1;
+ ingetinterface = 0;
+ vcpu_init();
+}
+
+ScriptObjectI::~ScriptObjectI()
+{
+ assignedVariables.deleteAll();
+ memberVariables.deleteAll();
+ interfaceslist.deleteAll();
+ WASABI_API_MAKI->vcpu_removeScriptObject(this);
+}
+
+void *ScriptObjectI::vcpu_getInterface(GUID g, int *interfacetype)
+{
+ if (g == scriptObjectGuid) return this;
+ InterfaceEntry *entry = 0;
+ int n=0;
+ while (entry = interfaceslist.enumItem(n++))
+ {
+ if (entry->getGuid() == g)
+ {
+ if (interfacetype != NULL)
+ *interfacetype = entry->getType();
+ return entry->getInterface();
+ }
+ }
+
+ if (ingetinterface) return NULL;
+ ingetinterface = 1;
+
+ void *i = NULL;
+ ScriptObjectController *c = controller;
+ //CUT: ScriptObject *no = NULL;
+ while (i == NULL && c != NULL)
+ {
+ i = c->cast(this, g);
+ if (i != NULL) break;
+ c = c->getAncestorController();
+ }
+
+ if (interfacetype != NULL)
+ *interfacetype = INTERFACE_SCRIPTOBJECT;
+ ingetinterface = 0;
+ return i;
+}
+
+void *ScriptObjectI::vcpu_getInterfaceObject(GUID g, ScriptObject **o)
+{
+ if (g == scriptObjectGuid) return this;
+ InterfaceEntry *entry = 0;
+ int n=0;
+ while (entry = interfaceslist.enumItem(n++))
+ {
+ if (entry && entry->getGuid() == g)
+ {
+ *o = NULL;
+ return entry->getInterface();
+ }
+ }
+ if (ingetinterface) return NULL;
+ ingetinterface = 1;
+
+ void *i = NULL;
+ ScriptObjectController *c = controller;
+ //CUT: ScriptObject *no = NULL;
+ while (i == NULL && c != NULL)
+ {
+ i = c->cast(this, g);
+ if (i != NULL)
+ {
+ if (o != NULL)
+ *o = (ScriptObject *)i;
+ break;
+ }
+ c = c->getAncestorController();
+ }
+
+ ingetinterface = 0;
+ return i;
+}
+
+int ScriptObjectI::vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent)
+{
+ if (start < 0) start = 0;
+ if (start >= assignedVariables.getNumItems()) return -1;
+ for (int i = start;i < assignedVariables.getNumItems();i++)
+ {
+ assvar *v = assignedVariables.enumItem(i);
+ if (WASABI_API_MAKI->vcpu_getCacheCount() != cache_count)
+ {
+ if (!WASABI_API_MAKI->vcpu_isValidScriptId(v->scriptid))
+ {
+ vcpu_removeAssignedVariable(v->varid, v->scriptid);
+ i--;
+ continue;
+ }
+ }
+ if (scriptid == -1 || v->scriptid == scriptid)
+ {
+ int r = getEventForVar(v, functionId, inheritedevent);
+ if (r == -1) continue;
+ if (next) *next = i + 1;
+ if (globalevententry) *globalevententry = r;
+ return WASABI_API_MAKI->vcpu_mapVarId(v->varid, v->scriptid);
+ }
+ }
+ return -1;
+}
+
+void ScriptObjectI::vcpu_removeAssignedVariable(int var, int id)
+{
+ for (int i = 0;i < assignedVariables.getNumItems();i++)
+ {
+ assvar *v = assignedVariables.enumItem(i);
+ if (v->varid == var && v->scriptid == id)
+ {
+ delete v;
+ assignedVariables.removeItem(v);
+ return ;
+ }
+ }
+}
+
+void ScriptObjectI::vcpu_addAssignedVariable(int var, int scriptid)
+{
+ do
+ {
+ assvar *v = new assvar;
+ v->scriptid = scriptid;
+ v->varid = var;
+ assignedVariables.addItem(v);
+ computeEventList(v);
+ var = WASABI_API_MAKI->vcpu_getUserAncestorId(var, scriptid);
+ }
+ while (var != -1);
+}
+
+const wchar_t *ScriptObjectI::vcpu_getClassName()
+{
+ return classname;
+}
+
+ScriptObjectController *ScriptObjectI::vcpu_getController()
+{
+ return controller;
+}
+
+int ScriptObjectI::vcpu_getScriptId()
+{
+ return id;
+}
+
+void ScriptObjectI::vcpu_setScriptId(int i)
+{
+ id = i;
+}
+
+int ScriptObjectI::vcpu_getMember(const wchar_t *id, int scriptid, int rettype)
+{
+ if (membercachesid == scriptid && !WCSICMP(membercacheid, id))
+ return membercachegid;
+ membercacheid = id;
+ membercachesid = scriptid;
+ for (int i = 0;i < memberVariables.getNumItems();i++)
+ {
+ MemberVar *m = memberVariables.enumItem(i);
+ if (m->getScriptId() == scriptid && !WCSICMP(m->getName(), id))
+ {
+ membercachegid = m->getGlobalId();
+ return membercachegid;
+ }
+ }
+ MemberVar *m = new MemberVar(id, scriptid, rettype);
+ memberVariables.addItem(m);
+ membercachegid = m->getGlobalId();
+ return membercachegid;
+}
+
+void ScriptObjectI::vcpu_delMembers(int scriptid)
+{
+ for (int i = 0;i < memberVariables.getNumItems();i++)
+ if (memberVariables.enumItem(i)->getScriptId() == scriptid)
+ {
+ delete memberVariables.enumItem(i);
+ memberVariables.removeByPos(i--);
+ }
+}
+
+void ScriptObjectI::vcpu_setInterface(GUID g, void *v, int interfacetype)
+{
+ for (int i = 0;i < interfaceslist.getNumItems();i++)
+ if (interfaceslist.enumItem(i)->getGuid() == g)
+ {
+ InterfaceEntry *p = interfaceslist.enumItem(i);
+ delete p;
+ interfaceslist.removeByPos(i);
+ i--;
+ }
+ interfaceslist.addItem(new InterfaceEntry(g, v, interfacetype));
+}
+
+void ScriptObjectI::vcpu_setClassName(const wchar_t *name)
+{
+ classname = name;
+}
+
+void ScriptObjectI::vcpu_setController(ScriptObjectController *c)
+{
+ controller = c;
+}
+
+void ScriptObjectI::vcpu_init()
+{
+ WASABI_API_MAKI->vcpu_addScriptObject(this);
+}
+
+int ScriptObjectI::getEventForVar(assvar *var, int funcid, int *inheritedevent)
+{
+ if (WASABI_API_MAKI->vcpu_getCacheCount() != cache_count)
+ {
+ for (int i = 0;i < assignedVariables.getNumItems();i++)
+ {
+ assvar* ass = assignedVariables.enumItem(i);
+ // Martin> We need to ensure here that a valid script is called
+ // There are a few circumstances where the script is already deleted from SOM but we want to call it.
+ // Example: onMouseWheelDown() in a script embedded in a customobject and another script.
+ // another script can hide the customobject and thus the custom object's embedded script gets unloaded.
+ // the old scriptID is still cached and wants to be invoked! this will lead to an guru but the guru cannot be thrown
+ // since the ScriptID isn't valid anymore. this leads to a nullpointer assert crash.
+ if (!WASABI_API_MAKI->vcpu_isValidScriptId(ass->scriptid))
+ {
+ continue;
+ }
+ computeEventList(ass);
+ }
+ cache_count = WASABI_API_MAKI->vcpu_getCacheCount();
+ }
+ TList<int> *list = &var->dlfs;
+ for (int i = 0;i < list->getNumItems();i += 4)
+ if (list->enumItem(i) == funcid && list->enumItem(i + 1) == var->varid)
+ {
+ *inheritedevent = list->enumItem(i + 3);
+ return list->enumItem(i + 2);
+ }
+
+ return -1;
+}
+
+void ScriptObjectI::computeEventList(assvar *a)
+{
+ a->dlfs.removeAll();
+
+ int dlfid;
+ int scriptid;
+ int varid;
+
+ int var = a->varid;
+ int inheritedevent = 0;
+
+ do
+ {
+ for (int i = 0;i < WASABI_API_MAKI->vcpu_getNumEvents();i++)
+ {
+ WASABI_API_MAKI->vcpu_getEvent(i, &dlfid, &scriptid, &varid);
+ if (scriptid == a->scriptid && varid == var)
+ {
+ a->dlfs.addItem(dlfid);
+ a->dlfs.addItem(varid);
+ a->dlfs.addItem(i);
+ a->dlfs.addItem(inheritedevent);
+ }
+ }
+ var = WASABI_API_MAKI->vcpu_getUserAncestorId(var, a->scriptid);
+ inheritedevent = 1;
+ }
+ while (var != -1);
+}
+
+
+
+ScriptObjectI::MemberVar::MemberVar(const wchar_t *_name, int _scriptid, int _rettype)
+{
+ name = _name;
+ rettype = _rettype;
+ scriptid = _scriptid;
+ globalid = WASABI_API_MAKI->maki_createOrphan(rettype);
+}
+
+ScriptObjectI::MemberVar::~MemberVar()
+{
+ WASABI_API_MAKI->maki_killOrphan(globalid); // heh :)
+}
+
diff --git a/Src/Wasabi/api/script/scriptobji.h b/Src/Wasabi/api/script/scriptobji.h
new file mode 100644
index 00000000..2a2aaf77
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobji.h
@@ -0,0 +1,134 @@
+#ifndef __SCRIPTOBJI_H
+#define __SCRIPTOBJI_H
+
+#include <api/script/vcputypes.h>
+#include <bfc/dispatch.h>
+
+#include <bfc/tlist.h>
+#include <bfc/ptrlist.h>
+#include <bfc/pair.h>
+
+//<?<autoheader/>
+#include "scriptobj.h"
+#include "scriptobjx.h"
+
+class ScriptHook;
+class ScriptObject;
+class ScriptObjectController;
+
+//?>
+
+
+class ScriptObjectController;
+class ScriptHook;
+
+/*[interface.header.h]
+enum {
+ INTERFACE_GENERICVOIDPTR=0,
+ INTERFACE_SCRIPTOBJECT,
+};
+*/
+
+// ----------------------------------------------------------------------------------------------------------
+
+/*class MemberVarCompare {
+ public:
+ static int compareItem(void *p1, void *p2);
+ static int compareAttrib(const wchar_t *attrib, void *p);
+};*/
+
+// ----------------------------------------------------------------------------------------------------------
+
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+
+class ScriptObjectI : public ScriptObjectX
+{
+private:
+ /* These three classes are here to ensure they don't get used anywhere else */
+ struct assvar
+ {
+ int scriptid;
+ int varid;
+ TList<int> dlfs;
+ };
+
+ class InterfaceEntry
+ {
+ public:
+ InterfaceEntry(GUID _guid, void *_ptr, int _type = INTERFACE_GENERICVOIDPTR) : guid(_guid), ptr(_ptr), type(_type) {}
+ virtual ~InterfaceEntry() {}
+
+ virtual GUID getGuid() { return guid; }
+ virtual void *getInterface() { return ptr; }
+ virtual int getType() { return type; }
+
+ private:
+
+ GUID guid;
+ void *ptr;
+ int type;
+};
+
+ class MemberVar
+ {
+ public:
+ MemberVar(const wchar_t *name, int scriptid, int rettype);
+ virtual ~MemberVar();
+
+ const wchar_t *getName() { return name; }
+ int getScriptId() { return scriptid; }
+ int getReturnType() { return rettype; }
+ int getGlobalId() { return globalid; }
+
+ private:
+ StringW name;
+ int scriptid;
+ int rettype;
+ int globalid;
+};
+
+
+public:
+ ScriptObjectI(const wchar_t *class_name = NULL, ScriptObjectController *object_controller = NULL);
+ virtual ~ScriptObjectI();
+
+ DISPATCH(50) virtual void *vcpu_getInterface(GUID g, int *interfacetype = NULL);
+ DISPATCH(60) virtual void *vcpu_getInterfaceObject(GUID g, ScriptObject **o);
+ DISPATCH(100) int vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent);
+ DISPATCH(200) void vcpu_removeAssignedVariable(int var, int id);
+ DISPATCH(300) void vcpu_addAssignedVariable(int var, int scriptid);
+ DISPATCH(400) virtual const wchar_t *vcpu_getClassName();
+ DISPATCH(500) virtual ScriptObjectController *vcpu_getController();
+// DISPATCH(600) virtual void vcpu_addClassHook(ScriptHook *h);
+// DISPATCH(700) virtual void vcpu_addObjectHook(ScriptHook *h);
+ DISPATCH(800) int vcpu_getScriptId();
+ DISPATCH(900) void vcpu_setScriptId(int i);
+ DISPATCH(1000) int vcpu_getMember(const wchar_t *id, int scriptid, int rettype);
+ DISPATCH(1100) void vcpu_delMembers(int scriptid);
+ DISPATCH(1200) virtual void vcpu_setInterface(GUID g, void *v, int interfacetype = INTERFACE_SCRIPTOBJECT);
+ DISPATCH(1300) virtual void vcpu_setClassName(const wchar_t *name);
+ DISPATCH(1400) virtual void vcpu_setController(ScriptObjectController *c);
+ DISPATCH(1500) virtual void vcpu_init();
+
+protected:
+ NODISPATCH int getEventForVar(assvar *var, int funcid, int *inheritedevent);
+ NODISPATCH void computeEventList(assvar *a);
+ PtrList < assvar > assignedVariables;
+ PtrList < MemberVar > memberVariables;
+ int cache_count;
+ int id;
+ StringW membercacheid;
+ int membercachesid;
+ int membercachegid;
+ PtrList < InterfaceEntry > interfaceslist;
+ const wchar_t *classname;
+ ScriptObjectController * controller;
+ int ingetinterface;
+
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/scriptobjx.cpp b/Src/Wasabi/api/script/scriptobjx.cpp
new file mode 100644
index 00000000..e9a0bbcb
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobjx.cpp
@@ -0,0 +1,34 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:09:18 2003]
+//
+// File : scriptobjx.cpp
+// Class : ScriptObject
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include "scriptobjx.h"
+#include "scriptobji.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS ScriptObjectX
+START_DISPATCH;
+ CB(SCRIPTOBJECT_VCPU_GETINTERFACE, vcpu_getInterface);
+ CB(SCRIPTOBJECT_VCPU_GETINTERFACEOBJECT, vcpu_getInterfaceObject);
+ CB(SCRIPTOBJECT_VCPU_GETASSIGNEDVARIABLE, vcpu_getAssignedVariable);
+ VCB(SCRIPTOBJECT_VCPU_REMOVEASSIGNEDVARIABLE, vcpu_removeAssignedVariable);
+ VCB(SCRIPTOBJECT_VCPU_ADDASSIGNEDVARIABLE, vcpu_addAssignedVariable);
+ CB(SCRIPTOBJECT_VCPU_GETCLASSNAME, vcpu_getClassName);
+ CB(SCRIPTOBJECT_VCPU_GETCONTROLLER, vcpu_getController);
+ CB(SCRIPTOBJECT_VCPU_GETSCRIPTID, vcpu_getScriptId);
+ VCB(SCRIPTOBJECT_VCPU_SETSCRIPTID, vcpu_setScriptId);
+ CB(SCRIPTOBJECT_VCPU_GETMEMBER, vcpu_getMember);
+ VCB(SCRIPTOBJECT_VCPU_DELMEMBERS, vcpu_delMembers);
+ VCB(SCRIPTOBJECT_VCPU_SETINTERFACE, vcpu_setInterface);
+ VCB(SCRIPTOBJECT_VCPU_SETCLASSNAME, vcpu_setClassName);
+ VCB(SCRIPTOBJECT_VCPU_SETCONTROLLER, vcpu_setController);
+ VCB(SCRIPTOBJECT_VCPU_INIT, vcpu_init);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/script/scriptobjx.h b/Src/Wasabi/api/script/scriptobjx.h
new file mode 100644
index 00000000..b34fc4ad
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobjx.h
@@ -0,0 +1,44 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:09:17 2003]
+//
+// File : scriptobjx.h
+// Class : ScriptObject
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __SCRIPTOBJECTX_H
+#define __SCRIPTOBJECTX_H
+
+#include "scriptobj.h"
+
+class ScriptHook;
+class ScriptObject;
+class ScriptObjectController;
+
+// ----------------------------------------------------------------------------
+
+class ScriptObjectX : public ScriptObject {
+ protected:
+ ScriptObjectX() {}
+ public:
+ virtual void *vcpu_getInterface(GUID g, int *interfacetype = NULL)=0;
+ virtual void *vcpu_getInterfaceObject(GUID g, ScriptObject **o)=0;
+ virtual int vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent)=0;
+ virtual void vcpu_removeAssignedVariable(int var, int id)=0;
+ virtual void vcpu_addAssignedVariable(int var, int scriptid)=0;
+ virtual const wchar_t *vcpu_getClassName()=0;
+ virtual ScriptObjectController *vcpu_getController()=0;
+ virtual int vcpu_getScriptId()=0;
+ virtual void vcpu_setScriptId(int i)=0;
+ virtual int vcpu_getMember(const wchar_t *id, int scriptid, int rettype)=0;
+ virtual void vcpu_delMembers(int scriptid)=0;
+ virtual void vcpu_setInterface(GUID g, void *v, int interfacetype = INTERFACE_SCRIPTOBJECT)=0;
+ virtual void vcpu_setClassName(const wchar_t *name)=0;
+ virtual void vcpu_setController(ScriptObjectController *c)=0;
+ virtual void vcpu_init()=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __SCRIPTOBJECTX_H
diff --git a/Src/Wasabi/api/script/scriptvar.h b/Src/Wasabi/api/script/scriptvar.h
new file mode 100644
index 00000000..0b225a50
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptvar.h
@@ -0,0 +1,35 @@
+#ifndef __SCRIPTVAR_H
+#define __SCRIPTVAR_H
+
+#ifdef __cplusplus
+ class ScriptObject;
+#endif
+
+#ifdef _MSC_VER
+#pragma pack(push, 1)
+#else
+#pragma pack(1)
+#endif
+
+typedef struct {
+ int type; // basic type, see above
+ union { // union of 4 bytes of different types
+ int idata; // Integer
+ float fdata; // Float
+ double ddata; // Double
+#ifdef __cplusplus
+ ScriptObject *odata; // Object
+#else
+ void *odata;
+#endif
+ const wchar_t *sdata; // String
+ } data;
+} scriptVar;
+
+#ifdef _MSC_VER
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif
+
+#endif
diff --git a/Src/Wasabi/api/script/vcpu.cpp b/Src/Wasabi/api/script/vcpu.cpp
new file mode 100644
index 00000000..1002ee57
--- /dev/null
+++ b/Src/Wasabi/api/script/vcpu.cpp
@@ -0,0 +1,2069 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include <api/skin/widgets/mb/scriptbrowser.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/script.h>
+#include "vcpu.h"
+#include "opcodes.h"
+#include <api/wndmgr/container.h>
+#include <api/wndmgr/msgbox.h>
+#include <api/script/objecttable.h>
+#include <api/syscb/callbacks/consolecb.h>
+#include "../nu/AutoWide.h"
+
+ScriptObjectManager *VCPU::scriptManager = NULL;
+
+void VCPU::shutdown()
+{
+ foreach(globalDlfList)
+ FREE(globalDlfList.getfor()->functionName);
+ delete globalDlfList.getfor();
+ endfor
+ globalDlfList.removeAll();
+ atoms.deleteAll();
+}
+
+// -------------------------------------------------------------
+void VCPU::push(VCPUscriptVar v) {
+ CpuStack.push(v);
+ VSP++;
+}
+
+// -------------------------------------------------------------
+void VCPU::push(scriptVar v) {
+ VCPUscriptVar _v;
+ _v.v = v;
+ CpuStack.push(_v);
+ VSP++;
+}
+
+void VCPU::RemoveOldScripts()
+{
+ while (scriptsToRemove.getNumItems())
+ {
+ int id = scriptsToRemove.getFirst();
+ VCPU::removeScript(id);
+ scriptsToRemove.delByPos(0);
+ }
+}
+
+// -------------------------------------------------------------
+VCPUscriptVar VCPU::pop() {
+ if (VSP <= 0) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_POPEMPTYSTACK);
+ VCPUscriptVar v;
+ MEMSET(&v, 0, sizeof(v));
+ return v;
+// ASSERT(0);
+ }
+ VCPUscriptVar v;
+ CpuStack.pop(&v);
+ VSP--;
+ if (VSP == 0)
+ VCPU::RemoveOldScripts(); // benski> TODO: dunno if this is the best place for this
+ return v;
+}
+
+// -------------------------------------------------------------
+VCPUscriptVar VCPU::peekAt(int n) {
+ if (VSP <= n) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_INVALIDPEEKSTACK);
+ VCPUscriptVar v;
+ MEMSET(&v, 0, sizeof(v));
+ return v;
+// ASSERT(0);
+ }
+ VCPUscriptVar v={0,{0},0};
+ CpuStack.peekAt(&v, n);
+ return v;
+}
+
+// -------------------------------------------------------------
+int VCPU::assignNewScriptId() {
+ return numScripts++;
+}
+
+// -------------------------------------------------------------
+int VCPU::oldClassToClassId(int id) {
+ if (id < SCRIPT_OBJECT) return id;
+ if (id >= 0x10000) return id;
+ switch (id) {
+ case 7 : return ObjectTable::getClassFromName(L"Object");
+ case 8 : return ObjectTable::getClassFromName(L"SystemObject");
+ case 9 : return ObjectTable::getClassFromName(L"Container");
+ case 10: return ObjectTable::getClassFromName(L"Layout");
+ case 11: return ObjectTable::getClassFromName(L"Button");
+ case 12: return ObjectTable::getClassFromName(L"Slider");
+ case 13: return ObjectTable::getClassFromName(L"Text");
+ case 14: return ObjectTable::getClassFromName(L"Image");
+ case 15: return ObjectTable::getClassFromName(L"Anim");
+ case 16: return ObjectTable::getClassFromName(L"Vis");
+ case 17: return ObjectTable::getClassFromName(L"Component");
+ case 18: return ObjectTable::getClassFromName(L"ToggleButton");
+ case 19: return ObjectTable::getClassFromName(L"Timer");
+ case 20: return ObjectTable::getClassFromName(L"Layer");
+ case 21: return ObjectTable::getClassFromName(L"GuiObject");
+ case 22: return ObjectTable::getClassFromName(L"AnimatedLayer");
+ case 23: return ObjectTable::getClassFromName(L"Browser");
+ case 24: return ObjectTable::getClassFromName(L"Edit");
+ case 25: return ObjectTable::getClassFromName(L"Map");
+ case 26: return ObjectTable::getClassFromName(L"Popup");
+ case 27: return ObjectTable::getClassFromName(L"Title");
+ case 28: return ObjectTable::getClassFromName(L"ComponentBucket");
+ case 29: return ObjectTable::getClassFromName(L"Status");
+ case 30: return ObjectTable::getClassFromName(L"Region");
+ case 31: return ObjectTable::getClassFromName(L"Wac");
+ case 32: return ObjectTable::getClassFromName(L"List");
+ case 33: return ObjectTable::getClassFromName(L"SBitList");
+ case 34: return ObjectTable::getClassFromName(L"SEqVis");
+ default: Script::guruMeditation(NULL, GURU_INVALIDOLDID, L"xlat error", id);
+ break;
+ }
+ return SCRIPT_INT; // heh =)
+}
+
+
+// -------------------------------------------------------------
+int VCPU::addScript(void *mem, int memsize, int id) {
+
+ int i,j;
+ int translateobjects = 0;
+
+ char *p = (char *)mem;
+
+ int hdr=0;
+ if (!MEMCMP(p, "FG\x03\x04\x14\00\00\00\00", 8))
+ hdr=1;
+ else if (!MEMCMP(p, "FG\x03\x04\x15\00\00\00\00", 8))
+ hdr=2;
+ else if (!MEMCMP(p, "FG\x03\x04\x16\00\00\00\00", 8))
+ hdr=3;
+ else if (!MEMCMP(p, "FG\x03\x04\x17\00\00\00\00", 8))
+ hdr=4;
+ else if (!MEMCMP(p, "FG\x03\x04", 4)) {
+ if (*(p+4) > 0x17)
+ hdr = -1;
+ }
+
+ switch (hdr) {
+ case -1:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_FUTUREFORMAT, L"NEED LATEST VERSION");
+ return -1;
+ case 0:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDHEADER);
+ return -1;
+ case 1:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_OLDFORMAT, L"DEPRECATED BINARY");
+ return -1;
+ case 2:
+ translateobjects=1;
+ break;
+ case 3:
+ case 4:
+ break;
+ }
+
+ SOM::getSystemObjectByScriptId(id)->setIsOldFormat(translateobjects);
+
+ p+=8;
+
+ TList<int> *typetable = SOM::getSystemObjectByScriptId(id)->getTypesList();
+ typetable->removeAll();
+
+ if (!translateobjects) {
+
+ int nGuids = *(int *)p;
+ p+=sizeof(int);
+
+ for (int z=0;z<nGuids;z++) {
+ GUID g;
+ MEMCPY(&g, p, sizeof(GUID));
+ p+=sizeof(GUID);
+ char zz[256] = {0};
+ nsGUID::toChar(g, zz);
+ int t = ObjectTable::getClassFromGuid(g);
+ if (t == -1) {
+ DebugStringW(L"maki class entry %d not found : %s\n", z, zz);
+// __asm int 3;
+ }
+ typetable->addItem(t);
+ }
+ }
+
+ // -------------------------------------------------------------
+ // Load DLF Table
+
+ int DLFEntryBase = DLFentryTable.getNumItems();
+
+ int nDLFentries = *(int *)p;
+ p+=sizeof(int);
+
+ for (i=0;i<nDLFentries;i++) {
+
+ int basetype = *(int *)p;
+ int pt = basetype;
+ int type = basetype;
+ p+=sizeof(int);
+
+ if (translateobjects) {
+ basetype = oldClassToClassId(basetype);
+ } else
+ if (basetype >= CLASS_ID_BASE && basetype < 0x10000)
+ basetype = typetable->enumItem(basetype - CLASS_ID_BASE);
+
+ if (basetype == -1) {
+//CUT!!!! so annoying Std::messageBox("Error while loading a script, a component is missing", "Oops", 0);
+ DebugStringW(L"Tried to link DLF %d (class entry %d) but the class isn't here\n", i, pt - CLASS_ID_BASE);
+ //return -1;
+ }
+
+ type = basetype;
+
+ uint16_t stringLen = *(uint16_t *)p;
+ p+=sizeof(uint16_t);
+ char functionName[65536+1] = {0};
+ MEMCPY(functionName, p, stringLen);
+ functionName[stringLen]=0;
+ p+=stringLen;
+
+ // check if entry seems valid
+
+ if (!*functionName) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDFUNCINDLF);
+// api->messageBox("Invalid function name in DLF table", "Script Error", MSGBOX_OK, NULL, NULL);
+ return -1;
+ }
+
+ // ok, register this function
+ VCPUdlfEntry *e = new VCPUdlfEntry;
+ e->basetype = type;
+#ifdef _WIN32
+ int size = MultiByteToWideChar(CP_UTF8, 0, functionName, -1, 0,0);
+ if (size)
+ {
+ wchar_t *wide = (wchar_t *)MALLOC(size*sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, functionName, -1, wide,size);
+ e->functionName = wide;
+ }
+ else
+ e->functionName = 0;
+#else
+ e->functionName = WCSDUP(AutoWide(functionName));
+#warning port me
+#endif
+ e->scriptId = id;
+ // insert safe values
+ e->nparams = -1;
+ e->DLFid = -1;
+ e->ptr = NULL;
+ DLFentryTable.addItem(e);
+
+ setupDLF(e, DLFEntryBase);
+
+ }
+
+ // -------------------------------------------------------------
+ // Load VAR Table
+
+ int variableBase = variablesTable.getNumItems();
+
+ int nVariables = *(int *)p;
+ p+=sizeof(int);
+
+ for (i=0;i<nVariables;i++) {
+ scriptVar e;
+ MEMCPY(&e, p, sizeof(scriptVar));
+ p+=sizeof(scriptVar);
+
+ VCPUscriptVar *v = new VCPUscriptVar;
+ v->isaclass = 0;
+
+ if (e.type >= 0x10000) {
+ int type = e.type;
+ int id;
+
+ do {
+ id = type - 0x10000;
+ VCPUscriptVar *v = variablesTable.enumItem(id+variableBase);
+ v->isaclass = 1;
+ type = v->v.type;
+ } while (type >= 0x10000);
+
+ }
+
+ if (translateobjects) {
+ e.type = oldClassToClassId(e.type);
+ } else
+ if (e.type >= CLASS_ID_BASE && e.type < 0x10000)
+ e.type = typetable->enumItem(e.type - CLASS_ID_BASE);
+
+ v->scriptId = id;
+ v->varId = i;
+ v->transcient = (*p++ == 0);
+ if (hdr >= 4)
+ v->isstatic = *p++;
+ else
+ v->isstatic = 0;
+
+ if (hdr < 4) {
+ // Autoassign system variables
+ if (e.type == ObjectTable::getClassFromName(L"SystemObject")) {
+ SystemObject *so = SOM::getSystemObjectByScriptId(id);
+ if (so) e.data.odata = so->getScriptObject(); else e.data.odata = NULL;
+ }
+ } else {
+ if (v->isstatic && e.type == ObjectTable::getClassFromName(L"SystemObject")) {
+ SystemObject *so = SOM::getSystemObjectByScriptId(id);
+ if (so) e.data.odata = so->getScriptObject(); else e.data.odata = NULL;
+ v->isstatic = 0; // disable deletion
+ } else if (v->isstatic) {
+ // Autoassign class variables
+ e.data.odata = ObjectTable::instantiate(e.type);
+ if (e.data.odata)
+ e.data.odata->vcpu_setScriptId(VSD);
+ }
+ }
+
+ if (e.type == SCRIPT_STRING)
+ {
+ wchar_t *emptyString = WMALLOC(1);
+ emptyString[0]=0;
+ e.data.sdata = emptyString;
+ }
+
+ if (e.type == SCRIPT_DOUBLE)
+ e.data.ddata = e.data.fdata;
+
+ v->v = e;
+ variablesTable.addItem(v);
+ }
+
+ // -------------------------------------------------------------
+ // Load Strings into string vars
+
+ int nStrings = *(int *)p;
+ p+=sizeof(int);
+
+ j=0;
+ //CUT: int count=0;
+
+ char string_buf[65536+1] = {0};
+ for (i=0;i<nStrings;i++)
+ {
+ int attach_id = *(int *)p;
+ p+=4;
+ uint16_t stringLen = *(uint16_t *)p;
+ p+=2;
+ //char *string;
+ //string = (char *)MALLOC(stringLen+1);
+ MEMCPY(string_buf, p, stringLen);
+ string_buf[stringLen]=0;
+ p+=stringLen;
+
+ // find next variable in this script that needs a string attached, and attach it
+ VCPUscriptVar *v = variablesTable.enumItem(attach_id+variableBase);
+ if (!v)
+ {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_EXCEPTION, L"Invalid String ID");
+ return -1;
+ }
+ FREE((wchar_t *)(v->v.data.sdata));
+ // strings are stored in UTF-8, but we're using UTF-16 here
+#ifdef _WIN32
+ int size = MultiByteToWideChar(CP_UTF8, 0, string_buf, -1, 0,0);
+ if (size)
+ {
+ wchar_t *wide = (wchar_t *)MALLOC(size*sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, string_buf, -1, wide,size);
+ v->v.data.sdata = wide;
+ }
+ else
+ v->v.data.sdata = 0;
+
+#else
+#warning port me
+ // TODO: benski> change to do one malloc
+ v->v.data.sdata = WCSDUP(AutoWide(string_buf));
+#endif
+ //FREE(string);
+
+ }
+
+
+ // -------------------------------------------------------------
+ // Load Events into table
+
+ int nEvents = *(int *)p;
+ p+=sizeof(int);
+
+ for (i=0;i<nEvents;i++) {
+
+ int varId = *(int *)p;
+ p+=sizeof(int);
+ int DLFentry = *(int *)p;
+ p+=sizeof(int);
+ int pointer = *(int *)p;
+ p+=sizeof(int);
+
+ // check if this event seems valid
+ if (DLFentry >= nDLFentries || DLFentry < 0) {
+// api->messageBox("Invalid event DLF descriptor", "Script Error", MSGBOX_OK, NULL, NULL);
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDEVENTDLF);
+ return -1;
+ }
+
+ if (pointer < 0) {
+// api->messageBox("Invalid event address", "Script Error", MSGBOX_OK, NULL, NULL);
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDEVENTADDR);
+ return -1;
+ }
+
+ if (varId < 0 || varId >= nVariables) {
+// api->messageBox("Invalid event variable", "Script Error", MSGBOX_OK, NULL, NULL);
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDEVENTVAR);
+ return -1;
+ }
+
+ // insert event into table
+
+ VCPUeventEntry *e = new VCPUeventEntry;
+ //e->DLFentry = DLFentry + DLFEntryBase;
+ e->DLFid = DLFentryTable.enumItem(DLFEntryBase+DLFentry)->DLFid;
+ e->pointer = pointer;
+ e->scriptId = id;
+ e->varId = varId;
+
+ eventsTable.addItem(e);
+ }
+
+ // -------------------------------------------------------------
+ // Load Code block into code table
+
+ int codeSize = *(int *)p;
+ p+=sizeof(int);
+ VCPUcodeBlock *c = new VCPUcodeBlock;
+ c->codeBlock = p;
+ c->dlfBase = DLFEntryBase;
+ c->varBase = variableBase;
+ c->scriptId = id;
+ c->size = codeSize;
+
+ codeTable.addItem(c);
+
+ SystemObject *so = SOM::getSystemObjectByScriptId(id);
+ if (so) {
+ ScriptObject *sso = so->getScriptObject();
+ if (sso)
+ sso->vcpu_addAssignedVariable(0, id);
+ }
+
+ cacheCount++;
+
+ c->debugsymbols = c->codeBlock+codeSize;
+ c->debugsize = memsize - (c->debugsymbols-(char *)mem);
+
+ //WASABI_API_MAKIDEBUG->debugger_createJITD(id); // fucko !!
+
+ return id;
+}
+
+
+// -------------------------------------------------------------
+int VCPU::varBase(int scriptId) {
+ static int lasti=-1;;
+ static int lastb=0;
+ static int lastid=0;
+ if (lastid == scriptId && lasti>=0 && lasti < codeTable.getNumItems()) {
+ if (lastid == codeTable.enumItem(lasti)->scriptId)
+ return lastb;
+ }
+ for (int i=0;i<codeTable.getNumItems();i++ ){
+ if (codeTable.enumItem(i)->scriptId == scriptId) {
+ lasti = i;
+ lastid = scriptId;
+ lastb = codeTable.enumItem(i)->varBase;
+ return lastb;
+ }
+ }
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptId), GURU_INVALIDSCRIPTID);
+ ASSERT(0);
+ return 0;
+}
+
+// -------------------------------------------------------------
+int VCPU::nVars(int scriptId) {
+ for (int i=0;i<codeTable.getNumItems();i++ ){
+ if (codeTable.enumItem(i)->scriptId == scriptId) {
+ if (codeTable.getNumItems() == i+1)
+ return variablesTable.getNumItems() - codeTable.enumItem(i)->varBase;
+ return codeTable.enumItem(i+1)->varBase - codeTable.enumItem(i)->varBase;
+ }
+ }
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptId), GURU_INVALIDSCRIPTID);
+ ASSERT(0);
+ return 0;
+}
+
+// -------------------------------------------------------------
+int VCPU::dlfBase(int scriptId) {
+ for (int i=0;i<codeTable.getNumItems();i++ ){
+ if (codeTable.enumItem(i)->scriptId == scriptId)
+ return codeTable.enumItem(i)->dlfBase;
+ }
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptId), GURU_INVALIDSCRIPTID);
+ ASSERT(0);
+ return 0;
+}
+
+// -------------------------------------------------------------
+void VCPU::removeScript(int id)
+{
+// ASSERTPR(VCPU::VSP==0, "Can't unload script while in script");
+ if (VCPU::VSP != 0)
+ {
+ scriptsToRemove.addItem(id);
+ return;
+ }
+
+ SystemObject *s = SOM::getSystemObjectByScriptId(id);
+ if (s)
+ {
+ s->onUnload();
+ delete s;
+ }
+
+ PtrList<ScriptObject> *l = SystemObject::getAllScriptObjects();
+ int i;
+ for (i=0;i<l->getNumItems();i++) {
+ ScriptObject *o = l->enumItem(i);
+ o->vcpu_delMembers(id);
+ }
+
+ int dlfdeleted=0;
+ int vardeleted=0;
+
+ for (i=0;i<DLFentryTable.getNumItems();i++) {
+ if (DLFentryTable.enumItem(i)->scriptId == id) {
+ delrefDLF(DLFentryTable.enumItem(i));
+ if (DLFentryTable.enumItem(i)->functionName)
+ FREE(DLFentryTable.enumItem(i)->functionName);
+ delete DLFentryTable.enumItem(i);
+ DLFentryTable.delByPos(i);
+ dlfdeleted++;
+ i--;
+ }
+ }
+
+ for (i=0;i<eventsTable.getNumItems();i++) {
+ if (eventsTable.enumItem(i)->scriptId == id) {
+ delete eventsTable.enumItem(i);
+ eventsTable.delByPos(i);
+ i--;
+ }
+ }
+
+ for (i=0;i<variablesTable.getNumItems();i++) {
+ if (variablesTable.enumItem(i)->scriptId == id) {
+ VCPUscriptVar *v = variablesTable.enumItem(i);
+ if (v->isstatic && v->v.type) {
+ ObjectTable::destroy(v->v.data.odata);
+ }
+ if (v->v.type == SCRIPT_STRING)
+ if (v->v.data.sdata)
+ FREE((wchar_t *)v->v.data.sdata);
+ delete v;
+ variablesTable.delByPos(i);
+ vardeleted++;
+ i--;
+ }
+ }
+
+ for (i=0;i<codeTable.getNumItems();i++) {
+ if (codeTable.enumItem(i)->scriptId == id) {
+ VCPUcodeBlock *b = codeTable.enumItem(i);
+ delete b;
+ codeTable.removeByPos(i);
+ for (;i<codeTable.getNumItems();i++) {
+ codeTable.enumItem(i)->dlfBase-=dlfdeleted;
+ codeTable.enumItem(i)->varBase-=vardeleted;
+ }
+ }
+ }
+
+
+ cacheCount++;
+}
+
+// -------------------------------------------------------------
+// Find next matching object, starting from start
+int VCPU::findObject(ScriptObject *o, int start, int dlfid, int vcpuid) {
+/* int stop;
+ if (vcpuid != -1) {
+ int b = varBase(vcpuid);
+ if (start < b)
+ start = b;
+ stop = b + nVars(vcpuid);
+ } else {
+ stop = variablesTable.getNumItems();
+ if (start < 0)
+ start = 0;
+ }*/
+
+/* while (start < stop) {
+ VCPUscriptVar *v = variablesTable.enumItem(start);
+ if (v->v.data.odata == o && !v->transcient && (vcpuid == -1 || v->scriptId == vcpuid))
+ return start;
+ start++;
+ }*/
+ return -1;
+}
+
+
+
+// -------------------------------------------------------------
+// Assign DLF functionId to class exported functions, starting from the last non initialized DLF
+void VCPU::setupDLF(VCPUdlfEntry *e, int dlfEntryBase) {
+ if (ObjectTable::addrefDLF(e, highestDLFId)) {
+ newDlf();
+ }
+
+}
+
+int VCPU::newDlf() {
+ return highestDLFId++;
+}
+
+void VCPU::resetDlf() {
+ highestDLFId = 0;
+}
+
+void VCPU::registerGlobalDlf(VCPUdlfEntry *e, int dlf) {
+ ASSERT(dlf == globalDlfList.getNumItems());
+ VCPUdlfEntry *_e = new VCPUdlfEntry;
+ MEMCPY(_e, e, sizeof(VCPUdlfEntry));
+ _e->functionName = WCSDUP(e->functionName);
+ globalDlfList.addItem(_e);
+}
+
+void VCPU::delrefDLF(VCPUdlfEntry *e) {
+ ObjectTable::delrefDLF(e);
+}
+
+// -------------------------------------------------------------
+
+TList<VCPUscriptVar> VCPU::plist;
+
+// -------------------------------------------------------------
+int VCPU::runEvent(VCPUeventEntry *e, int np, int pbase) {
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ /*if (WASABI_API_MAKIDEBUG && WASABI_API_MAKIDEBUG->debugger_isActive()) {
+ if (WASABI_API_MAKIDEBUG->debugger_filterEvent(e->scriptId, e->DLFid)) {
+ DebugString("Skipping event\n");
+ scriptVar v;
+ v.type = SCRIPT_INT;
+ v.data.idata = 0;
+ VCPU::push(v);
+ return 1;
+ }
+ }*/
+#endif
+
+ for (int z=0;z<np;z++) {
+ VCPU::push(plist[z+pbase]);
+ }
+
+ runCode(e->scriptId, e->pointer, np);
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+/* if (WASABI_API_MAKIDEBUG && WASABI_API_MAKIDEBUG->debugger_isActive())
+ WASABI_API_MAKIDEBUG->debugger_eventComplete();*/
+#endif
+
+ return 1;
+}
+
+// This is the function that actually executes the event. In the future, it will sequencially parse all loaded scripts in reversed load order and stop
+// either at the end of the chain OR as soon as one of the event used "complete;" in its code
+
+// -------------------------------------------------------------
+scriptVar VCPU::executeEvent(scriptVar v, int functionId, int np, int vcpuid) {
+
+ VCPUscriptVar retvar={0,{0},0};
+ int pbase = plist.getNumItems();
+
+ int varId=0;
+
+ complete = 0;
+
+ for (int z=0;z<np;z++) {
+ VCPUscriptVar vcpuv = VCPU::pop();
+ plist.addItem(vcpuv);
+ }
+
+ // find all variables containing this object, and run their event if it's traped
+
+ int next = 0;
+
+ while (!complete) {
+ VCPUscriptVar *vclass=NULL;
+ int inheritedevent=0;
+// varId = VCPU::findObject(v.data.odata, varId, vcpuid);
+ int event;
+ ASSERT(v.data.odata != NULL);
+ varId = ((ScriptObject *)v.data.odata)->vcpu_getAssignedVariable(next, vcpuid, functionId, &next, &event, &inheritedevent);
+
+ if (varId < 0) break;
+
+ VCPUscriptVar *vc = variablesTable.enumItem(varId);
+ ScriptObject *thisobject = (ScriptObject *)v.data.odata;
+
+ VCPUeventEntry *e = eventsTable.enumItem(event);
+
+ int r_varId = varId;
+
+ if (!vc->isaclass && !inheritedevent) {
+ if (e && runEvent(e, np, pbase))
+ retvar = pop();
+ if (getComplete())
+ break;
+ }
+
+ while (vc->isaclass) {
+ ASSERT(r_varId < variablesTable.getNumItems());
+ vclass = variablesTable.enumItem(r_varId);
+ vclass->v.data.odata = thisobject;
+
+ if (runEvent(e, np, pbase))
+ retvar = pop();
+
+ if (getComplete())
+ break;
+
+ vc = vclass;
+ if (vc->varId < 0x10000) break;
+ r_varId = varBase(vc->scriptId) + vc->v.type - 0x10000;
+ }
+
+ if (getComplete())
+ break;
+
+ varId++;
+ }
+
+ for (int i=0;i<np;i++)
+ plist.delByPos(pbase);
+
+ return retvar.v;
+}
+
+void VCPU::callDlfCommand(void *ptr, int nargs, maki_cmd *cmd) {
+ try {
+
+ scriptVar v={0,0};
+ switch (nargs) {
+ case 0:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *))ptr)(cmd, -1, NULL);
+ break;
+ case 1:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar))ptr)(cmd, -1, NULL, v);
+ break;
+ case 2:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v);
+ break;
+ case 3:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v);
+ break;
+ case 4:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v);
+ break;
+ case 5:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v);
+ break;
+ case 6:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v);
+ break;
+ case 7:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v);
+ break;
+ case 8:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v, v);
+ break;
+ case 9:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v, v, v);
+ break;
+ case 10:
+ ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v, v, v, v);
+ break;
+ }
+ }
+
+ catch(...)
+ {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VCPU::VSD), GURU_EXCEPTION, L"Script Fatal Error", -1);
+ #ifdef ON_FATAL_SKIN_ERROR
+ ON_FATAL_SKIN_ERROR
+ #endif
+ }
+
+}
+
+int VCPU::getDLFFromPointer(void *ptr, int nargs) {
+ maki_cmd cmd={MAKI_CMD_GETDLF, -1};
+ callDlfCommand(ptr, nargs, &cmd);
+ return cmd.id;
+}
+
+// This sends the DLFId to the function itself.
+void VCPU::setupDLFFunction(void *ptr, int nargs, int DLFid, VCPUdlfEntry *e) {
+ registerGlobalDlf(e, DLFid);
+ maki_cmd cmd={MAKI_CMD_SETDLF, DLFid};
+ callDlfCommand(ptr, nargs, &cmd);
+}
+
+// This sends the DLFId to the function itself.
+void VCPU::DLF_reset(void *ptr, int nargs) {
+ maki_cmd cmd={MAKI_CMD_RESETDLF, -1};
+ callDlfCommand(ptr, nargs, &cmd);
+}
+
+void VCPU::DLF_addref(void *ptr, int nargs) {
+ maki_cmd cmd={MAKI_CMD_ADDREF, -1};
+ callDlfCommand(ptr, nargs, &cmd);
+}
+
+void VCPU::DLF_remref(void *ptr, int nargs) {
+ maki_cmd cmd={MAKI_CMD_REMREF, -1};
+ callDlfCommand(ptr, nargs, &cmd);
+}
+
+// -------------------------------------------------------------
+scriptVar VCPU::safeDiv(VCPUscriptVar *v1, VCPUscriptVar *v2) {
+ double _r=0;
+ double _v1=SOM::makeDouble(&v1->v);
+ double _v2=SOM::makeDouble(&v2->v);
+ if (_v2 != 0.0)
+ _r = _v1 / _v2;
+ else
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(v1->scriptId), GURU_DIVBYZERO, L"Division by zero");
+
+ scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&r, _r);
+ return r;
+}
+
+/*
+
+Registers :
+
+VIP : Instruction Pointer
+VSP : Stack Pointer
+VSD : Script Descriptor (ID of script we're in)
+
+
+CALLM calls member function, pops a variable ID and a DLF entry, and pushs the result of
+the function. CallC calls an address, so pushs the return address on its stack
+(independant from the Push/Pop stack), and jumps to the code. Ret gets the last
+address pushed and returns there. JIZ jumps to an address if the first value on the stack
+is an int zero. JMP jumps unconditionnaly.
+
+The stack is a stack of 4 bytes integers containing scriptVar IDs.
+Var IDs from binaries are being added the base ID of the current script so we
+have only one variables segment for all scripts. Same for DLF entries. Events
+aren't references in the bytecode other than in the event table that links
+addresses in code to DLF entries, so we don't need that kind of tweaking.
+
+*/
+
+// -------------------------------------------------------------
+char *VCPU::getCodeBlock(int id, int *size) {
+ for (int i=0;i<codeTable.getNumItems();i++) {
+ if (codeTable.enumItem(i)->scriptId == id) {
+ if (size != NULL) *size = codeTable.enumItem(i)->size;
+ return codeTable.enumItem(i)->codeBlock;
+ }
+ }
+ return NULL;
+}
+
+// -------------------------------------------------------------
+VCPUcodeBlock *VCPU::getCodeBlockEntry(int id) {
+ for (int i=0;i<codeTable.getNumItems();i++) {
+ if (codeTable.enumItem(i)->scriptId == id) {
+ return codeTable.enumItem(i);
+ }
+ }
+ return NULL;
+}
+
+// -------------------------------------------------------------
+void VCPU::runCode(int scriptId, int pointer, int np) {
+ int quit=0;
+ VIP = pointer;
+ VSD = scriptId;
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ int debugger_present = debugApi ? debugApi->debugger_isActive() : 0;
+#endif
+
+ char *codeblock = (char *)getCodeBlock(VSD);
+ char *p = codeblock + VIP;
+ unsigned char opcode;
+
+ int stackbase = VSP-np;
+ int callcbase = CallStack.peek();
+ VCC = callcbase;
+
+ while (!quit) {
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ if (debugger_present) {
+ VIPstack.push(VIP);
+ VSDstack.push(VSD);
+// VSPstack.push(VSP);
+ VCCstack.push(VCC);
+ debugApi->debugger_trace();
+ VIPstack.pop(&VIP);
+ VSDstack.pop(&VSD);
+// VSPstack.pop(&VSP);
+ VCCstack.pop(&VCC);
+ }
+#endif
+ opcode = *p;
+ p+=sizeof(opcode);
+ VIP+=sizeof(opcode);
+
+ switch (opcode) {
+ case OPCODE_PUSH: {
+ int id; // var id
+ id = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ VCPUscriptVar *var = variablesTable.enumItem(id+varBase(VSD));
+ push(*var);
+ break;
+ }
+ case OPCODE_POPI: {
+ pop(); // discard
+ if (VSP == stackbase)
+ statementStringList.freeAll();
+ break;
+ }
+ case OPCODE_POP: {
+ int id = *(int *)p; // var id
+ p+=sizeof(int); VIP+=sizeof(int);
+ VCPUscriptVar v = pop();
+ VCPUassign(id, v.v, VSD);
+ break;
+ }
+ case OPCODE_SET: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (v1.varId == -1) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_SETNONINTERNAL);
+ ASSERT(0);
+ }
+ scriptVar r = VCPUassign(v1.varId, v2.v, VSD);
+ push(r);
+ break;
+ }
+ case OPCODE_RETF: {
+ if (/*VSP == stackbase+1 && */CallStack.peek() == callcbase) {
+ quit = 1;
+ break;
+ }
+ CallStack.pop(&p);
+ VIP = p-(char *)getCodeBlock(VSD);
+ break;
+ }
+ case OPCODE_CALLC: {
+ int shift; // jump length
+ shift = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ CallStack.push(p);
+ VCC++;
+ p+=shift;
+ VIP+=shift;
+ break;
+ }
+ case OPCODE_CALLM: {
+ int id; // DLF id
+ id = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ VCPUdlfEntry *e = DLFentryTable.enumItem(id+dlfBase(VSD));
+ int np = *(int *)p;
+ // OLD stack protection - was relying on a shody test based on the fact that the compiler should not be able to generate two FF's at this offset, replaced by new opcode but remains for backward compatibility
+ if ((np & 0xFFFF0000) == 0xFFFF0000) {
+ p += sizeof(int);
+ VIP += sizeof(int);
+ np &= 0xFFFF;
+ } else np = -1;
+ scriptVar r = callDLF(e, np);
+ VCPUscriptVar vr;
+ vr.scriptId = VSD;
+ vr.varId = -1;
+ vr.v = r;
+ push(vr);
+ break;
+ }
+ case OPCODE_CALLM2: {
+ int id; // DLF id
+ id = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ VCPUdlfEntry *e = DLFentryTable.enumItem(id+dlfBase(VSD));
+ int np = *(unsigned char *)p; p++; VIP+=1;
+ scriptVar r = callDLF(e, np);
+ VCPUscriptVar vr;
+ vr.scriptId = VSD;
+ vr.varId = -1;
+ vr.v = r;
+ push(vr);
+ break;
+ }
+ case OPCODE_UMV:
+ {
+ VCPUscriptVar name = pop();
+ VCPUscriptVar obj = pop();
+ ASSERT(obj.v.data.odata!=NULL);
+ ASSERT(name.v.data.sdata!=NULL);
+
+ int rettype = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+
+ if (rettype >= CLASS_ID_BASE) {
+ SystemObject *so = SOM::getSystemObjectByScriptId(VSD);
+ TList<int> *typeslist = so->getTypesList();
+ rettype = typeslist->enumItem(rettype - CLASS_ID_BASE);
+ }
+
+ int oid = ((ScriptObject *)obj.v.data.odata)->vcpu_getMember(name.v.data.sdata, VSD, rettype);
+ VCPUscriptVar *v = getOrphan(oid);
+ ASSERT(v != NULL);
+ push(*v);
+ break;
+ }
+ case OPCODE_CMPEQ: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&r.v, SOM::compEq(&v1.v, &v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_CMPNE: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&r.v, SOM::compNeq(&v1.v, &v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_CMPA: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&r.v, SOM::compA(&v1.v, &v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_CMPAE: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&r.v, SOM::compAe(&v1.v, &v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_CMPB: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&r.v, SOM::compB(&v1.v, &v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_CMPBE: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&r.v, SOM::compBe(&v1.v, &v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_JIZ: {
+ int shift; // jump length
+ shift = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ VCPUscriptVar v = pop();
+ if (v.v.data.idata == 0) {
+ p+=shift;
+ VIP+=shift;
+ }
+ break;
+ }
+ case OPCODE_JNZ: {
+ int shift; // jump length
+ shift = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ VCPUscriptVar v = pop();
+ if (v.v.data.idata != 0) {
+ p+=shift;
+ VIP+=shift;
+ }
+ break;
+ }
+ case OPCODE_JMP: {
+ int shift; // jump length
+ shift = *(int *)p;
+ p+=sizeof(int); VIP+=sizeof(int);
+ p+=shift;
+ VIP+=shift;
+ break;
+ }
+ case OPCODE_NOT: {
+ VCPUscriptVar v = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_BOOLEAN);
+ switch (v.v.type) {
+ case SCRIPT_BOOLEAN:
+ case SCRIPT_INT:
+ case SCRIPT_FLOAT:
+ case SCRIPT_DOUBLE: {
+ int i = SOM::makeBoolean(&v.v);
+ r.v.data.idata = i == 0 ? 1 : 0;
+ }
+ break;
+ case SCRIPT_STRING:
+ r.v.data.idata = (!v.v.data.sdata || !*v.v.data.sdata) ? 1 : 0;
+ break;
+ default:
+ r.v.data.idata = (v.v.data.odata == NULL) ? 1 : 0;
+ break;
+ }
+ push(r);
+ break;
+ }
+ case OPCODE_INCS: {
+ VCPUscriptVar v = pop();
+ push(v);
+ switch (v.v.type) {
+ case SCRIPT_BOOLEAN:
+ v.v.data.idata = 1;
+ break;
+ case SCRIPT_INT:
+ v.v.data.idata++;
+ break;
+ case SCRIPT_FLOAT:
+ v.v.data.fdata = v.v.data.fdata+1;
+ break;
+ case SCRIPT_DOUBLE:
+ v.v.data.ddata = v.v.data.ddata+1;
+ break;
+ default:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_INCSNONNUM);
+ ASSERT(0);
+ break;
+ }
+ if (v.varId != -1)
+ VCPUassign(v.varId, v.v, VSD);
+ break;
+ }
+ case OPCODE_DECS: {
+ VCPUscriptVar v = pop();
+ push(v);
+ switch (v.v.type) {
+ case SCRIPT_BOOLEAN:
+ v.v.data.idata = 0;
+ break;
+ case SCRIPT_INT:
+ v.v.data.idata--;
+ break;
+ case SCRIPT_FLOAT:
+ v.v.data.fdata = v.v.data.fdata-1;
+ break;
+ case SCRIPT_DOUBLE:
+ v.v.data.ddata = v.v.data.ddata-1;
+ break;
+ default:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_DECSNONNUM);
+ ASSERT(0);
+ break;
+ }
+ if (v.varId != -1)
+ VCPUassign(v.varId, v.v, VSD);
+ break;
+ }
+ case OPCODE_INCP: {
+ VCPUscriptVar v = pop();
+ switch (v.v.type) {
+ case SCRIPT_BOOLEAN:
+ v.v.data.idata = 1;
+ break;
+ case SCRIPT_INT:
+ v.v.data.idata++;
+ break;
+ case SCRIPT_FLOAT:
+ v.v.data.fdata = v.v.data.fdata+1;
+ break;
+ case SCRIPT_DOUBLE:
+ v.v.data.ddata = v.v.data.ddata+1;
+ break;
+ default:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_INCPNONNUM);
+ ASSERT(0);
+ break;
+ }
+ if (v.varId != -1)
+ VCPUassign(v.varId, v.v, VSD);
+ push(v);
+ break;
+ }
+ case OPCODE_DECP: {
+ VCPUscriptVar v = pop();
+ switch (v.v.type) {
+ case SCRIPT_BOOLEAN:
+ v.v.data.idata = 0;
+ break;
+ case SCRIPT_INT:
+ v.v.data.idata--;
+ break;
+ case SCRIPT_FLOAT:
+ v.v.data.fdata = v.v.data.fdata-1;
+ break;
+ case SCRIPT_DOUBLE:
+ v.v.data.ddata = v.v.data.ddata-1;
+ break;
+ default:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_DECSNONNUM);
+ ASSERT(0);
+ break;
+ }
+ if (v.varId != -1)
+ VCPUassign(v.varId, v.v, VSD);
+ push(v);
+ break;
+ }
+ case OPCODE_ADD: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ ASSERT(v1.v.type == SCRIPT_STRING || SOM::isNumeric(&v1.v));
+ ASSERT(v2.v.type == SCRIPT_STRING || SOM::isNumeric(&v2.v));
+ if (v2.v.type == SCRIPT_STRING)
+ {
+ int n=0;
+ if (!v2.v.data.sdata) break;
+ if (v1.v.data.sdata) n+= wcslen(v1.v.data.sdata);
+ n+= wcslen(v2.v.data.sdata);
+ wchar_t *s = (wchar_t *)WMALLOC((n+1));
+ ASSERT(s != NULL);
+
+ if (v1.v.data.sdata)
+ {
+ wcsncpy(s, v1.v.data.sdata, n);
+ wcsncat(s, (v2.v.data.sdata ? v2.v.data.sdata : L""), n);
+ } else
+ wcsncpy(s, (v2.v.data.sdata ? v2.v.data.sdata : L""), n);
+
+ v1.v = SOM::makeVar(SCRIPT_STRING);
+ SOM::assign(&v1.v, s);
+ FREE(s);
+ push(v1);
+ } else {
+ scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&r, SOM::makeDouble(&v1.v) + SOM::makeDouble(&v2.v));
+ push(r);
+ }
+ break;
+ }
+ case OPCODE_SUB: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ ASSERT(SOM::isNumeric(&v1.v));
+ ASSERT(SOM::isNumeric(&v2.v));
+ scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&r, SOM::makeDouble(&v1.v) - SOM::makeDouble(&v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_MUL: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ ASSERT(SOM::isNumeric(&v1.v));
+ ASSERT(SOM::isNumeric(&v2.v));
+ scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&r, SOM::makeDouble(&v1.v) * SOM::makeDouble(&v2.v));
+ push(r);
+ break;
+ }
+ case OPCODE_DIV: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ scriptVar r = safeDiv(&v1, &v2);
+ push(r);
+ break;
+ }
+
+ case OPCODE_MOD: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (!SOM::isNumeric(&v2.v) || !SOM::isNumeric(&v1.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_MODNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v1.v, SOM::makeInt(&v1.v) % SOM::makeInt(&v2.v));
+ push(v1);
+ break;
+ }
+
+ case OPCODE_NEG: {
+ VCPUscriptVar v = pop();
+ switch (v.v.type) {
+ case SCRIPT_BOOLEAN:
+ break;
+ case SCRIPT_INT:
+ v.v.data.idata = -v.v.data.idata;
+ break;
+ case SCRIPT_FLOAT:
+ v.v.data.fdata = -v.v.data.fdata;
+ break;
+ case SCRIPT_DOUBLE:
+ v.v.data.ddata = -v.v.data.ddata;
+ break;
+ default:
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_NEGNONNUM);
+ ASSERT(0);
+ break;
+ }
+ push(v);
+ break;
+ }
+
+ case OPCODE_BNOT: {
+ VCPUscriptVar v = pop();
+ if (!SOM::isNumeric(&v.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_BNOTNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v.v, ~SOM::makeInt(&v.v));
+ push(v);
+ break;
+ }
+
+ case OPCODE_SHL: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_SHLNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v1.v, SOM::makeInt(&v1.v) << SOM::makeInt(&v2.v));
+ push(v1);
+ break;
+ }
+ case OPCODE_SHR: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_SHRNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v1.v, SOM::makeInt(&v1.v) >> SOM::makeInt(&v2.v));
+ push(v1);
+ break;
+ }
+
+ case OPCODE_XOR: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_XORNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v1.v, SOM::makeInt(&v1.v) ^ SOM::makeInt(&v2.v));
+ push(v1);
+ break;
+ }
+
+ case OPCODE_AND: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_ANDNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v1.v, SOM::makeInt(&v1.v) & SOM::makeInt(&v2.v));
+ push(v1);
+ break;
+ }
+ case OPCODE_OR: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_ANDNONNUM);
+ ASSERT(0);
+ }
+ SOM::assign(&v1.v, SOM::makeInt(&v1.v) | SOM::makeInt(&v2.v));
+ push(v1);
+ break;
+ }
+
+ case OPCODE_LAND: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_BOOLEAN);
+ int a2 = SOM::makeBoolean(&v2.v);
+ int a1 = SOM::makeBoolean(&v1.v);
+ r.v.data.idata = (a2 && a1) ? 1 : 0;
+ push(r);
+ break;
+ }
+ case OPCODE_LOR: {
+ VCPUscriptVar v2 = pop();
+ VCPUscriptVar v1 = pop();
+ VCPUscriptVar r;
+ r.v = SOM::makeVar(SCRIPT_BOOLEAN);
+ int a2 = SOM::makeBoolean(&v2.v);
+ int a1 = SOM::makeBoolean(&v1.v);
+ r.v.data.idata = (a2 || a1) ? 1 : 0;
+ push(r);
+ break;
+ }
+
+ case OPCODE_DELETE: {
+ VCPUscriptVar v1 = pop();
+ int id = 0;
+ int type = v1.v.type;
+ if (type >= 0x10000)
+ do {
+ id = type - 0x10000;
+ VCPUscriptVar *v = variablesTable.enumItem(id+varBase(VSD));
+ type = v->v.type;
+ } while (type >= 0x10000);
+
+ if (isInstantiable(type)) {
+ ScriptObject *s = (ScriptObject *)v1.v.data.odata;
+ scriptVar v = SOM::makeVar(v1.v.type);
+ VCPUassign(v1.varId, v, v1.scriptId);
+ SystemObject *so = SOM::getSystemObjectByScriptId(VSD);
+ so->removeInstantiatedObject(s);
+ ObjectTable::destroy(s);
+ }
+ VCPU::push(v1);
+ break;
+ }
+
+
+ case OPCODE_NEW: {
+ int id = *(int *)p; // class id
+ p+=sizeof(int); VIP+=sizeof(int);
+
+ SystemObject *so = SOM::getSystemObjectByScriptId(VSD);
+ TList<int> *typeslist = so->getTypesList();
+
+ int _id;
+ if (id >= 0x10000)
+ do {
+ _id = id - 0x10000;
+ VCPUscriptVar *v = variablesTable.enumItem(_id+varBase(VSD));
+ id = v->v.type;
+ } while (id >= 0x10000);
+
+ if (SOM::getSystemObjectByScriptId(VSD)->isOldFormat())
+ id = oldClassToClassId(id);
+ else
+ id = typeslist->enumItem(id);
+
+ if (isInstantiable(id)) {
+ ScriptObject *s = ObjectTable::instantiate(id);
+ if (s) s->vcpu_setScriptId(VSD);
+
+ so->addInstantiatedObject(s);
+
+ if (s == NULL) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_NEWFAILED);
+ }
+ VCPUscriptVar v={{SCRIPT_OBJECT, {0}}, 0};
+ SOM::assign(&v.v, s);
+ push(v);
+ } else {
+ VCPUscriptVar n = {{SCRIPT_OBJECT,NULL}, 0};
+ push(n);
+ }
+ break;
+ }
+
+ case OPCODE_CMPLT : {
+ complete = 1;
+ break;
+ }
+
+ case OPCODE_NOP :
+ {
+#if defined(_WIN32) || defined(_WIN64)
+ OutputDebugStringA("Opcode 0 - NOP encountered, please check!\n");
+#else
+#warning port me
+#endif
+ break;
+ }
+ default: {
+ ASSERTALWAYS(StringPrintf("Opcode %X not implemented", opcode));
+ break;
+ }
+ }
+ }
+
+ ASSERT(VSP == stackbase + 1);
+}
+
+// -------------------------------------------------------------
+scriptVar VCPU::VCPUassign(int id, scriptVar sv, int scriptId) {
+ VCPUscriptVar *v = NULL;
+
+ if (id & (1 << 31)) {
+ id = id & ~(1 << 31);
+ v = getOrphan(id);
+ } else
+ v = variablesTable.enumItem(id+varBase(scriptId));
+
+ if (v->v.type != SCRIPT_STRING) {
+ if (!SOM::isNumeric(&v->v)) {
+ // assigning an object
+
+ scriptVar _sv = sv;
+
+ if (_sv.data.odata != NULL && !SystemObject::isObjectValid(_sv.data.odata))
+ _sv.data.odata = NULL;
+
+ if (v->v.data.odata != _sv.data.odata) {
+
+ if (v->v.data.odata != NULL && !v->transcient && SystemObject::isObjectValid(v->v.data.odata))
+ ((ScriptObject *)v->v.data.odata)->vcpu_removeAssignedVariable(v->varId, v->scriptId);
+
+ if (_sv.data.odata == NULL) {
+ v->v.data.odata = NULL;
+ } else {
+ SOM::assign(&v->v, &sv);
+ if (SOM::typeCheck(v, 0)) {
+ if (!v->isaclass && !v->transcient)
+ ((ScriptObject *)sv.data.odata)->vcpu_addAssignedVariable(v->varId, v->scriptId);
+ } else {
+ int type = v->v.type;
+ if (type >= 0x10000)
+ do {
+ id = type - 0x10000;
+ VCPUscriptVar *v = variablesTable.enumItem(id+varBase(VSD));
+ type = v->v.type;
+ } while (type >= 0x10000);
+ class_entry *e = ObjectTable::getClassEntry(type);
+ ASSERT(e != NULL);
+ GUID g = e->classGuid;
+ ScriptObject *o = NULL;
+ v->v.data.odata->vcpu_getInterfaceObject(g, &o);
+ if (o != NULL) {
+ v->v.data.odata = o;
+ if (!v->isaclass && !v->transcient)
+ o->vcpu_addAssignedVariable(v->varId, v->scriptId);
+ } else {
+ v->v.data.odata = NULL;
+ }
+ }
+ }
+ }
+
+ } else {
+ // assigning a number
+ SOM::assign(&v->v, &sv);
+ }
+ } else {
+ ASSERT(sv.type == SCRIPT_STRING);
+ SOM::persistentstrassign(&v->v, sv.data.sdata);
+ }
+
+ return v->v;
+}
+
+// -------------------------------------------------------------
+void VCPU::traceState(VCPUscriptVar object, VCPUdlfEntry *e) {
+ _DebugString("vcpu[%2X]: %04X [%04X].%s", VCPU::VSD, VCPU::VIP, object.varId, e->functionName);
+// CallbackManager::issueCallback(SysCallback::CONSOLE, ConsoleCallback::DEBUGMESSAGE, 0, reinterpret_cast<int>(t));
+}
+
+// -------------------------------------------------------------
+// Calls the DLF function
+scriptVar VCPU::callDLF(VCPUdlfEntry *e, int np) {
+
+ static Stack<int> cpuidstack;
+
+ cpuidstack.push(VSD);
+ cpuidstack.push(VIP);
+ cpuidstack.push(VCC);
+
+/* if (e->external) {
+ char t[256] = {0};
+ VCPUscriptVar v = VCPU::peekAt(e->nparams);
+ SPRINTF(t, "vcpu: %04X [%04X].%s", VCPU::VIP, v.varId, e->functionName);
+ Console::outputString(0, t);
+ DebugString("%s", t);
+ ((void(*)(int))e->ptr)(-1);
+ scriptVar rv = pop().v; // returned val
+ cpuidstack.pop(&VCC);
+ cpuidstack.pop(&VIP);
+ cpuidstack.pop(&VSD);
+ return rv;
+ }*/
+
+
+/* char t[256] = {0};
+ SPRINTF(t, "e->nparams = %d\n", e->nparams);
+ DebugString("%s", t); */
+
+ //ASSERT(np == -1 || np == e->nparams); // fucko!!!!!!!!
+
+ if (np == -1) {
+ np = e->nparams;
+ }
+
+ for (int i=0;i<np;i++) {
+ paramList[i] = pop().v;
+ }
+
+ VCPUscriptVar object = pop();
+ scriptVar r = MAKE_SCRIPT_INT(0);
+
+ //traceState(object, e);
+
+ if (object.v.data.odata == NULL) {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VCPU::VSD), GURU_NULLCALLED, L"Null object called", object.varId);
+ cpuidstack.pop(&VCC);
+ cpuidstack.pop(&VIP);
+ cpuidstack.pop(&VSD);
+ return MAKE_SCRIPT_INT(0);
+ //ASSERT(0);
+ }
+#ifndef _DEBUG
+ try
+#endif
+ {
+ if (object.v.data.odata) object.v.data.odata->vcpu_setScriptId(object.scriptId);
+
+ if (e->ptr != NULL) {
+ switch (np) {
+ case 0:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *))e->ptr)(NULL, VCPU::VSD, object.v.data.odata);
+ break;
+ case 1:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0]);
+ break;
+ case 2:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1]);
+ break;
+ case 3:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2]);
+ break;
+ case 4:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3]);
+ break;
+ case 5:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4]);
+ break;
+ case 6:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5]);
+ break;
+ case 7:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6]);
+ break;
+ case 8:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6], paramList[7]);
+ break;
+ case 9:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6], paramList[7], paramList[8]);
+ break;
+ case 10:
+ r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6], paramList[7], paramList[8], paramList[9]);
+ break;
+ }
+ }
+ }
+#ifndef _DEBUG
+ catch(...)
+ {
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(VCPU::VSD), GURU_EXCEPTION, L"Script Fatal Error", object.varId);
+ cpuidstack.pop(&VCC);
+ cpuidstack.pop(&VIP);
+ cpuidstack.pop(&VSD);
+ #ifdef ON_FATAL_SKIN_ERROR
+ ON_FATAL_SKIN_ERROR
+ #endif
+ return MAKE_SCRIPT_INT(0);
+ }
+#endif
+ cpuidstack.pop(&VCC);
+ cpuidstack.pop(&VIP);
+ cpuidstack.pop(&VSD);
+
+ return r;
+}
+
+// -------------------------------------------------------------
+void VCPU::addStatementString(wchar_t *s)
+{
+ statementStringList.addItem(s);
+}
+
+// -------------------------------------------------------------
+int VCPU::getComplete() {
+ return complete;
+}
+
+// -------------------------------------------------------------
+int VCPU::isInstantiable(int id) {
+ ASSERT(!SOM::isNumericType(id));
+ return ObjectTable::isClassInstantiable(id);
+}
+
+// -------------------------------------------------------------
+int VCPU::getDlfGlobalIndex(int dlfid, int scriptid) {
+ static int lasti=-1;
+ static int lastid=0;
+ static int lastsid=0;
+ if (lasti>=0 && lasti < DLFentryTable.getNumItems()) {
+ if (lastsid == scriptid && lastid == dlfid) {
+ VCPUdlfEntry *e = DLFentryTable.enumItem(lasti);
+ if (e->DLFid == dlfid && e->scriptId == scriptid)
+ return lasti;
+ }
+ }
+ for (int i=0;i<DLFentryTable.getNumItems();i++ ){
+ VCPUdlfEntry *e = DLFentryTable.enumItem(i);
+ if (e->scriptId == scriptid && e->DLFid == dlfid) {
+ lasti = i;
+ lastsid = scriptid;
+ lastid = dlfid;
+ return lasti;
+ }
+ }
+ Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptid), GURU_INVALIDEVENTDLF);
+ return -1;
+}
+
+// -------------------------------------------------------------
+int VCPU::isValidScriptId(int id) {
+ for (int i=0;i<codeTable.getNumItems();i++)
+ if (codeTable[i]->scriptId == id) return 1;
+ return 0;
+}
+
+// -------------------------------------------------------------
+int VCPU::getCacheCount() {
+ return cacheCount;
+}
+
+// -------------------------------------------------------------
+int VCPU::getUserAncestor(int varid, int scriptid) {
+ VCPUscriptVar *vc = variablesTable.enumItem(varid+varBase(scriptid)) ;
+ if (vc->v.type < 0x10000) return -1;
+ int r_varId = vc->v.type - 0x10000;
+ ASSERT(r_varId < variablesTable.getNumItems());
+ return r_varId;
+}
+
+// -------------------------------------------------------------
+void VCPU::pushObject(void *o) {
+ scriptVar v = SOM::makeVar(SCRIPT_OBJECT, (ScriptObject *)o);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void VCPU::pushInt(int i) {
+ scriptVar v = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&v, i);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void VCPU::pushBoolean(int b) {
+ scriptVar v = SOM::makeVar(SCRIPT_BOOLEAN);
+ SOM::assign(&v, b);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void VCPU::pushFloat(float f) {
+ scriptVar v = SOM::makeVar(SCRIPT_FLOAT);
+ SOM::assign(&v, f);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void VCPU::pushDouble(double d) {
+ scriptVar v = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&v, d);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void VCPU::pushString(const wchar_t *s)
+{
+ scriptVar v = SOM::makeVar(SCRIPT_STRING);
+ SOM::assign(&v, s);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void VCPU::pushVoid() {
+ scriptVar v = SOM::makeVar(SCRIPT_VOID);
+ VCPU::push(v);
+}
+
+// -------------------------------------------------------------
+void *VCPU::popObject() {
+ return (void *)VCPU::pop().v.data.odata;
+}
+
+// -------------------------------------------------------------
+int VCPU::popInt() {
+ scriptVar v = VCPU::pop().v;
+ ASSERT(SOM::isNumeric(&v));
+ return SOM::makeInt(&v);
+}
+
+// -------------------------------------------------------------
+bool VCPU::popBoolean() {
+ scriptVar v = VCPU::pop().v;
+ ASSERT(SOM::isNumeric(&v));
+ return SOM::makeBoolean(&v);
+}
+
+// -------------------------------------------------------------
+float VCPU::popFloat() {
+ scriptVar v = VCPU::pop().v;
+ ASSERT(SOM::isNumeric(&v));
+ return SOM::makeFloat(&v);
+}
+
+// -------------------------------------------------------------
+double VCPU::popDouble() {
+ scriptVar v = VCPU::pop().v;
+ ASSERT(SOM::isNumeric(&v));
+ return SOM::makeDouble(&v);
+}
+
+// -------------------------------------------------------------
+const wchar_t *VCPU::popString()
+{
+ scriptVar v = VCPU::pop().v;
+ ASSERT(v.type == SCRIPT_STRING);
+ return v.data.sdata;
+}
+
+// -------------------------------------------------------------
+void VCPU::popDiscard() {
+ VCPU::pop();
+}
+
+// -------------------------------------------------------------
+VCPUdlfEntry *VCPU::getGlobalDlfEntry(int dlfid) {
+ return globalDlfList.enumItem(dlfid);
+}
+
+// -------------------------------------------------------------
+int VCPU::createOrphan(int type) {
+ orphans.addItem(new OrphanEntry(orphanid, type));
+ return orphanid++;
+}
+
+// -------------------------------------------------------------
+void VCPU::killOrphan(int id) {
+ int pos;
+ OrphanEntry *p = orphans.findItem((const wchar_t *)&id, &pos);
+ ASSERT(p != NULL && pos >= 0);
+ if (p->v.v.type == SCRIPT_STRING)
+ FREE((void *)p->v.v.data.sdata);
+ delete p;
+ orphans.removeByPos(pos);
+}
+
+// -------------------------------------------------------------
+VCPUscriptVar *VCPU::getOrphan(int id) {
+ OrphanEntry *p = orphans.findItem((const wchar_t *)&id);
+ ASSERT(p != NULL);
+ return &p->v;
+}
+
+// -------------------------------------------------------------
+int OrphanQuickSort::compareItem(void *p1, void *p2) {
+ if ((static_cast<OrphanEntry *>(p1))->id < (static_cast<OrphanEntry *>(p2))->id) return -1;
+ if ((static_cast<OrphanEntry *>(p1))->id > (static_cast<OrphanEntry *>(p2))->id) return 1;
+ return 0;
+}
+
+// -------------------------------------------------------------
+int OrphanQuickSort::compareAttrib(const wchar_t *attr, void *p2)
+{
+ int id = *(reinterpret_cast<const int *>(attr));
+ int eid = (static_cast<OrphanEntry *>(p2))->id;
+ if (id < eid) return -1;
+ if (id > eid) return 1;
+ return 0;
+}
+
+// -------------------------------------------------------------
+OrphanEntry::OrphanEntry(int _id, int type) {
+ id = _id;
+ MEMSET(&v, 0, sizeof(VCPUscriptVar));
+ v.v.type = type;
+ v.scriptId = -1;
+ v.varId = id | (1 << 31);
+ v.transcient = 1; // so no event is trapped, will change later when compiler supports it
+}
+
+// -------------------------------------------------------------
+void VCPU::setAtom(const wchar_t *atomname, ScriptObject *o) {
+ int pos;
+ ScriptAtom *sa = atoms.findItem(atomname, &pos);
+ if (pos >= 0) {
+ delete sa;
+ atoms.removeByPos(pos);
+ }
+ if (o)
+ atoms.addItem(new ScriptAtom(atomname, o));
+}
+
+// -------------------------------------------------------------
+ScriptObject *VCPU::getAtom(const wchar_t *atomname) {
+ ScriptAtom *sa = atoms.findItem(atomname);
+ if (sa) {
+ return sa->getAtomObject();
+ }
+ return NULL;
+}
+
+// -------------------------------------------------------------
+const wchar_t *VCPU::getClassName(int vcpuid, int localclassid) {
+ SystemObject *so = SOM::getSystemObject(vcpuid);
+ if (so != NULL) {
+ TList<int> *l = so->getTypesList();
+ if (l != NULL) {
+ int global = l->enumItem(localclassid);
+ class_entry *e = ObjectTable::getClassEntry(global);
+ if (e != NULL)
+ return e->classname;
+ }
+ }
+ return NULL;
+}
+
+
+// -------------------------------------------------------------
+int VCPU::cacheCount = 0;
+
+// segments
+PtrList<VCPUscriptVar> VCPU::variablesTable;
+PtrList<VCPUeventEntry> VCPU::eventsTable;
+PtrList<VCPUdlfEntry> VCPU::DLFentryTable;
+PtrList<VCPUdlfEntry> VCPU::globalDlfList;
+PtrList<VCPUcodeBlock> VCPU::codeTable;
+PtrList<wchar_t> VCPU::statementStringList;
+PtrListInsertSorted<OrphanEntry, OrphanQuickSort> VCPU::orphans;
+PtrListQuickSorted<ScriptAtom, ScriptAtomSort> VCPU::atoms;
+int VCPU::orphanid=0;
+
+// stacks
+Stack<VCPUscriptVar> VCPU::CpuStack;
+Stack<char *> VCPU::CallStack;
+
+// registers
+int VCPU::VIP=0;
+int VCPU::VSP=0;
+int VCPU::VSD=0;
+int VCPU::VCC=0;
+
+Stack<int> VCPU::VIPstack;
+Stack<int> VCPU::VSPstack;
+Stack<int> VCPU::VSDstack;
+Stack<int> VCPU::VCCstack;
+
+// misc
+int VCPU::numScripts=0;
+int VCPU::highestDLFId=0;
+scriptVar VCPU::paramList[SCRIPT_MAXARGS];
+int VCPU::complete;
+
+TList<int> VCPU::scriptsToRemove;
+// NOTES
+
+// There is no reason why people would cast System, Layout and Container
+// back to the common base class... so...
+// GUI objects should descend from a GUIObject rather than ScriptObject
+// GUIObject would descend from ScriptObject for the compiler and should
+// be exported as "Object" for the script, ScriptObject should then not
+// be exported at all, thus preventing someone from doing "Object o = System;"
+// which makes no sense since System is not a GUI object. Of course you
+// could still do "Layout l = System.getContainer("mqlksd").getLayout("lqsdkj");"
+// but you won't be able to cast that to an "Object". Furthermore, to get a
+// GUI object, you'll use the layout's function "getObject", so this
+// will add consistency to the overall thing.
+
+/*
+--------------------------------------------------------------------------------
+
+ VCPU: Virtual CPU, The virtual machine processor.
+ The VCPU actually takes care of some kinds of segments of variables,
+ events, and so on. The VCPU's task is to run any number of scripts
+ serially in reversed loading order. Last script loaded takes precedence
+ over previous ones. Events and functions fall back to the the previous
+ script if it also defines them, unless explicitly prevented via 'complete;'
+ The VCPU links DLFs in reverse hierarchy order, allowing overriding of
+ functions in objects.
+
+ DLF : Dynamically Linked Function. Function name is used to link it to
+ whatever layout of functions we have in any release of the VCPU, allowing
+ us to reorder our functions in objects.
+
+ TODO: Add versionning info so we can safely expand this format.
+
+ Binaries format :
+
+ <obsolete>
+
+ Size Desc What
+ -----------------------------------------------------------------------------
+ 8 Header FG\x03\x04\x14\00\00\00\00
+ -----------------------------------------------------------------------------
+ 4 # of DLF int
+ -----------------------------------------------------------------------------
+ 4 DLF base type int
+ 1 Size of func name char
+ N Function name char[n]
+ ...
+ -----------------------------------------------------------------------------
+ 4 # of variables int
+ -----------------------------------------------------------------------------
+ 8 variable scriptVar
+ ...
+ -----------------------------------------------------------------------------
+ 4 # of strings int
+ -----------------------------------------------------------------------------
+ 1 Size of string char 1st string assigned to 1st string var
+ N String char[n] 2nd string assigned to 2nd string var...
+ ...
+ -----------------------------------------------------------------------------
+ 4 # of events int
+ -----------------------------------------------------------------------------
+ 4 variable id int Matching variable table
+ 4 DLF entry int Matching DLF table
+ 4 Function pointer int Pointer in code from base of code
+ ...
+ -----------------------------------------------------------------------------
+ 4 Size of code int
+ -----------------------------------------------------------------------------
+ N Compiled code char[n]
+ -----------------------------------------------------------------------------
+
+*/
diff --git a/Src/Wasabi/api/script/vcpu.h b/Src/Wasabi/api/script/vcpu.h
new file mode 100644
index 00000000..fdd90bb3
--- /dev/null
+++ b/Src/Wasabi/api/script/vcpu.h
@@ -0,0 +1,171 @@
+#ifndef __VCPU_H
+#define __VCPU_H
+
+#include "script.h"
+#include "opcodes.h"
+
+#include <bfc/tlist.h>
+#include <bfc/ptrlist.h>
+#include <bfc/stack.h>
+#include <bfc/critsec.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/systemobj.h>
+
+class ConsoleEnum;
+
+#include <api/script/vcputypes.h>
+
+class OrphanEntry {
+
+ public:
+
+ OrphanEntry(int _id, int type);
+ virtual ~OrphanEntry() {}
+
+ int id;
+ VCPUscriptVar v;
+};
+
+class OrphanQuickSort {
+ public:
+ static int compareItem(void *p1, void* p2);
+ static int compareAttrib(const wchar_t *attrib, void *item);
+ };
+
+class ScriptAtom {
+ public:
+ ScriptAtom(const wchar_t *atomname, ScriptObject *object) : name(atomname), obj(object) {}
+ ~ScriptAtom() {}
+
+ const wchar_t *getAtomName() { return name; }
+ ScriptObject *getAtomObject() { return obj; }
+
+ private:
+ StringW name;
+ ScriptObject *obj;
+};
+
+class ScriptAtomSort {
+public:
+ static int compareItem(ScriptAtom *p1, ScriptAtom*p2) {
+ return WCSICMP(p1->getAtomName(), p2->getAtomName());
+ }
+ static int compareAttrib(const wchar_t *attrib, ScriptAtom *item) {
+ return WCSICMP(attrib, item->getAtomName());
+ }
+};
+
+
+class VCPU {
+
+public:
+ static void shutdown();
+ static int assignNewScriptId();
+ static int addScript(void *mem, int memsize, int cpuid);
+ static void removeScript(int id);
+
+ static void push(VCPUscriptVar v);
+ static void push(scriptVar v);
+ static VCPUscriptVar pop();
+ static VCPUscriptVar peekAt(int n);
+
+ static scriptVar executeEvent(scriptVar v, int functionId, int np, int vcpuid=-1);
+ static int runEvent(VCPUeventEntry *e, int np, int pbase);
+ static void runCode(int scriptId, int pointer, int np);
+ static scriptVar callDLF(VCPUdlfEntry *e, int np);
+ static scriptVar VCPUassign(int id, scriptVar sv, int scriptId);
+
+ static int findObject(ScriptObject *o, int start, int dlfid, int vcpuid=-1);
+ static int numScripts;
+ static void setupDLF(VCPUdlfEntry *e, int base);
+ static void delrefDLF(VCPUdlfEntry *e);
+ static void setupDLFFunction(void *ptr, int nargs, int DLFid, VCPUdlfEntry *e);
+ static int getDlfGlobalIndex(int dlfid, int scriptid);
+
+ static scriptVar safeDiv(VCPUscriptVar*, VCPUscriptVar*);
+ static void setComplete() { complete=1; }
+ static void resetComplete() { complete=0; }
+ static int getComplete();
+ static int newDlf();
+ static void resetDlf();
+
+ static PtrList<VCPUscriptVar> variablesTable;
+ static PtrList<VCPUeventEntry> eventsTable;
+ static PtrList<VCPUdlfEntry> DLFentryTable;
+ static PtrList<VCPUcodeBlock> codeTable;
+
+ static int highestDLFId;
+ static Stack<VCPUscriptVar> CpuStack;
+ static Stack<char *> CallStack;
+
+ static int varBase(int scriptId);
+ static int dlfBase(int scriptId);
+ static int nVars(int scriptId);
+ static char *getCodeBlock(int scriptId, int *size=NULL);
+ static VCPUcodeBlock *getCodeBlockEntry(int vcpuid);
+
+ static void addStatementString(wchar_t *s);
+
+ static int getCacheCount();
+ static int getUserAncestor(int varid, int scriptid);
+ static int isValidScriptId(int id);
+ static int oldClassToClassId(int id);
+ static const wchar_t *getClassName(int vcpuid, int localclassid);
+
+ static int VIP;
+ static int VSP;
+ static int VSD;
+ static int VCC;
+ static int complete;
+ static int cacheCount;
+
+ static Stack<int> VIPstack;
+ static Stack<int> VSPstack;
+ static Stack<int> VSDstack;
+ static Stack<int> VCCstack;
+
+ static void RemoveOldScripts();
+ static TList<int> scriptsToRemove;
+
+ static scriptVar paramList[SCRIPT_MAXARGS];
+ static TList<VCPUscriptVar> plist;
+ static PtrList<wchar_t> statementStringList;
+
+ static int isInstantiable(int id);
+
+ static void pushObject(void *o);
+ static void pushInt(int i);
+ static void pushBoolean(int b);
+ static void pushFloat(float f);
+ static void pushDouble(double d);
+ static void pushString(const wchar_t *s);
+ static void pushVoid();
+ static void *popObject();
+ static int popInt();
+ static bool popBoolean();
+ static float popFloat();
+ static double popDouble();
+ static const wchar_t *popString();
+ static void popDiscard();
+ static void callDlfCommand(void *ptr, int nargs, maki_cmd *cmd);
+ static int getDLFFromPointer(void *ptr, int nargs);
+ static void DLF_addref(void *ptr, int nargs);
+ static void DLF_reset(void *ptr, int nargs);
+ static void DLF_remref(void *ptr, int nargs);
+ static VCPUdlfEntry *getGlobalDlfEntry(int dlfid);
+ static void registerGlobalDlf(VCPUdlfEntry *e, int dlf);
+ static void traceState(VCPUscriptVar object, VCPUdlfEntry *e);
+ static PtrList<VCPUdlfEntry> globalDlfList;
+ static PtrListInsertSorted< OrphanEntry, OrphanQuickSort >orphans;
+ static int orphanid;
+ static VCPUscriptVar *getOrphan(int id);
+ static int createOrphan(int type);
+ static void killOrphan(int id);
+ static void setAtom(const wchar_t *atomname, ScriptObject *o);
+ static ScriptObject *getAtom(const wchar_t *atomname);
+ static PtrListQuickSorted<ScriptAtom, ScriptAtomSort> atoms;
+ static ScriptObjectManager *scriptManager;
+};
+
+#endif
diff --git a/Src/Wasabi/api/script/vcputypes.h b/Src/Wasabi/api/script/vcputypes.h
new file mode 100644
index 00000000..b36cb6cb
--- /dev/null
+++ b/Src/Wasabi/api/script/vcputypes.h
@@ -0,0 +1,78 @@
+#ifndef __VCPUTYPES_H
+#define __VCPUTYPES_H
+
+#include <bfc/platform/platform.h>
+
+// Basic types
+#define SCRIPT_FIRSTTYPE SCRIPT_VOID
+#define SCRIPT_VOID 0
+#define SCRIPT_EVENT 1
+#define SCRIPT_INT 2
+#define SCRIPT_FLOAT 3
+#define SCRIPT_DOUBLE 4
+#define SCRIPT_BOOLEAN 5
+#define SCRIPT_STRING 6
+#define SCRIPT_OBJECT 7
+#define SCRIPT_ANY 8
+#define SCRIPT_LASTTYPE SCRIPT_ANY
+
+static const GUID guidNull =
+{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
+
+#include <api/script/scriptvar.h>
+
+#ifdef _MSC_VER
+#pragma pack(push, 1)
+#else
+#pragma pack(1)
+#endif
+
+typedef struct {
+ scriptVar v;
+ int scriptId;
+ int varId;
+ char transcient;
+ char isaclass;
+ char isstatic;
+} VCPUscriptVar;
+
+typedef struct {
+ int varId;
+ int pointer;
+ int DLFid;
+ int scriptId;
+} VCPUeventEntry;
+
+typedef struct {
+ wchar_t *functionName;
+ int basetype;
+ int scriptId;
+ int DLFid;
+ void *ptr;
+ int nparams;
+} VCPUdlfEntry;
+
+typedef struct {
+ char *codeBlock;
+ int scriptId;
+ int dlfBase;
+ int varBase;
+ int size;
+ char *debugsymbols;
+ int debugsize;
+} VCPUcodeBlock;
+
+typedef struct
+{
+ int cmd;
+ int id;
+} maki_cmd;
+
+#ifdef _MSC_VER
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif
+
+#endif
+
diff --git a/Src/Wasabi/api/service/api_service.cpp b/Src/Wasabi/api/service/api_service.cpp
new file mode 100644
index 00000000..6d67c16d
--- /dev/null
+++ b/Src/Wasabi/api/service/api_service.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:56:11 2003]
+//
+// File : api_service.cpp
+// Class : api_service
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_service.h"
+
+api_service *serviceApi = NULL; \ No newline at end of file
diff --git a/Src/Wasabi/api/service/api_service.h b/Src/Wasabi/api/service/api_service.h
new file mode 100644
index 00000000..0d309000
--- /dev/null
+++ b/Src/Wasabi/api/service/api_service.h
@@ -0,0 +1,184 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:56:11 2003]
+//
+// File : api_service.h
+// Class : api_service
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_SERVICE_H
+#define __API_SERVICE_H
+
+#include "bfc/dispatch.h"
+#include "bfc/platform/types.h"
+
+namespace SvcNotify
+{
+ enum
+ {
+ ONREGISTERED = 100, // init yourself here -- not all other services are registered yet
+ ONSTARTUP = 200, // everyone is initialized, safe to talk to other services
+ ONAPPRUNNING = 210, // app is showing and processing events
+ ONSHUTDOWN = 300, // studio is shutting down, release resources from other services
+ ONDEREGISTERED = 400, // bye bye
+ ONDBREADCOMPLETE = 500, // after db is read in (happens asynchronously after ONSTARTUP)
+ ONBEFORESHUTDOWN = 600, // system is about to shutdown, call WASABI_API_APP->main_cancelShutdown() to cancel
+ };
+}
+
+ class waServiceFactory;
+
+// ----------------------------------------------------------------------------
+
+ class NOVTABLE api_service : public Dispatchable
+ {
+ protected:
+ api_service() {}
+ ~api_service() {}
+
+ public:
+ int service_register( waServiceFactory *svc );
+ int service_deregister( waServiceFactory *svc );
+
+ size_t service_getNumServices( FOURCC svc_type );
+ waServiceFactory *service_enumService( FOURCC svc_type, size_t n );
+
+ waServiceFactory *service_getServiceByGuid( GUID guid );
+
+ int service_lock( waServiceFactory *owner, void *svcptr );
+ int service_clientLock( void *svcptr );
+ int service_release( void *svcptr );
+ const char *service_getTypeName( FOURCC svc_type );
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ GUID service_getOwningComponent( void *svcptr );
+ GUID service_getLockingComponent( void *svcptr );
+#endif // WASABI_COMPILE_COMPONENTS
+
+ int service_unlock( void *svcptr );
+ int service_isvalid( FOURCC svctype, waServiceFactory *service );
+ // removes "me" from the services list and finds a second service with the same GUID and puts it in the same position
+ // this is used by the lazy loader service factory - you shouldn't need it for any other purposes.
+ // returns 0 if compaction actually happened
+ int service_compactDuplicates( waServiceFactory *me );
+
+ protected:
+ enum
+ {
+ API_SERVICE_SERVICE_REGISTER = 10,
+ API_SERVICE_SERVICE_DEREGISTER = 20,
+ API_SERVICE_SERVICE_GETNUMSERVICES = 30,
+ API_SERVICE_SERVICE_ENUMSERVICE = 40,
+ API_SERVICE_SERVICE_GETSERVICEBYGUID = 50,
+ API_SERVICE_SERVICE_LOCK = 60,
+ API_SERVICE_SERVICE_CLIENTLOCK = 70,
+ API_SERVICE_SERVICE_RELEASE = 80,
+ API_SERVICE_SERVICE_GETTYPENAME = 90,
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ API_SERVICE_SERVICE_GETOWNINGCOMPONENT = 100,
+ API_SERVICE_SERVICE_GETLOCKINGCOMPONENT = 110,
+#endif // WASABI_COMPILE_COMPONENTS
+
+ API_SERVICE_SERVICE_UNLOCK = 120,
+ API_SERVICE_ISVALID = 130,
+ API_SERVICE_COMPACT_DUPLICATES = 140,
+ };
+ };
+
+// ----------------------------------------------------------------------------
+
+ inline int api_service::service_register( waServiceFactory *svc )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_REGISTER, (int)0, svc );
+ return __retval;
+ }
+
+ inline int api_service::service_deregister( waServiceFactory *svc )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_DEREGISTER, (int)0, svc );
+ return __retval;
+ }
+
+ inline size_t api_service::service_getNumServices( FOURCC svc_type )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_GETNUMSERVICES, (int)0, svc_type );
+ return __retval;
+ }
+
+ inline waServiceFactory *api_service::service_enumService( FOURCC svc_type, size_t n )
+ {
+ waServiceFactory *__retval = _call( API_SERVICE_SERVICE_ENUMSERVICE, (waServiceFactory *)0, svc_type, n );
+ return __retval;
+ }
+
+ inline waServiceFactory *api_service::service_getServiceByGuid( GUID guid )
+ {
+ waServiceFactory *__retval = _call( API_SERVICE_SERVICE_GETSERVICEBYGUID, (waServiceFactory *)0, guid );
+ return __retval;
+ }
+
+ inline int api_service::service_lock( waServiceFactory *owner, void *svcptr )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_LOCK, (int)0, owner, svcptr );
+ return __retval;
+ }
+
+ inline int api_service::service_clientLock( void *svcptr )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_CLIENTLOCK, (int)0, svcptr );
+ return __retval;
+ }
+
+ inline int api_service::service_release( void *svcptr )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_RELEASE, (int)0, svcptr );
+ return __retval;
+ }
+
+ inline const char *api_service::service_getTypeName( FOURCC svc_type )
+ {
+ const char *__retval = _call( API_SERVICE_SERVICE_GETTYPENAME, (const char *)0, svc_type );
+ return __retval;
+ }
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ inline GUID api_service::service_getOwningComponent( void *svcptr )
+ {
+ GUID __retval = _call( API_SERVICE_SERVICE_GETOWNINGCOMPONENT, INVALID_GUID, svcptr );
+ return __retval;
+ }
+
+ inline GUID api_service::service_getLockingComponent( void *svcptr )
+ {
+ GUID __retval = _call( API_SERVICE_SERVICE_GETLOCKINGCOMPONENT, INVALID_GUID, svcptr );
+ return __retval;
+ }
+#endif // WASABI_COMPILE_COMPONENTS
+
+ inline int api_service::service_unlock( void *svcptr )
+ {
+ int __retval = _call( API_SERVICE_SERVICE_UNLOCK, (int)0, svcptr );
+ return __retval;
+ }
+
+ inline int api_service::service_isvalid( FOURCC svctype, waServiceFactory *service )
+ {
+ int __retval = _call( API_SERVICE_ISVALID, (int)0, svctype, service );
+ return __retval;
+ }
+
+ inline int api_service::service_compactDuplicates( waServiceFactory *me )
+ {
+ return _call( API_SERVICE_COMPACT_DUPLICATES, (int)1, me );
+ }
+// ----------------------------------------------------------------------------
+
+
+extern api_service *serviceApi;
+
+#ifndef WASABI_API_SVC
+#define WASABI_API_SVC serviceApi
+#endif // !WASABI_API_SVC
+
+#endif // __API_SERVICE_H
diff --git a/Src/Wasabi/api/service/api_servicei.cpp b/Src/Wasabi/api/service/api_servicei.cpp
new file mode 100644
index 00000000..e5cae440
--- /dev/null
+++ b/Src/Wasabi/api/service/api_servicei.cpp
@@ -0,0 +1,83 @@
+#include <precomp.h>
+#ifndef NOSVCMGR
+//<?#include "<class data="implementationheader"/>"
+#include "api_servicei.h"
+//?>
+
+#include <api/api.h>
+#include <api/service/svcmgr.h>
+
+api_service *serviceApi = NULL;
+
+api_serviceI::api_serviceI() {
+}
+
+api_serviceI::~api_serviceI() {
+ ServiceManager::onShutdown();
+}
+
+int api_serviceI::service_register(waServiceFactory *svc) {
+#ifdef WASABI_COMPILE_COMPONENTS
+ int r = ServiceManager::registerService(svc, WASABI_API_COMPONENT->getThisGuid());
+#else
+ int r = ServiceManager::registerService(svc, WASABI_API_APP->main_getGUID());
+#endif
+ return r;
+}
+
+int api_serviceI::service_deregister(waServiceFactory *svc) {
+ int r = ServiceManager::deregisterService(svc);
+ return r;
+}
+
+int api_serviceI::service_getNumServices(FOURCC svc_type) {
+ return ServiceManager::getNumServices(svc_type);
+}
+
+waServiceFactory *api_serviceI::service_enumService(FOURCC svc_type, int n) {
+ return ServiceManager::enumService(svc_type, n);
+}
+
+waServiceFactory *api_serviceI::service_getServiceByGuid(GUID guid) {
+ return ServiceManager::getServiceByGuid(guid);
+}
+
+
+int api_serviceI::service_lock(waServiceFactory *owner, void *svcptr) {
+ return ServiceManager::lock(owner, svcptr);
+}
+
+int api_serviceI::service_clientLock(void *svcptr) {
+#ifdef WASABI_COMPILE_COMPONENTS
+ return ServiceManager::clientLock(svcptr, WASABI_API_COMPONENT->getThisGuid());
+#else
+ return ServiceManager::clientLock(svcptr, WASABI_API_APP->main_getGUID());
+#endif
+}
+
+int api_serviceI::service_release(void *svcptr) {
+ return ServiceManager::release(svcptr);
+}
+
+const char *api_serviceI::service_getTypeName(FOURCC svc_type) {
+ return ServiceManager::getServiceTypeName(svc_type);
+}
+
+#ifdef WASABI_COMPILE_COMPONENTS
+GUID api_serviceI::service_getOwningComponent(void *svcptr) {
+ return ServiceManager::getOwningComponent(svcptr);
+}
+
+GUID api_serviceI::service_getLockingComponent(void *svcptr) {
+ return ServiceManager::getLockingComponent(svcptr);
+}
+#endif
+
+int api_serviceI::service_unlock(void *svcptr) {
+ return ServiceManager::unlock(svcptr);
+}
+
+int api_serviceI::service_isvalid(FOURCC svctype, waServiceFactory *service) {
+ return ServiceManager::isValidService(svctype, service);
+}
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/service/api_servicei.h b/Src/Wasabi/api/service/api_servicei.h
new file mode 100644
index 00000000..f50ceaa6
--- /dev/null
+++ b/Src/Wasabi/api/service/api_servicei.h
@@ -0,0 +1,150 @@
+#ifndef __SERVICE_APII_IMPL_H
+#define __SERVICE_APII_IMPL_H
+
+/*<?<autoheader/>*/
+#include "api_service.h"
+#include "api_servicex.h"
+
+class waServiceFactory;
+/*?>*/
+
+class api_serviceI : public api_serviceX {
+public:
+ NODISPATCH api_serviceI();
+ NODISPATCH virtual ~api_serviceI();
+
+// services
+ /**
+ Register a service. Service registration is done
+ on creation of the WAC.
+
+ @see WAComponentClient
+ @ret 1, success; 0, failure.
+ @param p Pointer to your service factory.
+ */
+ DISPATCH(10) int service_register(waServiceFactory *svc);
+
+ /**
+ Deregister a service. Service deregistration is done
+ on destruction of the WAC.
+
+ @see WAComponentClient
+ @ret 1, success; 0, failure.
+ @param p Pointer to your service factory.
+ */
+ DISPATCH(20) int service_deregister(waServiceFactory *svc);
+
+ /**
+ Get the number of services registered for a specific
+ service type. This should only be called after
+ Wasabi is fully started (after WAC creation).
+
+ @see FOURCC
+ @ret Number of services present in that service type.
+ @param svc_type Service type.
+ */
+ DISPATCH(30) int service_getNumServices(FOURCC svc_type); // see common/svc_enum.h
+
+ // enumerate by family
+ /**
+ Enumerate services by family. This should only
+ be called after Wasabi is fully started (after WAC creation).
+
+ @see FOURCC
+ @ret Requested service.
+ @param svc_type Service type.
+ @param n Number of the service.
+ */
+ DISPATCH(40) waServiceFactory *service_enumService(FOURCC svc_type, int n);
+
+ // fetch by GUID
+ /**
+ Get a service by it's GUID. This should only
+ be called after Wasabi is fully started (after WAC creation).
+
+ @ret Requested service.
+ @param guid Service GUID.
+ */
+ DISPATCH(50) waServiceFactory *service_getServiceByGuid(GUID guid);
+
+ // service owner calls this when it issues a service *
+ /**
+ Lock a service. Service owner must call this when
+ it issues a new service pointer to a client.
+
+ @ret 1, success; 0, failure;
+ @param owner Service owner.
+ @param svcptr Service pointer returned to client.
+ */
+ DISPATCH(60) int service_lock(waServiceFactory *owner, void *svcptr);
+
+ // service client calls this when it uses a service *
+ /**
+ ClientLock a service. Service client must call
+ this before using the service.
+
+ @ret 1, success; 0, failure;
+ @param svcptr Service pointer.
+ */
+ DISPATCH(70) int service_clientLock(void *svcptr);
+
+ // service client calls this when done w/ service *
+ /**
+ Release a service. Service client must call this
+ when he's finished using the service. If the service
+ is NOT released it will cause improper shutdown of
+ the service.
+
+ @ret 1, success; 0, failure;
+ */
+ DISPATCH(80) int service_release(void *svcptr);
+ /**
+ Get the pretty printed type name of a service type based
+ on it's FOURCC.
+
+ @see FOURCC
+ @ret Service name (readable).
+ @param svc_type Service type.
+ */
+ DISPATCH(90) const char *service_getTypeName(FOURCC svc_type);
+
+#ifdef WASABI_COMPILE_COMPONENTS
+
+/*[interface.service_getOwningComponent.cpp]#ifdef WASABI_COMPILE_COMPONENTS*/
+/*[interface.service_getOwningComponent.h]#ifdef WASABI_COMPILE_COMPONENTS*/
+/*[dispatchable.service_getOwningComponent.enum]#ifdef WASABI_COMPILE_COMPONENTS*/
+/*[dispatchable.service_getOwningComponent.bridge]#ifdef WASABI_COMPILE_COMPONENTS*/
+ /**
+ Get the owning component of a service from
+ a service pointer.
+
+ @ret GUID of the owning component.
+ @param svcptr Service pointer.
+ */
+ DISPATCH(100) GUID service_getOwningComponent(void *svcptr);
+
+ /**
+ Get the locking component for a service from
+ a service pointer.
+
+ @ret GUID of the locking component.
+ @param svcptr Service pointer.
+ */
+ DISPATCH(110) GUID service_getLockingComponent(void *svcptr);
+
+/*[interface.service_unlock.cpp]#endif // WASABI_COMPILE_COMPONENTS*/
+/*[interface.service_unlock.h]#endif // WASABI_COMPILE_COMPONENTS*/
+/*[dispatchable.service_unlock.enum]#endif // WASABI_COMPILE_COMPONENTS*/
+/*[dispatchable.service_unlock.bridge]#endif // WASABI_COMPILE_COMPONENTS*/
+#endif
+
+ DISPATCH(120) int service_unlock(void *svcptr);
+
+ DISPATCH(130) int service_isvalid(FOURCC svctype, waServiceFactory *service);
+};
+
+/*[interface.footer.h]
+extern api_service *serviceApi;
+*/
+
+#endif // __SERVICE_APII_IMPL_H
diff --git a/Src/Wasabi/api/service/api_servicex.cpp b/Src/Wasabi/api/service/api_servicex.cpp
new file mode 100644
index 00000000..cc275b3f
--- /dev/null
+++ b/Src/Wasabi/api/service/api_servicex.cpp
@@ -0,0 +1,35 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:56:11 2003]
+//
+// File : api_servicex.cpp
+// Class : api_service
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+#ifndef NOSVCMGR
+#include "api_servicex.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_serviceX
+START_DISPATCH;
+ CB(API_SERVICE_SERVICE_REGISTER, service_register);
+ CB(API_SERVICE_SERVICE_DEREGISTER, service_deregister);
+ CB(API_SERVICE_SERVICE_GETNUMSERVICES, service_getNumServices);
+ CB(API_SERVICE_SERVICE_ENUMSERVICE, service_enumService);
+ CB(API_SERVICE_SERVICE_GETSERVICEBYGUID, service_getServiceByGuid);
+ CB(API_SERVICE_SERVICE_LOCK, service_lock);
+ CB(API_SERVICE_SERVICE_CLIENTLOCK, service_clientLock);
+ CB(API_SERVICE_SERVICE_RELEASE, service_release);
+ CB(API_SERVICE_SERVICE_GETTYPENAME, service_getTypeName);
+ #ifdef WASABI_COMPILE_COMPONENTS
+ CB(API_SERVICE_SERVICE_GETOWNINGCOMPONENT, service_getOwningComponent);
+ CB(API_SERVICE_SERVICE_GETLOCKINGCOMPONENT, service_getLockingComponent);
+ #endif // WASABI_COMPILE_COMPONENTS
+ CB(API_SERVICE_SERVICE_UNLOCK, service_unlock);
+ CB(API_SERVICE_ISVALID, service_isvalid);
+END_DISPATCH;
+#undef CBCLASS
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/service/api_servicex.h b/Src/Wasabi/api/service/api_servicex.h
new file mode 100644
index 00000000..650d6b97
--- /dev/null
+++ b/Src/Wasabi/api/service/api_servicex.h
@@ -0,0 +1,44 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:56:11 2003]
+//
+// File : api_servicex.h
+// Class : api_service
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_SERVICEX_H
+#define __API_SERVICEX_H
+
+#include "api_service.h"
+
+class waServiceFactory;
+
+
+
+// ----------------------------------------------------------------------------
+
+class api_serviceX : public api_service {
+ protected:
+ api_serviceX() {}
+ public:
+ virtual int service_register(waServiceFactory *svc)=0;
+ virtual int service_deregister(waServiceFactory *svc)=0;
+ virtual int service_getNumServices(FOURCC svc_type)=0;
+ virtual waServiceFactory *service_enumService(FOURCC svc_type, int n)=0;
+ virtual waServiceFactory *service_getServiceByGuid(GUID guid)=0;
+ virtual int service_lock(waServiceFactory *owner, void *svcptr)=0;
+ virtual int service_clientLock(void *svcptr)=0;
+ virtual int service_release(void *svcptr)=0;
+ virtual const char *service_getTypeName(FOURCC svc_type)=0;
+ #ifdef WASABI_COMPILE_COMPONENTS
+ virtual GUID service_getOwningComponent(void *svcptr)=0;
+ virtual GUID service_getLockingComponent(void *svcptr)=0;
+ #endif // WASABI_COMPILE_COMPONENTS
+ virtual int service_unlock(void *svcptr)=0;
+ virtual int service_isvalid(FOURCC svctype, waServiceFactory *service)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_SERVICEX_H
diff --git a/Src/Wasabi/api/service/service.h b/Src/Wasabi/api/service/service.h
new file mode 100644
index 00000000..4ef710a6
--- /dev/null
+++ b/Src/Wasabi/api/service/service.h
@@ -0,0 +1,16 @@
+#ifndef _SERVICE_H
+#define _SERVICE_H
+
+// this file defines the wasabi service factory class. this isn't the actual
+// service, just the interface to get the service pointer
+
+#include <bfc/dispatch.h>
+#include "services.h"
+
+#include "waservicefactory.h"
+#include "waservicefactorybase.h"
+#include "waservicefactoryt.h"
+#include "waservicefactorytsingle.h"
+
+
+#endif
diff --git a/Src/Wasabi/api/service/servicei.cpp b/Src/Wasabi/api/service/servicei.cpp
new file mode 100644
index 00000000..e3d87fca
--- /dev/null
+++ b/Src/Wasabi/api/service/servicei.cpp
@@ -0,0 +1,5 @@
+
+#include <precomp.h>
+#include "servicei.h"
+
+
diff --git a/Src/Wasabi/api/service/servicei.h b/Src/Wasabi/api/service/servicei.h
new file mode 100644
index 00000000..9d2bcc1b
--- /dev/null
+++ b/Src/Wasabi/api/service/servicei.h
@@ -0,0 +1,180 @@
+#ifndef _SERVICEI_H
+#define _SERVICEI_H
+
+// here is where we define some helper implementations of the service factory
+// interface
+
+#include "service.h"
+
+#include "waservicefactoryi.h"
+#include "waservicefactorybase.h"
+#include "waservicefactoryt.h"
+#include "waservicefactorytsingle.h"
+#include <bfc/ptrlist.h>
+#include <bfc/foreach.h>
+
+// DEPRECATED
+#define waService waServiceFactory
+#define waServiceT waServiceFactoryT
+#define waServiceTSingle waServiceFactoryTSingle
+
+// Declaring services via macros
+// ie:
+// BEGIN_SERVICES(YourClass_Svc)
+// DECLARE_SERVICE(SomeSvcCreator<YourServiceClass1>);
+// DECLARE_SERVICE(SomeSvcCreator<YourServiceClass2>);
+// DECLARE_SERVICE(SomeSvcCreator<YourServiceClass3>);
+// DECLARE_SERVICETMULTI(svc_serviceclass, YourMultiInstanceServiceClass1>);
+// DECLARE_SERVICETMULTI(svc_serviceclass, YourMultiInstanceServiceClass2>);
+// DECLARE_SERVICETMULTI(svc_serviceclass, YourMultiInstanceServiceClass3>);
+// DECLARE_SERVICETSINGLE(svc_serviceclass, YourSingleInstanceServiceClass1>);
+// DECLARE_SERVICETSINGLE(svc_serviceclass, YourSingleInstanceServiceClass2>);
+// DECLARE_SERVICETSINGLE(svc_serviceclass, YourSingleInstanceServiceClass3>);
+// END_SERVICES(YourClass_Svc, _YourClass_Svc);
+
+// The macro DECLARE_MODULE_SVCMGR should be defined in your main cpp file if you are compiling
+// a standalone exe without using the Application class. In this case you should also add
+// MODULE_SVCMGR_ONINIT(); in your app startup and MODULE_SVCMGR_ONSHUTDOWN() in your app shutdown
+// (class Application does this already)
+
+// You can use BEGIN_SYS_SERVICES to declare a service that is initialized in priority and
+// shutdown late (normal version inits late, shutdowns early)
+
+
+class StaticServices {
+ public:
+ virtual void registerServices()=0;
+ virtual void unregisterServices()=0;
+};
+
+class AutoServiceList : public PtrList<StaticServices> {
+ public:
+ AutoServiceList()
+ {
+#ifdef _WIN32 // PORT ME
+ OutputDebugStringA(">\n");
+#endif
+ }
+};
+
+class StaticServiceMgr {
+ public:
+ AutoServiceList __m_modules;
+ AutoServiceList __m_modules2;
+};
+
+#define DECLARE_MODULE_SVCMGR StaticServiceMgr *staticServiceMgr = NULL;
+
+extern StaticServiceMgr *staticServiceMgr;
+
+#define MODULE_SVCMGR_ONINIT() { \
+foreach(staticServiceMgr->__m_modules) \
+ staticServiceMgr->__m_modules.getfor()->registerServices(); \
+endfor; \
+}
+
+#define MODULE_SVCMGR_ONINIT2() { \
+foreach(staticServiceMgr->__m_modules2) \
+ staticServiceMgr->__m_modules2.getfor()->registerServices(); \
+endfor; \
+}
+
+#define MODULE_SVCMGR_ONSHUTDOWN() { \
+foreach(staticServiceMgr->__m_modules) \
+ staticServiceMgr->__m_modules.getfor()->unregisterServices(); \
+endfor; \
+}
+
+#define MODULE_SVCMGR_ONSHUTDOWN2() { \
+foreach(staticServiceMgr->__m_modules2) \
+ staticServiceMgr->__m_modules2.getfor()->unregisterServices(); \
+endfor; \
+}
+
+#define INIT_MODULE_SVCMGR() \
+ if (!staticServiceMgr) staticServiceMgr = new StaticServiceMgr;
+
+#define BEGIN_SERVICES(CLASSNAME) \
+class CLASSNAME : public StaticServices { \
+public: \
+ CLASSNAME() { \
+ INIT_MODULE_SVCMGR() \
+ staticServiceMgr->__m_modules.addItem(this); \
+ } \
+ virtual ~CLASSNAME() {} \
+ virtual void registerServices() { \
+ ASSERT(staticServiceMgr);
+
+#define BEGIN_SERVICES_DEBUG(CLASSNAME, TEXT) \
+class CLASSNAME : public StaticServices { \
+public: \
+ CLASSNAME() { \
+ INIT_MODULE_SVCMGR() \
+ OutputDebugString("Registering "); \
+ OutputDebugString(TEXT); \
+ OutputDebugString("\n"); \
+ staticServiceMgr->__m_modules.addItem(this); \
+ } \
+ virtual ~CLASSNAME() {} \
+ virtual void registerServices() { \
+ ASSERT(staticServiceMgr);
+
+#define BEGIN_SYS_SERVICES(CLASSNAME) \
+class CLASSNAME : public StaticServices { \
+public: \
+ CLASSNAME() { \
+ INIT_MODULE_SVCMGR() \
+ staticServiceMgr->__m_modules2.addItem(this); \
+ } \
+ virtual ~CLASSNAME() {} \
+ virtual void registerServices() {
+
+#define DECLARE_SERVICE(INSTANTIATIONCODE) \
+ registerService(new INSTANTIATIONCODE);
+
+#define DECLARE_SERVICE_DEBUG(INSTANTIATIONCODE, TEXT) \
+ OutputDebugString("Starting "); \
+ OutputDebugString(TEXT); \
+ OutputDebugString("\n"); \
+ registerService(new INSTANTIATIONCODE);
+
+#define DECLARE_SERVICETMULTI(SVCTYPE, SVCCLASS) \
+ registerService(new waServiceFactoryT<SVCTYPE, SVCCLASS>);
+
+#define DECLARE_SERVICETMULTI_DEBUG(SVCTYPE, SVCCLASS, TEXT) \
+ OutputDebugString("Starting "); \
+ OutputDebugString(TEXT); \
+ OutputDebugString("\n"); \
+ registerService(new waServiceFactoryT<SVCTYPE, SVCCLASS>);
+
+#define DECLARE_SERVICETSINGLE(SVCTYPE, SVCCLASS) \
+ registerService(new waServiceFactoryTSingle<SVCTYPE, SVCCLASS>);
+
+#define DECLARE_SERVICETSINGLE_DEBUG(SVCTYPE, SVCCLASS, TEXT) \
+ OutputDebugString("Starting "); \
+ OutputDebugString(TEXT); \
+ OutputDebugString("\n"); \
+ registerService(new waServiceFactoryTSingle<SVCTYPE, SVCCLASS>, TEXT);
+
+#define END_SERVICES(CLASSNAME, INSTANCENAME) \
+ } \
+ virtual void unregisterServices() { \
+ foreach(services) \
+ waServiceFactoryI *svc = services.getfor(); \
+ WASABI_API_SVC->service_deregister(svc); \
+ delete svc; \
+ endfor; \
+ services.removeAll();\
+ } \
+private: \
+ void registerService(waServiceFactoryI *svc) { \
+ if (svc != NULL) { \
+ services.addItem(svc); \
+ WASABI_API_SVC->service_register(svc); \
+ } \
+ } \
+ PtrList<waServiceFactoryI> services; \
+}; \
+CLASSNAME INSTANCENAME;
+
+#endif
diff --git a/Src/Wasabi/api/service/services.h b/Src/Wasabi/api/service/services.h
new file mode 100644
index 00000000..ab044459
--- /dev/null
+++ b/Src/Wasabi/api/service/services.h
@@ -0,0 +1,76 @@
+#ifndef _SERVICES_H
+#define _SERVICES_H
+
+#include "bfc/std_mkncc.h" // for MKnCC()
+
+// lower-case service names are reserved by Nullsoft for future use
+// upper-case service names are for 3rd parties to extend the service system
+
+// if you have a service that is unique to a component, make it type
+// UNIQUE and register it by GUID
+
+
+namespace WaSvc
+{
+ enum
+ {
+ NONE = MK4CC( 'n', 'o', 'n', 'e' ),
+ UNIQUE = MK4CC( 'u', 'n', 'i', 'q' ), // for unique services, enumed by GUID
+ OBJECT = MK4CC( 'o', 'b', 'j', 'f' ), // for unique objects, enumed by GUID
+ CONTEXTCMD = MK4CC( 'c', 'c', 'm', 'd' ), // context menu command svc_contextCmd.h
+ DEVICE = MK3CC( 'd', 'e', 'v' ), // portable device svc_device.h
+ FILEREADER = MK4CC( 'f', 's', 'r', 'd' ), // file system reader (disk, zip, http)
+ FILESELECTOR = MK4CC( 'f', 's', 'e', 'l' ), // file selector svc_filesel.h
+ STORAGEVOLENUM = MK4CC( 'f', 's', 'e', 'n' ), // storage volume enumerator.
+ IMAGEGENERATOR = MK4CC( 'i', 'm', 'g', 'n' ), // image generator svc_imggen.h
+ IMAGELOADER = MK4CC( 'i', 'm', 'g', 'l' ), // image loader svc_imgload.h
+ IMAGEWRITER = MK4CC( 'i', 'm', 'g', 'w' ), // image writer
+ ITEMMANAGER = MK4CC( 'i', 'm', 'g', 'r' ), // item manager svc_itemmgr.h
+ PLAYLISTREADER = MK4CC( 'p', 'l', 'r', 'd' ), // playlist reader - DEPRECATED - only for wa3
+ PLAYLISTWRITER = MK4CC( 'p', 'l', 'w', 'r' ), // playlist writer - DEPRECATED - only for wa3
+ MEDIACONVERTER = MK4CC( 'c', 'o', 'n', 'v' ), // media converter
+ MEDIACORE = MK4CC( 'c', 'o', 'r', 'e' ), // media core
+ MEDIARECORDER = MK4CC( 'm', 'r', 'e', 'c' ), // media recorder
+ SCRIPTOBJECT = MK4CC( 'm', 'a', 'k', 'i' ), // third party script object
+ // TRANSLATOR=MK4CC('x','l','a','t'), // text translator
+ WINDOWCREATE = MK4CC( 'w', 'n', 'd', 'c' ), // window creator
+ XMLPROVIDER = MK4CC( 'x', 'm', 'l', 'p' ), // xml provider
+ DB = MK2CC( 'd', 'b' ), // database
+ SKINFILTER = MK4CC( 'f', 'l', 't', 'r' ), // bitmap/colorref skin filter
+ METADATA = MK4CC( 'm', 't', 'd', 't' ), // play item meta data
+ METATAG = MK4CC( 'm', 't', 't', 'g' ), // metadata tagging of play items
+ EVALUATOR = MK4CC( 'e', 'v', 'a', 'l' ), // evaluate a string
+ MINIBROWSER = MK2CC( 'm', 'b' ), // minibrowser
+ TOOLTIPSRENDERER = MK4CC( 't', 't', 'i', 'p' ), // tooltips renderer
+ XUIOBJECT = MK4CC( 'x', 'u', 'i', 'o' ), // xml gui objects
+ STRINGCONVERTER = MK4CC( 'u', 't', 'f', '8' ), // unicode string conversion
+ ACTION = MK3CC( 'a', 'c', 't' ), // custom actions (ie: for buttons)
+ COREADMIN = MK4CC( 'c', 'a', 'd', 'm' ), // core administrator
+ DROPTARGET = MK4CC( 'd', 'r', 'o', 'p' ), // drop targets
+ OBJECTDIR = MK4CC( 'o', 'b', 'j', 'd' ), // object directory
+ TEXTFEED = MK4CC( 't', 'x', 't', 'f' ), // text feed, to send text to various XUI objects (ie: <Text> by using display="textfeedid"
+ ACCESSIBILITY = MK4CC( 'a', 'c', 'c', 's' ), // accessibility service
+ ACCESSIBILITYROLESERVER = MK4CC( 'r', 'o', 'l', 'e' ), // accessibility roleServer services
+ EXPORTER = MK3CC( 'e', 'x', 'p' ), // exporter
+ COLLECTION = MK4CC( 'c', 'l', 'c', 't' ), // named xml overridable collection
+ REDIRECT = MK4CC( 'r', 'e', 'd', 'r' ), // filename redirect
+ FONTRENDER = MK4CC( 'f', 'o', 'n', 't' ), // font renderer (bitmap/truetype/freetype)
+ SRCCLASSFACTORY = MK4CC( 'c', 'l', 'f', 'a' ), // source code class factory
+ SRCEDITOR = MK4CC( 's', 'e', 'd', 't' ), // source code editor
+ MP4AUDIODECODER = MK4CC( 'm', '4', 'a', 'd' ), // mp4 audio decoder
+ MP4VIDEODECODER = MK4CC( 'm', '4', 'v', 'd' ), // mp4 audio decoder
+ PLAYLISTREADER_WA5 = MK4CC( 'p', 'l', 'r', '5' ), // playlist reader
+ PLAYLISTWRITER_WA5 = MK4CC( 'p', 'l', 'w', '5' ), // playlist writer
+ PLAYLISTHANDLER = MK3CC( 'p', 'l', 'h' ), // playlist handler
+ TAGPROVIDER = MK4CC( 't', 'a', 'g', 'z' ), // tag provider (for ATF engine)
+ NSVFACTORY = MK4CC( 'n', 's', 'v', 'f' ), // NSV factory (to create NSV objects)
+ JSAPI2_APICREATOR = MK4CC( 'j', 's', 'a', 'c' ), // API Creator for the Javascript API
+ MKVDECODER = MK3CC( 'm', 'k', 'v' ), // MKV factory (to create MKV decoder objects)
+ FLVDECODER = MK3CC( 'f', 'l', 'v' ), // FLV factory (to create FLV decoder objects)
+ AVIDECODER = MK3CC( 'a', 'v', 'i' ), // AVI factory (to create AVI decoder objects)
+ OGGDECODER = MK3CC( 'o', 'g', 'g' ), // Ogg factory (to create Ogg decoder objects)
+ MP4DECODER = MK3CC( 'm', 'p', '4' ), // MP4 factory (to create MP4 decoder objects)
+ };
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svc_enum.cpp b/Src/Wasabi/api/service/svc_enum.cpp
new file mode 100644
index 00000000..8ca8a1af
--- /dev/null
+++ b/Src/Wasabi/api/service/svc_enum.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "svc_enum.h"
diff --git a/Src/Wasabi/api/service/svc_enum.h b/Src/Wasabi/api/service/svc_enum.h
new file mode 100644
index 00000000..40f5c651
--- /dev/null
+++ b/Src/Wasabi/api/service/svc_enum.h
@@ -0,0 +1,24 @@
+#ifndef _SVC_ENUM_H
+#define _SVC_ENUM_H
+
+// try to use this one, it does a clientLock for you
+#include <api/service/waservicefactory.h>
+template <class T>
+class castService {
+public:
+ castService(waServiceFactory *w, int global_lock=TRUE) : was(w), gl(global_lock) { }
+ operator T *() {
+ if (was == NULL) return NULL;
+ T *ret = static_cast<T *>(was->getInterface(gl));
+ return ret;
+ }
+private:
+ waServiceFactory *was;
+ int gl;
+};
+
+#include "svcenumbyguid.h"
+#include "svcenum.h"
+#include "svcenumt.h"
+
+#endif
diff --git a/Src/Wasabi/api/service/svccache.cpp b/Src/Wasabi/api/service/svccache.cpp
new file mode 100644
index 00000000..af3e47cf
--- /dev/null
+++ b/Src/Wasabi/api/service/svccache.cpp
@@ -0,0 +1,35 @@
+#include <precomp.h>
+#include "svccache.h"
+#include <bfc/string/bfcstring.h>
+
+#if !defined(WASABI_API_SVC)
+#error no no
+#endif
+
+SvcCache::SvcCache(FOURCC type) {
+ int p = 0;
+ list.setAutoSort(FALSE);
+ for (;;) {
+ waServiceFactory *svc = WASABI_API_SVC->service_enumService(type, p++);
+ if (svc == NULL) break;
+ const wchar_t *teststr = svc->getTestString();
+ if (teststr == NULL || *teststr == '\0') continue;
+//CUT DebugString("cachin %s\n", teststr);
+ list.addItem(svc);
+ }
+ list.setAutoSort(TRUE);
+}
+
+waServiceFactory *SvcCache::findServiceFactory(const wchar_t *searchval) {
+ return list.findItem(searchval);
+}
+
+int SvcCache::waServiceFactoryCompare::compareItem(waServiceFactory *p1, waServiceFactory* p2) {
+ int r = WCSICMP(p1->getTestString(), p2->getTestString());
+ if (r == 0) return CMP3(p1, p2);
+ return r;
+}
+
+int SvcCache::waServiceFactoryCompare::compareAttrib(const wchar_t *attrib, waServiceFactory *item) {
+ return WCSICMP(attrib, item->getTestString());
+}
diff --git a/Src/Wasabi/api/service/svccache.h b/Src/Wasabi/api/service/svccache.h
new file mode 100644
index 00000000..1e989e57
--- /dev/null
+++ b/Src/Wasabi/api/service/svccache.h
@@ -0,0 +1,43 @@
+#ifndef _SVC_CACHE_H
+#define _SVC_CACHE_H
+
+#include <api/service/svc_enum.h>
+#include <bfc/ptrlist.h>
+
+/**
+ This is a caching version of SvcEnum. Upon creation, it enumerates all
+ service factories in the family and keeps them in a list. Then you can
+ call findService() with a search string to quickly find the service you
+ want. If you don't have a search string, you can still use a SvcEnum.
+*/
+
+class SvcCache {
+protected:
+ SvcCache(FOURCC type);
+
+public:
+ waServiceFactory *findServiceFactory(const wchar_t *searchval);
+
+private:
+ class waServiceFactoryCompare {
+ public:
+ static int compareItem(waServiceFactory *p1, waServiceFactory* p2);
+ static int compareAttrib(const wchar_t *attrib, waServiceFactory *item);
+ };
+ PtrListQuickSorted<waServiceFactory, waServiceFactoryCompare> list;
+};
+
+template <class T>
+class SvcCacheT : public SvcCache {
+public:
+ SvcCacheT() : SvcCache(T::getServiceType()) { }
+
+ T *findService(const char *key, int global_lock=TRUE) {
+ waServiceFactory *sf = findServiceFactory(key);
+ if (sf == NULL) return NULL;
+ T *ret = castService<T>(sf, global_lock);
+ return ret;
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcenum.cpp b/Src/Wasabi/api/service/svcenum.cpp
new file mode 100644
index 00000000..f9219654
--- /dev/null
+++ b/Src/Wasabi/api/service/svcenum.cpp
@@ -0,0 +1,45 @@
+#include <precomp.h>
+
+//<?#include "<class data="implementationheader"/>"
+#include "svcenum.h"
+//?>
+
+
+#include <api/service/services.h>
+#include <api/service/waservicefactory.h>
+#include <bfc/bfc_assert.h>
+
+SvcEnum::SvcEnum() : type(WaSvc::NONE), factory(NULL) {
+ reset();
+}
+
+void *SvcEnum::_getNext(int global_lock) {
+ if (WASABI_API_SVC == NULL) return NULL;
+ for (;;) {
+ factory = WASABI_API_SVC->service_enumService(type, pos++);
+ if (factory == NULL) return NULL;
+ void *s = factory->getInterface(FALSE);// get but don't lock
+ if (s)
+ {
+ if (_testService(s)) {
+ if (global_lock)
+ WASABI_API_SVC->service_lock(factory, s); // lock in sys tables
+ return s;
+ }
+ factory->releaseInterface(s);
+ }
+ }
+}
+
+void SvcEnum::reset() {
+ pos = 0;
+ factory = NULL;
+}
+
+int SvcEnum::release(void *ptr) {
+ return WASABI_API_SVC->service_release(ptr);
+}
+
+waServiceFactory *SvcEnum::getLastFactory() {
+ return factory;
+}
diff --git a/Src/Wasabi/api/service/svcenum.h b/Src/Wasabi/api/service/svcenum.h
new file mode 100644
index 00000000..bdfbb7df
--- /dev/null
+++ b/Src/Wasabi/api/service/svcenum.h
@@ -0,0 +1,37 @@
+#ifndef _SVCENUM_H
+#define _SVCENUM_H
+
+
+/*<?<autoheader/>*/
+class waServiceFactory;
+/*?>*/
+
+// abstract base class
+class NOVTABLE SvcEnum {
+protected:
+ SvcEnum();
+
+ void *_getNext(int global_lock = TRUE);
+ void reset();
+
+ virtual int _testService(void *)=0;
+
+public:
+#ifdef ASSERTS_ENABLED
+ static int release(waServiceFactory *ptr) { ASSERTALWAYS("never ever call release() with a waServiceFactory * !!!"); return 0; }
+#endif
+ static int release(void *ptr);
+
+ waServiceFactory *getLastFactory();
+
+protected:
+ FOURCC type;
+
+private:
+ int pos;
+ waServiceFactory * factory;
+};
+
+
+#endif // _SVCENUM_H
+
diff --git a/Src/Wasabi/api/service/svcenumbyguid.cpp b/Src/Wasabi/api/service/svcenumbyguid.cpp
new file mode 100644
index 00000000..28b315a0
--- /dev/null
+++ b/Src/Wasabi/api/service/svcenumbyguid.cpp
@@ -0,0 +1,5 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "svcenumbyguid.h"
+//?>
+
diff --git a/Src/Wasabi/api/service/svcenumbyguid.h b/Src/Wasabi/api/service/svcenumbyguid.h
new file mode 100644
index 00000000..412523c3
--- /dev/null
+++ b/Src/Wasabi/api/service/svcenumbyguid.h
@@ -0,0 +1,37 @@
+#ifndef _SVCENUMBYGUID_H
+#define _SVCENUMBYGUID_H
+
+/*<?<autoheader/>*/
+/*?>*/
+
+#include "svc_enum.h"
+
+/*
+ * this is a helper class to fetch a service * by GUID
+ * usage: svc_something *svc = SvcEnumByGuid<svc_something>(svcguid);
+ * @short: Helper class to fetch unique service by GUID
+*/
+template <class SERVICETYPE>
+class SvcEnumByGuid {
+public:
+/**
+@param _guid The GUID of the service factory to fetch the service from.
+*/
+ SvcEnumByGuid() : guid(SERVICETYPE::getServiceGuid()) {}
+ SvcEnumByGuid(GUID _guid) : guid(_guid) {}
+
+/**
+@return The pointer to the service.
+*/
+ SERVICETYPE *getInterface() {
+ waServiceFactory *svc = WASABI_API_SVC->service_getServiceByGuid(guid);
+ return castService<SERVICETYPE>(svc);
+ }
+
+ operator SERVICETYPE *() { return getInterface(); }
+
+private:
+ GUID guid;
+};
+
+#endif // _SVCENUMBYGUID_H
diff --git a/Src/Wasabi/api/service/svcenumt.cpp b/Src/Wasabi/api/service/svcenumt.cpp
new file mode 100644
index 00000000..2fa45792
--- /dev/null
+++ b/Src/Wasabi/api/service/svcenumt.cpp
@@ -0,0 +1,5 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "svcenumt.h"
+//?>
+
diff --git a/Src/Wasabi/api/service/svcenumt.h b/Src/Wasabi/api/service/svcenumt.h
new file mode 100644
index 00000000..e423b542
--- /dev/null
+++ b/Src/Wasabi/api/service/svcenumt.h
@@ -0,0 +1,30 @@
+#ifndef _SVCENUMT_H
+#define _SVCENUMT_H
+
+#include "svcenum.h"
+
+template <class T>
+class SvcEnumT : private SvcEnum {
+protected:
+ SvcEnumT() { type = T::getServiceType(); }
+
+public:
+ void reset() { SvcEnum::reset(); }
+ T *getFirst(int global_lock = TRUE) { reset(); return getNext(global_lock); }
+ T *getNext(int global_lock = TRUE) { return static_cast<T*>(_getNext(global_lock)); }
+
+ // these would just be 'using' but msvc.net sucks butt
+ inline int release(void *ptr) { return SvcEnum::release(ptr); }
+ inline waServiceFactory *getLastFactory() { return SvcEnum::getLastFactory(); }
+
+protected:
+ // override this one (or don't if you want to return all of them)
+ virtual int testService(T *svc) { return TRUE; }
+
+private:
+ virtual int _testService(void *svc) {
+ return testService(static_cast<T *>(svc));
+ }
+};
+
+#endif // _SVCENUMT_H
diff --git a/Src/Wasabi/api/service/svcmgr.cpp b/Src/Wasabi/api/service/svcmgr.cpp
new file mode 100644
index 00000000..78eec802
--- /dev/null
+++ b/Src/Wasabi/api/service/svcmgr.cpp
@@ -0,0 +1,365 @@
+#include <precomp.h>
+#ifndef NOSVCMGR
+#include "svcmgr.h"
+
+#ifdef WASABI_COMPILE_COMPONENTS
+#include <api/wac/wac.h>
+#include <api/wac/compon.h>
+#endif
+
+#ifdef WASABI_COMPILE_SYSCB
+#include <api/syscb/cbmgr.h>
+#include <api/syscb/callbacks/syscb.h>
+#include <api/syscb/callbacks/svccb.h>
+#endif
+
+#include <bfc/multimap.h>
+#include <bfc/map.h>
+#include <bfc/critsec.h>
+
+static MultiMap<FOURCC, waServiceFactory> services;// list of factories by class
+static Map<waServiceFactory*, GUID> ownermap; // who presented it
+static Map<GUID, waServiceFactory*> services_by_guid;// unique services
+static Map<void *, waServiceFactory*> lockmap; // who to tell when it's unlocked
+//CUTstatic Map<void *, GUID> clientmap; // who locked it
+
+static CriticalSection cs;
+
+int ServiceManager::registerService(waServiceFactory *service, GUID owner) {
+ ASSERT(owner != INVALID_GUID);
+ if (owner == INVALID_GUID) return 0;
+ FOURCC svctype = service->getServiceType();
+ cs.enter();
+ if (!services.multiHaveItem(svctype, service)) {
+ services.multiAddItem(svctype, service);
+
+ ownermap.addItem(service, owner);
+
+ GUID svcguid = service->getGuid();
+ if (svcguid != INVALID_GUID) services_by_guid.addItem(svcguid, service);
+ }
+ cs.leave();
+
+ service->serviceNotify(SvcNotify::ONREGISTERED);
+
+ #ifdef WASABI_COMPILE_SYSCB
+ CallbackManager::issueCallback(SysCallback::SERVICE,
+ SvcCallback::ONREGISTER,
+ (int)svctype, reinterpret_cast<int>(service));
+ #endif
+
+ return 1;
+}
+
+int ServiceManager::deregisterService(waServiceFactory *service, int internal) {
+ FOURCC svctype = service->getServiceType();
+ // make sure it was there
+ cs.enter();
+ if (services.multiHaveItem(svctype, service)) {
+ // make sure there aren't still services issued by this guy
+// ASSERT(internal || !lockmap.reverseGetItem(service));
+ services.multiDelItem(svctype, service);
+ ownermap.delItem(service);
+ services_by_guid.reverseDelItem(service);
+ }
+ cs.leave();
+ service->serviceNotify(SvcNotify::ONDEREGISTERED);
+
+ #ifdef WASABI_COMPILE_SYSCB
+ CallbackManager::issueCallback(SysCallback::SERVICE,
+ SvcCallback::ONDEREGISTER,
+ (int)svctype, reinterpret_cast<int>(service));
+ #endif
+
+ return 1;
+}
+
+int ServiceManager::getNumServices(FOURCC svc_type) {
+ INCRITICALSECTION(cs);
+ return services.multiGetNumItems(svc_type);
+}
+
+int ServiceManager::getNumServices() {
+ return services.getNumItems();
+}
+
+waServiceFactory *ServiceManager::enumService(int n) {
+ return services_by_guid.enumItemByPos(n, NULL);
+}
+
+int ServiceManager::getNumOwners() {
+ return ownermap.getNumItems();
+}
+
+int ServiceManager::getNumServicesByGuid() {
+ return services_by_guid.getNumItems();
+}
+
+int ServiceManager::getNumLocks() {
+ return lockmap.getNumItems();
+}
+
+waServiceFactory *ServiceManager::enumService(FOURCC svc_type, int n) {
+ INCRITICALSECTION(cs);
+ waServiceFactory *ret = NULL;
+ services.multiGetItem(svc_type, n, &ret);
+ return ret;
+}
+
+waServiceFactory *ServiceManager::getServiceByGuid(GUID guid) {
+ INCRITICALSECTION(cs);
+ if (guid == INVALID_GUID) return NULL;
+ waServiceFactory *ret=NULL;
+ services_by_guid.getItem(guid, &ret);
+ return ret;
+}
+
+void ServiceManager::sendNotification(int msg, int param1, int param2) {
+ cs.enter();
+ for (int x = 0; x < services.multiGetNumPairs(); x++) {
+ for (int y = 0; ; y++) {
+ waServiceFactory *svc;
+ if (!services.multiGetItemDirect(x, y, &svc)) {
+ break;
+ }
+ svc->serviceNotify(msg, param1, param2);
+ }
+ }
+ cs.leave();
+#ifdef WASABI_COMPILE_COMPONENTS
+ // also notify components
+ for (int i = 0; ; i++) {
+ WaComponent *wac = ComponentManager::enumComponent(i);
+ if (wac == NULL) break;
+ wac->onNotify(WAC_NOTIFY_SERVICE_NOTIFY, msg, param1, param2);
+ }
+#endif
+ #ifdef WASABI_COMPILE_SYSCB
+ // and syscallbacks
+ CallbackManager::issueCallback(SysCallback::RUNLEVEL, msg);
+ #endif
+}
+
+int ServiceManager::lock(waServiceFactory *owner, void *svcptr) {
+ INCRITICALSECTION(cs);
+ if (owner == NULL || svcptr == NULL) return 0;
+ // we allow multiple entries for same service
+ lockmap.addItem(svcptr, owner);
+ return 1;
+}
+
+int ServiceManager::unlock(void *svcptr) {
+ if (svcptr == NULL) return 0;
+
+ waServiceFactory *wsvc = NULL;
+ cs.enter();
+ if (!lockmap.getItem(svcptr, &wsvc)) {
+ cs.leave();
+ DebugString("WARNING: got unlock with no lock record!");
+ return 0;
+ }
+
+ int r = lockmap.delItem(svcptr);
+ ASSERT(r);
+
+//CUT // this might fail, client locking isn't enforceable
+//CUT clientmap.delItem(svcptr);
+
+ cs.leave();
+
+ return 1;
+}
+
+int ServiceManager::clientLock(void *svcptr, GUID lockedby) {
+//CUT INCRITICALSECTION(cs);
+//CUT ASSERT(svcptr != NULL);
+//CUT if (svcptr == NULL) return 0;
+//CUT ASSERT(lockedby != INVALID_GUID);
+//CUT if (lockedby == INVALID_GUID) return 0;
+//CUT clientmap.addItem(svcptr, lockedby);
+ return 1;
+}
+
+int ServiceManager::release(void *svcptr) {
+ if (svcptr == NULL) return 0;
+
+ waServiceFactory *wsvc = NULL;
+ cs.enter(); // note cs getting locked twice via release+unlock
+ if (!lockmap.getItem(svcptr, &wsvc)) {
+ cs.leave();
+ DebugString("WARNING: got release with no lock record!");
+ return 0;
+ }
+ unlock(svcptr);
+ cs.leave();
+
+ ASSERT(wsvc != NULL);
+ return wsvc->releaseInterface(svcptr);
+}
+
+#ifdef WASABI_COMPILE_COMPONENTS
+GUID ServiceManager::getOwningComponent(void *svcptr) {
+ INCRITICALSECTION(cs);
+ GUID ret = INVALID_GUID;
+ waServiceFactory *svc=NULL;
+ if (lockmap.getItem(svcptr, &svc)) ownermap.getItem(svc, &ret);
+ return ret;
+}
+
+GUID ServiceManager::getLockingComponent(void *svcptr) {
+ INCRITICALSECTION(cs);
+ GUID ret = INVALID_GUID;
+//CUT clientmap.getItem(svcptr, &ret);
+ return ret;
+}
+#endif
+
+using namespace WaSvc;
+
+static struct {
+ FOURCC type;
+ const char *name;
+} svc_names[] = {
+ { DEVICE, "Portable Device" },
+ { FILEREADER, "File Reader" },
+ { FILESELECTOR, "File Selector" },
+ { IMAGEGENERATOR, "Image Generator" },
+ { IMAGELOADER, "Image Loader" },
+ { ITEMMANAGER, "Item Manager" },
+ { MEDIACONVERTER, "Media Converter" },
+ { MEDIACORE, "Media Core" },
+ { PLAYLISTREADER, "Playlist Reader" },
+ { PLAYLISTWRITER, "Playlist Writer" },
+ { SCRIPTOBJECT, "Script Class" },
+ { XMLPROVIDER, "XML Provider" },
+ { DB, "Database" },
+ { EVALUATOR, "Evaluator" },
+ { COREADMIN, "Core Administrator" },
+ { NONE, NULL }, // this one has to be last
+};
+
+const char *ServiceManager::getServiceTypeName(FOURCC svc_type) {
+ for (int i = 0; ; i++) {
+ if (svc_names[i].name == NULL) break;
+ if (svc_names[i].type == svc_type) return svc_names[i].name;
+ }
+ return NULL;
+}
+
+FOURCC ServiceManager::safe_getServiceType(waServiceFactory *was) {
+#ifndef _DEBUG
+ return 0;
+#endif
+ FOURCC type = 0;
+ _TRY
+ {
+ type = was->getServiceType();
+ }
+ _EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ OutputDebugString("EXCEPTION_EXECUTE_HANDLER\n");
+ }
+ return type;
+}
+
+const char *ServiceManager::safe_getServiceName(waServiceFactory *was) {
+#ifndef _DEBUG
+ return 0;
+#endif
+ const char *name = NULL;
+ _TRY
+ {
+ name = was->getServiceName();
+ }
+ _EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ OutputDebugString("EXCEPTION_EXECUTE_HANDLER\n");
+ }
+ return name;
+}
+
+void ServiceManager::onShutdown() {
+/*
+ ownermap.purge();
+ services.purge();
+ services_by_guid.purge();
+ clientmap.purge();
+*/
+
+ int nlocks = lockmap.getNumPairs();
+ if (nlocks <= 0) {
+ //lockmap.purge();
+ #ifdef GEN_FF // i need this to have clean session restart, feel free to remove the ifdef if you fgeel that should always be done
+ ownermap.deleteAll();
+ services.multiRemoveAll();
+ services_by_guid.deleteAll();
+ lockmap.deleteAll();
+ #endif
+ return;
+ }
+
+#ifndef _DEBUG
+ DebugString("-----------------\n");
+ for (int i = 0; i < nlocks; i++) {
+ void *ptr = lockmap.enumIndexByPos(i, NULL); ASSERT(ptr != NULL);
+ StringPrintf s("lock: %d type:'", (int)ptr);
+
+// GUID g = lockermap.enumItemByPos(i, INVALID_GUID);ASSERT(g != INVALID_GUID);
+// s += g;
+// WaComponent *wac = ComponentManager::getComponentFromGuid(g);
+
+ waServiceFactory *was=NULL;
+ was = lockmap.enumItemByPos(i, NULL);
+ ASSERT(was != NULL);
+ FOURCC type = safe_getServiceType(was);
+ const char *tname = ServiceManager::getServiceTypeName(type);
+ if (tname != NULL) {
+ s += tname;
+ } else {
+ FOURCC v = BSWAP(type);
+ unsigned char bleh[5]=" ";
+ MEMCPY(bleh, &v, 4);
+ s += String((char *)bleh);
+ }
+ s += "' from service:'";
+ s += safe_getServiceName(was);
+
+// s += " wac:";
+// if (wac) s += wac->getName();
+#ifdef WASABI_COMPILE_COMPONENTS
+ s += "' owned by:'";
+
+ GUID g = INVALID_GUID;
+ ownermap.getItem(was, &g);
+ if (g != INVALID_GUID) {
+ s += g;
+ WaComponent *wac = ComponentManager::getComponentFromGuid(g);
+ if (wac) s += wac->getName();
+ } else s += "(unregistered)";
+#else
+ GUID g;
+#endif
+
+ s += "' registered lock to '";
+ g = INVALID_GUID;
+ //clientmap.getItem(ptr, &g);
+ s += g;
+
+ s += "'\n";
+ DebugString(s.v());
+ }
+ DebugString("-----------------\n");
+#endif
+#ifdef GEN_FF // i need this to have clean session restart, feel free to remove the ifdef if you fgeel that should always be done
+ ownermap.deleteAll();
+ services.multiRemoveAll();
+ services_by_guid.deleteAll();
+ lockmap.deleteAll();
+#endif
+}
+
+int ServiceManager::isValidService(FOURCC svctype, waServiceFactory *service) {
+ INCRITICALSECTION(cs);
+ return services.multiHaveItem(svctype, service);
+}
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/service/svcmgr.h b/Src/Wasabi/api/service/svcmgr.h
new file mode 100644
index 00000000..a9bcdc66
--- /dev/null
+++ b/Src/Wasabi/api/service/svcmgr.h
@@ -0,0 +1,41 @@
+#ifndef _SVCMGR_H
+#define _SVCMGR_H
+
+#include <api/service/service.h>
+
+class ServiceManager {
+public:
+ static int registerService(waServiceFactory *service, GUID owner);
+ static int deregisterService(waServiceFactory *service, int internal = 0);
+
+ static int getNumServices(FOURCC svc_type);
+ static waServiceFactory *enumService(FOURCC svc_type, int n);
+
+ static waServiceFactory *getServiceByGuid(GUID guid);
+
+ static void sendNotification(int msg, int param1 = 0, int param2 = 0);
+
+ static int lock(waServiceFactory *owner, void *svcptr);
+ static int unlock(void *svcptr);
+ static int clientLock(void *svcptr, GUID lockedby);
+ static int release(void *svcptr);
+
+ static GUID getOwningComponent(void *svcptr);
+ static GUID getLockingComponent(void *svcptr);
+ static const char *getServiceTypeName(FOURCC svc_type);
+
+ static void onShutdown();
+
+ static FOURCC safe_getServiceType(waServiceFactory *was);
+ static const char *safe_getServiceName(waServiceFactory *was);
+
+ static int getNumServices();
+ static waServiceFactory *enumService(int n);
+ static int getNumServicesByGuid();
+ static int getNumOwners();
+ static int getNumLocks();
+
+ static int isValidService(FOURCC svctype, waServiceFactory *service);
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_accessibility.cpp b/Src/Wasabi/api/service/svcs/svc_accessibility.cpp
new file mode 100644
index 00000000..37e6287b
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_accessibility.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+#include "svc_accessibility.h"
+
+#define CBCLASS svc_accessibilityI
+START_DISPATCH;
+ CB(SVC_ACCESSIBILITY_CREATEACCESSIBLEOBJECT, createAccessibleObject);
+END_DISPATCH;
+#undef CBCLASS
+
+
diff --git a/Src/Wasabi/api/service/svcs/svc_accessibility.h b/Src/Wasabi/api/service/svcs/svc_accessibility.h
new file mode 100644
index 00000000..60ad0c30
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_accessibility.h
@@ -0,0 +1,43 @@
+#ifndef _SVC_ACCESSIBILITY_H
+#define _SVC_ACCESSIBILITY_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class Accessible;
+class ifc_window;
+
+class NOVTABLE svc_accessibility : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::ACCESSIBILITY; }
+
+ Accessible *createAccessibleObject(ifc_window *w);
+
+ enum {
+ SVC_ACCESSIBILITY_CREATEACCESSIBLEOBJECT=10,
+ };
+};
+
+inline Accessible *svc_accessibility::createAccessibleObject(ifc_window *w) {
+ return _call(SVC_ACCESSIBILITY_CREATEACCESSIBLEOBJECT, (Accessible *)NULL, w);
+}
+
+class NOVTABLE svc_accessibilityI: public svc_accessibility {
+ public:
+ virtual Accessible *createAccessibleObject(ifc_window *w)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class AccessibilityCreatorSingle : public waServiceFactoryTSingle<svc_accessibility, T> {
+public:
+ svc_accessibility *getHandler() {
+ return waServiceFactoryTSingle<svc_accessibility, T>::getSingleService();
+ }
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_accroleserver.cpp b/Src/Wasabi/api/service/svcs/svc_accroleserver.cpp
new file mode 100644
index 00000000..84bbaabf
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_accroleserver.cpp
@@ -0,0 +1,70 @@
+#include <precomp.h>
+
+#include "svc_accroleserver.h"
+#include <api/script/objects/guiobject.h>
+#include <api/wnd/api_window.h>
+
+#define CBCLASS svc_accRoleServerI
+START_DISPATCH;
+ CB(RS_HANDLEROLE, handleRole);
+ CB(RS_CREATEOBJECT, createObject);
+ VCB(RS_DESTROYOBJECT, destroyObject);
+END_DISPATCH;
+#undef CBCLASS
+
+
+#define CBCLASS roleServerObjectI
+START_DISPATCH;
+ CB(RSO_WNDPROC, wndProc);
+ CB(RSO_GETHWND, gethWnd);
+ CB(RSO_FLATTENCONTENT, flattenContent);
+END_DISPATCH;
+#undef CBCLASS
+
+
+roleServerObjectI::roleServerObjectI(HWND par, api_window *w) {
+ wnd = w;
+ hwnd = NULL;
+ parent = par;
+ triedyet = 0;
+}
+
+roleServerObjectI::~roleServerObjectI() {
+ if (hwnd != NULL)
+ DestroyWindow(hwnd);
+}
+
+api_window *roleServerObjectI::getWnd() {
+ return wnd;
+}
+
+HWND roleServerObjectI::gethWnd() {
+ if (!triedyet) {
+ triedyet = 1;
+ hwnd = createWindow(parent);
+ if (hwnd !=NULL)
+ oldproc = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);
+ else
+ oldproc = NULL;
+ }
+ return hwnd;
+}
+
+ScriptObject *roleServerObjectI::getScriptObject() {
+ if (wnd == NULL) return NULL;
+ GuiObject *go = wnd->getGuiObject();
+ if (go == NULL) return NULL;
+ return go->guiobject_getScriptObject();
+}
+
+WNDPROC roleServerObjectI::getOldProc() {
+ return oldproc;
+}
+
+int roleServerObjectI::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ return CallWindowProc(oldproc, hWnd, uMsg, wParam, lParam);
+}
+
+int roleServerObjectI::flattenContent(HWND *w) {
+ return FLATTENFLAG_ASKPARENT;
+}
diff --git a/Src/Wasabi/api/service/svcs/svc_accroleserver.h b/Src/Wasabi/api/service/svcs/svc_accroleserver.h
new file mode 100644
index 00000000..ad40c149
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_accroleserver.h
@@ -0,0 +1,132 @@
+#ifndef __SVC_ROLESERVER_H
+#define __SVC_ROLESERVER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/string.h>
+#include <bfc/ptrlist.h>
+#include <api/service/services.h>
+#include <api/script/scriptobj.h>
+
+class ifc_window;
+
+#define FLATTENFLAG_FLATTEN 1
+#define FLATTENFLAG_UNFLATTEN -1
+#define FLATTENFLAG_ASKPARENT 0
+
+class NOVTABLE roleServerObject : public Dispatchable {
+ public:
+ int wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ HWND gethWnd();
+ int flattenContent(HWND *w);
+
+ enum {
+ RSO_WNDPROC=0,
+ RSO_GETHWND=10,
+ RSO_FLATTENCONTENT=20,
+ };
+};
+
+inline int roleServerObject::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ return _call(RSO_WNDPROC, 0, hWnd, uMsg, wParam, lParam);
+}
+
+inline HWND roleServerObject::gethWnd() {
+ return _call(RSO_GETHWND, (HWND)NULL);
+}
+
+inline int roleServerObject::flattenContent(HWND *w) {
+ return _call(RSO_FLATTENCONTENT, 0, w);
+}
+
+class roleServerObjectI : public roleServerObject {
+ public:
+
+ roleServerObjectI(HWND parent, ifc_window *w);
+ virtual ~roleServerObjectI();
+
+ virtual int wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual HWND createWindow(HWND parent)=0;
+ virtual int flattenContent(HWND *w);
+
+ protected:
+
+ ScriptObject *getScriptObject();
+ virtual ifc_window *getWnd();
+ virtual HWND gethWnd();
+ WNDPROC getOldProc();
+
+ HWND hwnd, parent;
+ ifc_window *wnd;
+ long (__stdcall *oldproc)(struct HWND__ *,unsigned int,unsigned int,long);
+ int triedyet;
+
+ RECVS_DISPATCH;
+};
+
+class NOVTABLE svc_accRoleServer : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::ACCESSIBILITYROLESERVER; }
+
+ int handleRole(int role);
+ roleServerObject *createObject(HWND parent, ifc_window *attached_wnd);
+ void destroyObject(roleServerObject *obj);
+
+ enum {
+ RS_HANDLEROLE=10,
+ RS_CREATEOBJECT=20,
+ RS_DESTROYOBJECT=30
+ };
+
+};
+
+inline int svc_accRoleServer::handleRole(int role) {
+ return _call(RS_HANDLEROLE, 0, role);
+}
+
+inline roleServerObject *svc_accRoleServer::createObject(HWND parent, ifc_window *attached_wnd) {
+ return _call(RS_CREATEOBJECT, (roleServerObject *)NULL, parent, attached_wnd);
+}
+
+inline void svc_accRoleServer::destroyObject(roleServerObject *obj) {
+ _voidcall(RS_DESTROYOBJECT, obj);
+}
+
+
+
+class svc_accRoleServerI : public svc_accRoleServer {
+
+ public:
+
+ virtual int handleRole(int role)=0;
+ virtual roleServerObject *createObject(HWND parent, ifc_window *attached_wnd)=0;
+ virtual void destroyObject(roleServerObject *obj)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class AccRoleServerCreatorSingle : public waServiceFactoryTSingle<svc_accRoleServer, T> {
+public:
+ svc_accRoleServer *getHandler() {
+ return getSingleService();
+ }
+};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/string.h>
+
+class AccRoleServerEnum : public SvcEnumT<svc_accRoleServer> {
+public:
+ AccRoleServerEnum(int role) : roletest(role) { }
+protected:
+ virtual int testService(svc_accRoleServer *svc) {
+ return (svc->handleRole(roletest));
+ }
+private:
+ int roletest;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_action.cpp b/Src/Wasabi/api/service/svcs/svc_action.cpp
new file mode 100644
index 00000000..bb6954de
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_action.cpp
@@ -0,0 +1,38 @@
+#include <precomp.h>
+
+#include "svc_action.h"
+
+#define CBCLASS svc_actionI
+START_DISPATCH;
+CB(HASACTION, hasAction);
+CB(ONACTION, onAction);
+END_DISPATCH;
+#undef CBCLASS
+
+svc_actionI::~svc_actionI()
+{
+ actions.deleteAll();
+}
+
+void svc_actionI::registerAction(const wchar_t *actionid, int pvtid)
+{
+ ASSERT(actionid != NULL);
+ actions.addItem(new ActionEntry(actionid, pvtid));
+}
+
+int svc_actionI::hasAction(const wchar_t *name)
+{
+ if (name == NULL) return FALSE;
+ return (actions.findItem(name) != NULL);
+}
+
+int svc_actionI::onAction(const wchar_t *action, const wchar_t *param, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ if (action == NULL) return 0;
+ int pos = -1;
+ if (actions.findItem(action, &pos))
+ {
+ return onActionId(actions.enumItem(pos)->getId(), action, param, p1, p2, data, datalen, source);
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/service/svcs/svc_action.h b/Src/Wasabi/api/service/svcs/svc_action.h
new file mode 100644
index 00000000..45b87004
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_action.h
@@ -0,0 +1,154 @@
+#ifndef _SVC_ACTION_H
+#define _SVC_ACTION_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/ptrlist.h>
+
+#include <api/service/services.h>
+
+class ifc_window;
+
+class NOVTABLE svc_action : public Dispatchable {
+protected:
+ svc_action() { }
+
+public:
+ static FOURCC getServiceType() { return WaSvc::ACTION; }
+
+ int hasAction(const wchar_t *name);
+ int onAction(const wchar_t *action, const wchar_t *param=NULL, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+ enum {
+ HASACTION=10,
+ ONACTION=20,
+ };
+
+};
+
+inline int svc_action::hasAction(const wchar_t *name) {
+ return _call(HASACTION, 0, name);
+}
+
+inline int svc_action::onAction(const wchar_t *action, const wchar_t *param, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ return _call(ONACTION, 0, action, param, p1, p2, data, datalen, source);
+}
+
+class ActionEntry {
+ public:
+ ActionEntry(const wchar_t *_action, int _id) : action(_action), id(_id) {}
+ virtual ~ActionEntry() { }
+
+ const wchar_t *getAction() { return action; }
+ int getId() { return id; }
+
+ private:
+ StringW action;
+ int id;
+};
+
+class SortActions {
+public:
+ static int compareItem(ActionEntry *p1, ActionEntry *p2) {
+ return WCSICMP(p1->getAction(), p2->getAction());
+ }
+ static int compareAttrib(const wchar_t *attrib, ActionEntry *item) {
+ return WCSICMP(attrib, item->getAction());
+ }
+};
+
+class NOVTABLE svc_actionI : public svc_action {
+public:
+ virtual ~svc_actionI();
+ void registerAction(const wchar_t *actionid, int pvtid);
+ virtual int onActionId(int pvtid, const wchar_t *action, const wchar_t *param=NULL, int p1=0, int p2=0, void *data=NULL, int datalen=0, ifc_window *source=NULL)=0;
+
+protected:
+ virtual int hasAction(const wchar_t *name);
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+ PtrListQuickSorted<ActionEntry, SortActions> actions;
+
+ RECVS_DISPATCH;
+};
+#include <api/service/servicei.h>
+template <class T>
+class ActionCreator : public waServiceFactoryT<svc_action, T> {};
+template <class T>
+class ActionCreatorSingle : public waServiceFactoryTSingle<svc_action, T> {
+public:
+ svc_action *getHandler() {
+ return waServiceFactoryT<svc_action, T>::getSingleService();
+ }
+};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class ActionEnum : public SvcEnumT<svc_action> {
+public:
+ ActionEnum(const wchar_t *_action) : action(_action) { }
+protected:
+ virtual int testService(svc_action *svc) {
+ return (!action.isempty() && svc->hasAction(action));
+ }
+private:
+ StringW action;
+};
+
+class FireAction {
+public:
+ enum {
+ ACTION_NOT_HANDLED = 0x80000000
+ };
+ /**
+ Fire a named action out into the system with the given parameters.
+
+ This method will only send the action to the first registered handler for that action.
+
+ This prevents the action from being overridden or handled by newer wacs.
+
+ The content and syntax of the generalized params are defined by the handler of the action string.
+
+ Read: Using Wasabi: General Development: Actions
+
+ @see svc_actionI
+ @param action The action string.
+ @param param A string parameter to the action.
+ @param p1 The first integer parameter to the action.
+ @param p2 The second integer parameter to the action.
+ @param data An untyped data buffer parameter to the action.
+ @param datalen The size in bytes of the data buffer parameter.
+ @param source A window object that can be given as the source object, if the action handler is expecting one. Actions bound to guiobjects use that guiobject's rootwnd pointer as the source.
+ @param apply_to_all Send the action to everyone. (If false only sends to first registered)
+ */
+ FireAction(const wchar_t *action, const wchar_t *param = NULL, intptr_t p1 = 0, intptr_t p2 = 0, void *data = NULL, size_t datalen = 0, ifc_window *source = NULL, int apply_to_all = TRUE) {
+ lastretval = ACTION_NOT_HANDLED;
+ ActionEnum ae(action);
+ svc_action *act;
+ while ((act = ae.getNext()) != NULL) {
+ lastretval = act->onAction(action, param, p1, p2, data, datalen, source);
+ ae.release(act);
+ if (!apply_to_all) break;
+ }
+ }
+ /**
+ More robust retval handling is needed.
+
+ I ought to be grabbing all of the return values into a list an exposing that.
+
+ Later.
+
+ Read: Using Wasabi: General Development: Actions
+
+ @see svc_actionI
+ @ret The return code of the action sent.
+ */
+ int getLastReturnValue() {
+ return lastretval;
+ }
+private:
+ int lastretval;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_burner.cpp b/Src/Wasabi/api/service/svcs/svc_burner.cpp
new file mode 100644
index 00000000..896a984b
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_burner.cpp
@@ -0,0 +1,70 @@
+#include <precomp.h>
+#include "svc_burner.h"
+#include <api/api.h>
+
+#define CBCLASS svc_mediaRecorderI
+START_DISPATCH;
+ CB(ISSESSIONSUPPORTED,isSessionSupported)
+ CB(ISMEDIASUPPORTED,isMediaSupported)
+ CB(GETNUMDEVICES,getNumDevices)
+ CB(ENUMDEVICE,enumDevice)
+ VCB(REFRESHDEVICES,refreshDevices)
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS MediaRecorder::DeviceI
+START_DISPATCH;
+ CB(GETDEPENDENCYPTR,getDependencyPtr)
+ CB(GETDEVICENAME,getDeviceName)
+ CB(GETDEVICETYPE,getDeviceType)
+ CB(GETDEVICEDESCRIPTION,getDeviceDescription)
+ CB(ENUMDEVICESPEEDS,enumDeviceSpeeds)
+ CB(GETMEDIASIZE,getMediaSize)
+ CB(GETMEDIAFREE,getMediaFree)
+ VCB(CLEARSESSIONS,clearSessions)
+ CB(ADDSESSION,addSession)
+ CB(GETSESSION,getSession)
+ CB(SETRECORDSPEED,setRecordSpeed)
+ CB(SETTEST,setTest)
+ CB(SETCLOSEDISC,setCloseDisc)
+ CB(CANBURNNOW,canBurnNow)
+ CB(CANCANCEL,canCancel)
+ CB(BEGIN,begin)
+ CB(END,end)
+ CB(CANCEL,cancel)
+ CB(GETSTATUS,getStatus)
+ CB(GETPROGRESS,getProgress)
+ CB(GETSTATUSTEXT,getStatusText)
+ CB(GETLASTERROR,getLastError)
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS MediaRecorder::SessionI
+START_DISPATCH;
+ CB(GETSESSIONTYPE,getSessionType)
+ CB(CLOSESESSION,closeSession)
+ CB(GETNUMENTRIES,getNumEntries)
+ CB(ENUMENTRY,enumEntry)
+ CB(GETTOTALBYTES,getTotalBytes)
+ CB(GETTOTALTIME,getTotalTime)
+END_DISPATCH;
+#undef CBCLASS
+
+const char *MediaRecorder::RedbookSession::enumEntry(int n) {
+ if( n>=getNumEntries()) return NULL;
+ return m_tracks[n]->getValue();
+}
+
+int MediaRecorder::RedbookSession::getTotalBytes() {
+ double length=(double)getTotalTime();
+ return (int)(length*(44100*4)/1000); //always 44khz 16bps stereo
+}
+
+int MediaRecorder::RedbookSession::getTotalTime() {
+ int total=0;
+ for(int i=0;i<getNumEntries();i++) {
+ int length=0;
+ if((length=api->metadb_getLength(m_tracks[i]->getValue()))!=-1) total+=length;
+ }
+ return total;
+}
diff --git a/Src/Wasabi/api/service/svcs/svc_burner.h b/Src/Wasabi/api/service/svcs/svc_burner.h
new file mode 100644
index 00000000..88f690af
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_burner.h
@@ -0,0 +1,243 @@
+#ifndef _SVC_BURNER_H
+#define _SVC_BURNER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/depend.h>
+#include <bfc/string/string.h>
+#include <api/service/services.h>
+
+namespace MediaRecorder {
+
+class Session : public Dispatchable {
+protected:
+ Session() {} // protect constructor
+
+public:
+ int getSessionType() { return _call(GETSESSIONTYPE,0); }
+ enum {
+ Session_REDBOOK, Session_DATA, Session_ISO
+ };
+ int closeSession() { return _call(CLOSESESSION,0); }
+ int getNumEntries() { return _call(GETNUMENTRIES,0); }
+ const char *enumEntry(int n) { return _call(ENUMENTRY,(const char *)NULL,n); }
+ int getTotalBytes() { return _call(GETTOTALBYTES,0); }
+ int getTotalTime() { return _call(GETTOTALTIME,0); }
+
+ enum {
+ GETSESSIONTYPE=10,
+ CLOSESESSION=20,
+ GETNUMENTRIES=30,
+ ENUMENTRY=40,
+ GETTOTALBYTES=50,
+ GETTOTALTIME=60,
+ };
+};
+
+// this represents one session on the cd
+// normal audio cds have 1 redbook session, mixed mode has 2 (or more), with
+// 1 audio followed by 1 or more data
+class SessionI : public Session {
+public:
+ virtual int getSessionType()=0;
+
+ virtual int closeSession()=0;
+ virtual int getNumEntries()=0;
+ virtual const char *enumEntry(int n)=0;
+ virtual int getTotalBytes()=0; //total space used in bytes
+ virtual int getTotalTime()=0; //total time used in ms
+
+protected:
+ RECVS_DISPATCH;
+};
+
+class RedbookSession : public SessionI {
+public:
+ virtual ~RedbookSession() { m_tracks.deleteAll(); }
+
+ int getSessionType() { return Session_REDBOOK; }
+
+ int closeSession() { return 1; }
+
+ void addEntry(const char *file) { m_tracks.addItem(new String(file)); }
+ int getNumEntries() { return m_tracks.getNumItems(); }
+ void removeEntry(int n) { m_tracks.deleteItem(n); }
+ void clearEntries() { m_tracks.deleteAll(); }
+
+ const char *enumEntry(int n);
+ int getTotalBytes();
+ int getTotalTime();
+
+protected:
+ PtrList<String> m_tracks;
+};
+
+// this is the physical device
+class Device : public Dispatchable {
+protected:
+ Device() {} // protect constructor
+
+public:
+ static const GUID *depend_getClassGuid() {
+ // {23F48039-455D-4348-86D5-0A82754678FC}
+ static const GUID ret =
+ { 0x23f48039, 0x455d, 0x4348, { 0x86, 0xd5, 0xa, 0x82, 0x75, 0x46, 0x78, 0xfc } };
+ return &ret;
+ }
+
+ api_dependent *getDependencyPtr() { return _call(GETDEPENDENCYPTR,(api_dependent *)NULL); }
+
+ const char *getDeviceName() { return _call(GETDEVICENAME,(const char *)NULL); }
+ const char *getDeviceType() { return _call(GETDEVICETYPE,(const char *)NULL); }
+ const char *getDeviceDescription() { return _call(GETDEVICEDESCRIPTION,(const char *)NULL); }
+
+ int enumDeviceSpeeds(int n) { return _call(ENUMDEVICESPEEDS,0,n); }
+
+ int getMediaSize() { return _call(GETMEDIASIZE,0); }
+ int getMediaFree() { return _call(GETMEDIAFREE,0); }
+
+ void clearSessions() { _voidcall(CLEARSESSIONS); }
+ int addSession(Session *session) { return _call(ADDSESSION,0,session); }
+ Session *getSession(int num) { return _call(GETSESSION,(Session *)NULL,num); }
+
+ int setRecordSpeed(int kbps) { return _call(SETRECORDSPEED,0,kbps); }
+ int setTest(int testmode) { return _call(SETTEST,0,testmode); }
+ int setCloseDisc(int closedisc) { return _call(SETCLOSEDISC,0,closedisc); }
+
+ int canBurnNow() { return _call(CANBURNNOW,0); }
+ int canCancel() { return _call(CANCANCEL,0); }
+
+ int begin() { return _call(BEGIN,0); }
+ int end() { return _call(END,0); }
+ int cancel() { return _call(CANCEL,0); }
+
+ int getStatus() { return _call(GETSTATUS,0); }
+ enum {
+ Status_IDLE, Status_PREPARING, Status_BURNING, Status_DONE,
+ };
+
+ int getProgress() { return _call(GETPROGRESS,0); }
+ const char *getStatusText() { return _call(GETSTATUSTEXT,(const char *)NULL); }
+
+ const char *getLastError() { return _call(GETLASTERROR,(const char *)NULL); }
+
+ enum {
+ Event_PREPAREBEGIN=100,
+ Event_MEDIATRANSCODED=200, // params is item #
+ Event_PREPAREEND=300,
+ Event_BURNBEGIN=400,
+ Event_ENTRYCOMPLETE=500, // param is the position in bytes
+ Event_SESSIONCOMPLETE=600,
+ Event_BURNEND=700,
+ Event_ERROR=800,
+ Event_MEDIACHANGE=900, // user put in a different disc
+ };
+
+ enum {
+ GETDEPENDENCYPTR=10,
+ GETDEVICENAME=20,
+ GETDEVICETYPE=30,
+ GETDEVICEDESCRIPTION=40,
+ ENUMDEVICESPEEDS=50,
+ GETMEDIASIZE=60,
+ GETMEDIAFREE=70,
+ CLEARSESSIONS=80,
+ ADDSESSION=90,
+ GETSESSION=100,
+ SETRECORDSPEED=110,
+ SETTEST=120,
+ SETCLOSEDISC=130,
+ CANBURNNOW=140,
+ CANCANCEL=150,
+ BEGIN=160,
+ END=170,
+ CANCEL=180,
+ GETSTATUS=190,
+ GETPROGRESS=200,
+ GETSTATUSTEXT=210,
+ GETLASTERROR=220,
+ };
+};
+
+class DeviceI : public Device {
+public:
+ virtual api_dependent *getDependencyPtr()=0; // for events
+
+ virtual const char *getDeviceName()=0; // internal device name
+ virtual const char *getDeviceType()=0; // "CD-R", "CD-RW", "DVD-R" etc
+ virtual const char *getDeviceDescription()=0; // user readable string
+
+ virtual int enumDeviceSpeeds(int n)=0; // in kb/s
+
+ virtual int getMediaSize()=0; // total space in bytes
+ virtual int getMediaFree()=0; // free space in bytes
+
+ virtual void clearSessions()=0;
+ virtual int addSession(Session *session)=0;
+ virtual Session *getSession(int num)=0;
+
+ virtual int setRecordSpeed(int kbps)=0; //kbps==0 means max speed
+ virtual int setTest(int testmode)=0; // if true, don't really burn
+ virtual int setCloseDisc(int closedisc)=0; // if true, close entire disc at end
+
+ virtual int canBurnNow()=0; // return 1 if everything's ready
+ virtual int canCancel()=0; // return 1 if we can cancel (during burning)
+
+ virtual int begin()=0;
+ virtual int end()=0;
+ virtual int cancel()=0;
+
+ virtual int getStatus()=0;
+ virtual int getProgress()=0; // # of bytes written
+ virtual const char *getStatusText()=0; // like "xx% complete" or something
+
+ virtual const char *getLastError()=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+}; // end namespace MediaRecorder
+
+//don't override this one
+class NOVTABLE svc_mediaRecorder : public Dispatchable {
+protected:
+ svc_mediaRecorder() {} // protect constructor
+
+public:
+ static FOURCC getServiceType() { return WaSvc::MEDIARECORDER; }
+
+ int isSessionSupported(MediaRecorder::Session *session) { return _call(ISSESSIONSUPPORTED,0,session); }
+ int isMediaSupported(const char *medianame) { return _call(ISMEDIASUPPORTED,0,medianame); }
+
+ int getNumDevices() { return _call(GETNUMDEVICES,0); }
+ MediaRecorder::Device *enumDevice(int n) { return _call(ENUMDEVICE,(MediaRecorder::Device*)NULL,n); }
+
+ void refreshDevices() { _voidcall(REFRESHDEVICES); }
+
+ enum {
+ ISSESSIONSUPPORTED=10,
+ ISMEDIASUPPORTED=20,
+ GETNUMDEVICES=30,
+ ENUMDEVICE=40,
+ REFRESHDEVICES=50,
+ };
+};
+
+// this should be implemented by a given burning lib
+class NOVTABLE svc_mediaRecorderI : public svc_mediaRecorder {
+public:
+ static FOURCC getServiceType() { return WaSvc::MEDIARECORDER; }
+
+ virtual int isSessionSupported(MediaRecorder::Session *session)=0;
+ virtual int isMediaSupported(const char *medianame)=0;// "CD-R", "DVD-R", etc.
+
+ virtual int getNumDevices()=0;
+ virtual MediaRecorder::Device *enumDevice(int n)=0;
+
+ virtual void refreshDevices()=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/service/svcs/svc_collection.cpp b/Src/Wasabi/api/service/svcs/svc_collection.cpp
new file mode 100644
index 00000000..9e9e3a67
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_collection.cpp
@@ -0,0 +1,194 @@
+#include <precomp.h>
+
+#include "svc_collection.h"
+
+// an named xml overridable collection of objects
+
+#define CBCLASS svc_collectionI
+START_DISPATCH;
+ CB(COLLECTION_TESTTAG, testTag);
+ VCB(COLLECTION_ADDELEMENT, addElement);
+ VCB(COLLECTION_REMOVEELEMENT, removeElement);
+ VCB(COLLECTION_REMOVEALLELEMENTS, removeAllElements);
+ CB(COLLECTION_GETNUMELEMENTS, getNumElements);
+ CB(COLLECTION_GETNUMELEMENTSUNIQUE, getNumElementsUnique);
+ CB(COLLECTION_ENUMELEMENT, enumElement);
+ CB(COLLECTION_ENUMELEMENTUNIQUE, enumElementUnique);
+ CB(COLLECTION_GETELEMENT, getElement);
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS CollectionElementI
+START_DISPATCH;
+ CB(COLLECTIONELEMENT_GETID, getId);
+ CB(COLLECTIONELEMENT_GETPARAMVALUE, getParamValue);
+ CB(COLLECTIONELEMENT_GETPARAMVALUEINT, getParamValueInt);
+ CB(COLLECTIONELEMENT_GETINCLUDEPATH, getIncludePath);
+END_DISPATCH;
+#undef CBCLASS
+
+
+svc_collectionI::svc_collectionI() {
+ count = 0;
+ elements.setAutoSort(1);
+}
+
+svc_collectionI::~svc_collectionI() {
+}
+
+void svc_collectionI::addElement(const char *id, const char *includepath, int incrementalremovalid, skin_xmlreaderparams *params) {
+ CollectionElementI *cei = new CollectionElementI(this, id, params, incrementalremovalid, includepath);
+ elements.addItem(cei);
+}
+
+void svc_collectionI::removeElement(int removalid) {
+ for (int i=0;i<elements.getNumItems();i++) {
+ CollectionElementI *e = elements.enumItem(i);
+ if (e->getSecCount() == removalid) {
+ elements.removeItem(e);
+ delete e;
+ i--;
+ }
+ }
+}
+
+void svc_collectionI::removeAllElements() {
+ elements.deleteAll();
+}
+
+int svc_collectionI::getNumElements() {
+ return elements.getNumItems();
+}
+
+int svc_collectionI::getNumElementsUnique() {
+ int i=0;
+ int n=0;
+ const char *previous = NULL;
+ for (i=0;i<elements.getNumItems();i++) {
+ const char *id = elements.enumItem(i)->getId();
+ if (!STRCASEEQLSAFE(id, previous))
+ n++;
+ previous = id;
+ }
+ return n;
+}
+
+CollectionElement *svc_collectionI::enumElementUnique(int n, int *ancestor) {
+ int i=0;
+ int _n=-1;
+ CollectionElement *e=NULL;
+ CollectionElement *previous = NULL;
+ elements.sort(1);
+ for (i=0;i<elements.getNumItems();i++) {
+ CollectionElement *c = elements.enumItem(i);
+ if (!STRCASEEQLSAFE(c->getId(), previous ? previous->getId() : NULL)) {
+ if (_n == n)
+ break;
+ _n++;
+ }
+ previous = c;
+ }
+ if (_n == n)
+ e = previous;
+ else
+ e = NULL;
+ if (ancestor != NULL) {
+ if (e != NULL) {
+ int pos=-1;
+ elements.findItem(static_cast<CollectionElementI*>(e), &pos);
+ if (pos > 0) {
+ CollectionElement *f = elements.enumItem(pos-1);
+ if (!STRCASEEQLSAFE(f ? f->getId() : NULL, e->getId())) *ancestor = -1;
+ } else {
+ *ancestor = -1;
+ e = NULL;
+ }
+ } else
+ *ancestor = -1;
+ }
+ return e;
+}
+
+CollectionElement *svc_collectionI::enumElement(int n, int *ancestor) {
+ CollectionElement *e = elements.enumItem(n);
+ if (ancestor != NULL) {
+ CollectionElement *a = elements.enumItem(n-1);
+ if (!STRCASEEQL(a->getId(), e->getId())) *ancestor = -1;
+ *ancestor = n-1;
+ }
+ return e;
+}
+
+CollectionElement *svc_collectionI::getElement(const char *id, int *ancestor) {
+ int pos=-1;
+ CollectionElement *e = elements.findLastItem(id, &pos);
+ if (ancestor != NULL) {
+ CollectionElement *a = elements.enumItem(pos-1);
+ if (!STRCASEEQL(a->getId(), e->getId())) *ancestor = -1;
+ *ancestor = pos-1;
+ }
+ return e;
+}
+
+CollectionElement *svc_collectionI::getAncestor(CollectionElement *e) {
+ int pos=-1;
+ CollectionElementI *ei = static_cast<CollectionElementI *>(e);
+ elements.findItem(ei, &pos);
+ if (pos >= 0) {
+ pos--;
+ if (STRCASEEQL(elements.enumItem(pos)->getId(), e->getId())) return elements.enumItem(pos);
+ }
+ return NULL;
+}
+
+CollectionElementI::CollectionElementI(svc_collectionI *col, const char *_id, skin_xmlreaderparams *p, int _seccount, const char *_path) {
+ id = _id;
+ for (int i=0;i<p->getNbItems();i++) {
+ Pair < String, String > *pr = new Pair < String, String >("","");
+ pr->a = p->getItemName(i);
+ pr->b = p->getItemValue(i);
+ params.addItem(pr);
+ }
+ seccount = _seccount;
+ collection = col;
+ path = _path;
+}
+
+CollectionElementI::~CollectionElementI() {
+ params.deleteAll();
+}
+
+const char *CollectionElementI::getId() {
+ return id;
+}
+
+const char *CollectionElementI::getParamValue(const char *param, CollectionElement **item){
+ CollectionElement *e = getAncestor();
+ const char *a = e ? e->getParamValue(param) : NULL;
+ Pair<String, String> *p = params.findItem(param);
+ a = p ? p->b.getValue() : a;
+ if (item && p != NULL) *item = this;
+ return a;
+}
+
+int CollectionElementI::getParamValueInt(const char *param){
+ const char *a = getParamValue(param);
+ return ATOI(a);
+}
+
+int CollectionElementI::getSecCount() {
+ return seccount;
+}
+
+CollectionElement *CollectionElementI::getAncestor() {
+ return collection->getAncestor(this);
+}
+
+const char *CollectionElementI::getIncludePath(const char *param/* =NULL */) {
+ if (param == NULL) return path;
+ CollectionElement *i;
+ if (!getParamValue(param, &i)) return NULL;
+ if (i != NULL)
+ return i->getIncludePath(NULL);
+ return NULL;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/service/svcs/svc_collection.h b/Src/Wasabi/api/service/svcs/svc_collection.h
new file mode 100644
index 00000000..9769d5a3
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_collection.h
@@ -0,0 +1,226 @@
+#ifndef _SVC_COLLECTION_H
+#define _SVC_COLLECTION_H
+
+#include <bfc/dispatch.h>
+#include <bfc/ptrlist.h>
+#include <bfc/pair.h>
+#include <api/xml/xmlreader.h>
+#include <api/service/services.h>
+
+class CollectionElement;
+class svc_collectionI;
+
+class NOVTABLE svc_collection : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::COLLECTION; }
+ int testTag(const wchar_t *xmltag);
+ void addElement(const wchar_t *id, const wchar_t *includepath, int removalid, skin_xmlreaderparams *params);
+ void removeElement(int recored_value);
+ void removeAllElements();
+ int getNumElements();
+ int getNumElementsUnique();
+ CollectionElement *enumElement(int n, int *ancestor);
+ CollectionElement *enumElementUnique(int n, int *ancestor);
+ CollectionElement *getElement(const wchar_t *id, int *ancestor);
+ CollectionElement *getAncestor(CollectionElement *e);
+
+ enum
+ {
+ COLLECTION_TESTTAG=10,
+ COLLECTION_ADDELEMENT=20,
+ COLLECTION_REMOVEELEMENT=30,
+ COLLECTION_REMOVEALLELEMENTS=35,
+ COLLECTION_GETNUMELEMENTS=40,
+ COLLECTION_GETNUMELEMENTSUNIQUE=50,
+ COLLECTION_ENUMELEMENT=60,
+ COLLECTION_ENUMELEMENTUNIQUE=70,
+ COLLECTION_GETELEMENT=80,
+ };
+};
+
+inline int svc_collection::testTag(const wchar_t *xmltag) {
+ return _call(COLLECTION_TESTTAG, 0, xmltag);
+}
+
+inline void svc_collection::addElement(const wchar_t *id, const wchar_t *includepath, int incrementalremovalid, skin_xmlreaderparams *params) {
+ _voidcall(COLLECTION_ADDELEMENT, id, includepath, incrementalremovalid, params);
+}
+
+inline void svc_collection::removeElement(int removalid) {
+ _voidcall(COLLECTION_REMOVEELEMENT, removalid);
+}
+
+inline void svc_collection::removeAllElements() {
+ _voidcall(COLLECTION_REMOVEALLELEMENTS);
+}
+
+inline int svc_collection::getNumElements() {
+ return _call(COLLECTION_GETNUMELEMENTS, 0);
+}
+
+inline int svc_collection::getNumElementsUnique() {
+ return _call(COLLECTION_GETNUMELEMENTSUNIQUE, 0);
+}
+
+inline CollectionElement *svc_collection::enumElement(int n, int *ancestor) {
+ return _call(COLLECTION_ENUMELEMENT, (CollectionElement *)NULL, n, ancestor);
+}
+
+inline CollectionElement *svc_collection::enumElementUnique(int n, int *ancestor) {
+ return _call(COLLECTION_ENUMELEMENTUNIQUE, (CollectionElement *)NULL, n, ancestor);
+}
+
+inline CollectionElement *svc_collection::getElement(const wchar_t *id, int *ancestor) {
+ return _call(COLLECTION_GETELEMENT, (CollectionElement *)NULL, id, ancestor);
+}
+
+class SortPairString {
+public:
+ static int compareItem(Pair<StringW, StringW> *p1, Pair<StringW, StringW> *p2) {
+ return WCSICMP(p1->a, p2->a);
+ }
+ static int compareAttrib(const wchar_t *attrib, Pair<StringW, StringW> *item) {
+ return WCSICMP(attrib, item->a);
+ }
+};
+
+class CollectionElement : public Dispatchable {
+ public:
+ const wchar_t *getId();
+ const wchar_t *getParamValue(const wchar_t *param, CollectionElement **item=NULL);
+ int getParamValueInt(const wchar_t *param);
+ const wchar_t *getIncludePath(const wchar_t *param=NULL);
+ CollectionElement *getAncestor();
+
+ enum {
+ COLLECTIONELEMENT_GETID=10,
+ COLLECTIONELEMENT_GETPARAMVALUE=20,
+ COLLECTIONELEMENT_GETPARAMVALUEINT=30,
+ COLLECTIONELEMENT_GETANCESTOR=40,
+ COLLECTIONELEMENT_GETINCLUDEPATH=50,
+ };
+};
+
+inline const wchar_t *CollectionElement::getId() {
+ return _call(COLLECTIONELEMENT_GETID, (const wchar_t *)NULL);
+}
+
+inline const wchar_t *CollectionElement::getParamValue(const wchar_t *param, CollectionElement **item) {
+ return _call(COLLECTIONELEMENT_GETPARAMVALUE, (const wchar_t *)NULL, param, item);
+}
+
+inline int CollectionElement::getParamValueInt(const wchar_t *param) {
+ return _call(COLLECTIONELEMENT_GETPARAMVALUEINT, 0, param);
+}
+
+inline CollectionElement *CollectionElement::getAncestor() {
+ return _call(COLLECTIONELEMENT_GETANCESTOR, (CollectionElement *)NULL);
+}
+
+inline const wchar_t *CollectionElement::getIncludePath(const wchar_t *param) {
+ return _call(COLLECTIONELEMENT_GETINCLUDEPATH, (const wchar_t *)NULL, param);
+}
+
+class CollectionElementI : public CollectionElement {
+ public:
+ CollectionElementI(svc_collectionI *collectionI, const wchar_t *id, skin_xmlreaderparams *params, int seccount, const wchar_t *includepath);
+ virtual ~CollectionElementI();
+
+ virtual const wchar_t *getId();
+ virtual const wchar_t *getParamValue(const wchar_t *param, CollectionElement **item=NULL);
+ virtual int getParamValueInt(const wchar_t *param);
+ virtual CollectionElement *getAncestor();
+ const wchar_t *getIncludePath(const wchar_t *param=NULL); // null returns last override's include path
+
+ int getSecCount();
+
+ protected:
+ RECVS_DISPATCH;
+
+ PtrListQuickSorted < Pair < StringW, StringW >, SortPairString > params;
+ StringW id;
+ int seccount;
+ svc_collectionI *collection;
+ StringW path;
+};
+
+class SortCollectionElementsI {
+public:
+ static int compareItem(CollectionElementI *p1, CollectionElementI *p2) {
+ int r = WCSICMP(p1->getId(), p2->getId());
+ if (r == 0) {
+ if (p1->getSecCount() < p2->getSecCount()) return -1;
+ if (p1->getSecCount() > p2->getSecCount()) return 1;
+ return 0;
+ }
+ return r;
+ }
+ static int compareAttrib(const wchar_t *attrib, CollectionElementI *item) {
+ return WCSICMP(attrib, item->getId());
+ }
+};
+
+// derive from this one
+class svc_collectionI : public svc_collection {
+public:
+ svc_collectionI();
+ virtual ~svc_collectionI();
+ virtual int testTag(const wchar_t *xmltag)=0;
+ virtual void addElement(const wchar_t *id, const wchar_t *includepath, int incrementalremovalid, skin_xmlreaderparams *params);
+ virtual void removeElement(int removalid);
+ virtual void removeAllElements();
+ virtual int getNumElements();
+ virtual int getNumElementsUnique();
+ virtual CollectionElement *enumElement(int n, int *ancestor);
+ virtual CollectionElement *enumElementUnique(int n, int *ancestor);
+ virtual CollectionElement *getElement(const wchar_t *id, int *ancestor);
+ virtual CollectionElement *getAncestor(CollectionElement *e);
+
+protected:
+ RECVS_DISPATCH;
+
+ PtrListQuickMultiSorted < CollectionElementI, SortCollectionElementsI > elements;
+ int count;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class CollectionCreator : public waServiceFactoryTSingle<svc_collection, T> {};
+
+template <wchar_t TAG[]>
+class CollectionSvc : public svc_collectionI {
+ public:
+ int testTag(const wchar_t *xmltag) {
+ if (!WCSICMP(xmltag, TAG)) return 1;
+ return 0;
+ }
+ static const char *getServiceName() { return StringPrintf("Collection Service for \"%S\"", TAG); }
+};
+
+template <class T>
+class CollectionSvc2 : public svc_collectionI {
+ public:
+ int testTag(const wchar_t *xmltag) {
+ if (STRCASEEQL(xmltag, T::collection_getXmlTag())) return 1;
+ return 0;
+ }
+ static const char *getServiceName() { return StringPrintf("Collection Service for \"%S\"", T::collection_getXmlTag()); }
+};
+
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+class CollectionSvcEnum : public SvcEnumT<svc_collection>
+{
+public:
+ CollectionSvcEnum(const wchar_t *xmltag) : tag(xmltag) {}
+protected:
+ virtual int testService(svc_collection *svc) {
+ return (svc->testTag(tag));
+ }
+private:
+ StringW tag;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_console.cpp b/Src/Wasabi/api/service/svcs/svc_console.cpp
new file mode 100644
index 00000000..c34bb156
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_console.cpp
@@ -0,0 +1,10 @@
+
+#include <svc_console.h>
+
+#define CBCLASS svc_consoleI
+START_DISPATCH;
+ CB(ACTIVATED, activated);
+ CB(OUTPUTSTRING, outputString);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_console.h b/Src/Wasabi/api/service/svcs/svc_console.h
new file mode 100644
index 00000000..696b7897
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_console.h
@@ -0,0 +1,36 @@
+#ifndef _SVC_CONSOLE_H
+#define _SVC_CONSOLE_H
+
+#include <bfc/dispatch.h>
+
+class NOVTABLE svc_console : public Dispatchable
+{
+public:
+ int activated();
+ int outputString(int severity, const char *string);
+
+ enum {
+ ACTIVATED=10,
+ OUTPUTSTRING=20,
+ };
+};
+
+inline int svc_console::activated() {
+ return _call(ACTIVATED, 0);
+}
+
+inline int svc_console::outputString(int severity, const char *string) {
+ return _call(OUTPUTSTRING, 0, severity, string);
+}
+
+// derive from this one
+class svc_consoleI : public svc_console {
+public:
+ virtual int activated()=0;
+ virtual int outputString(int severity, const char *string)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_contextCmd.cpp b/Src/Wasabi/api/service/svcs/svc_contextCmd.cpp
new file mode 100644
index 00000000..da220cfa
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_contextCmd.cpp
@@ -0,0 +1,16 @@
+#include <precomp.h>
+
+#include "svc_contextcmd.h"
+
+#define CBCLASS svc_contextCmdI
+START_DISPATCH;
+ CB(TESTITEM, testItem);
+ CB(GETSUBMENU, getSubMenu);
+ CB(GETSUBMENUTEXT, getSubMenuText);
+ CB(GETCOMMAND, getCommand);
+ CB(GETENABLED, getEnabled);
+ CB(GETCHECKED, getChecked);
+ CB(GETSORTVAL, getSortVal);
+ VCB(ONCOMMAND, onCommand);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_contextCmd.h b/Src/Wasabi/api/service/svcs/svc_contextCmd.h
new file mode 100644
index 00000000..06a0aff5
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_contextCmd.h
@@ -0,0 +1,127 @@
+#ifndef _SVC_CONTEXTCMD_H
+#define _SVC_CONTEXTCMD_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+namespace ContextCmdSortVal {
+ enum ContextCmdSortVal {
+ BEGINNING = 0,
+ MIDDLE = 32767,
+ END = 65535,
+ };
+};
+
+class DragItem;
+
+class NOVTABLE svc_contextCmd : public Dispatchable {
+protected:
+ svc_contextCmd() {}
+ ~svc_contextCmd() {}
+public:
+ static FOURCC getServiceType() { return WaSvc::CONTEXTCMD; }
+
+ int testItem(DragItem *item, const wchar_t *menu_path);
+
+ int getSubMenu(DragItem *item, const wchar_t *menu_path);
+ const wchar_t *getSubMenuText(const wchar_t *menu_path);
+
+ const wchar_t *getCommand(DragItem *item, int n);
+
+ int getEnabled(DragItem *item, int n);
+ int getChecked(DragItem *item, int n);
+ int getSortVal(DragItem *item, int n);
+
+ void onCommand(DragItem *item, int n);
+
+protected:
+ enum {
+ TESTITEM,
+ GETSUBMENU,
+ GETSUBMENUTEXT,
+ GETCOMMAND,
+ GETENABLED,
+ GETCHECKED,
+ GETSORTVAL,
+ ONCOMMAND,
+ };
+};
+
+inline int svc_contextCmd::testItem(DragItem *item, const wchar_t *menu_path) {
+ return _call(TESTITEM, 0, item, menu_path);
+}
+
+inline
+int svc_contextCmd::getSubMenu(DragItem *item, const wchar_t *menu_path) {
+ return _call(GETSUBMENU, 0, item, menu_path);
+}
+
+inline
+const wchar_t *svc_contextCmd::getSubMenuText(const wchar_t *menu_path) {
+ return _call(GETSUBMENUTEXT, (const wchar_t *)NULL, menu_path);
+}
+
+inline const wchar_t *svc_contextCmd::getCommand(DragItem *item, int n) {
+ return _call(GETCOMMAND, (const wchar_t *)0, item, n);
+}
+
+inline int svc_contextCmd::getEnabled(DragItem *item, int n) {
+ return _call(GETENABLED, TRUE, item, n);
+}
+
+inline int svc_contextCmd::getChecked(DragItem *item, int n) {
+ return _call(GETCHECKED, FALSE, item, n);
+}
+
+inline int svc_contextCmd::getSortVal(DragItem *item, int n) {
+ return _call(GETSORTVAL, ContextCmdSortVal::MIDDLE, item, n);
+}
+
+inline void svc_contextCmd::onCommand(DragItem *item, int n) {
+ _voidcall(ONCOMMAND, item, n);
+}
+
+class NOVTABLE svc_contextCmdI : public svc_contextCmd {
+public:
+ virtual int testItem(DragItem *item, const wchar_t *menu_path)=0;
+
+ virtual int getSubMenu(DragItem *item, const wchar_t *menu_path) { return 0; }
+ virtual const wchar_t *getSubMenuText(const wchar_t *menu_path) { return NULL; }
+
+ virtual const wchar_t *getCommand(DragItem *item, int n)=0;
+
+ // override these as needed
+ virtual int getEnabled(DragItem *item, int n) { return TRUE; }
+ virtual int getChecked(DragItem *item, int n) { return FALSE; }
+ virtual int getSortVal(DragItem *item, int n) { return ContextCmdSortVal::MIDDLE; }
+
+ virtual void onCommand(DragItem *item, int n)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class ContextCmdCreator : public waServiceFactoryT<svc_contextCmd, T> { };
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/stringW.h>
+
+class ContextCmdEnum : public SvcEnumT<svc_contextCmd> {
+public:
+ ContextCmdEnum(DragItem *_item, const wchar_t *_menu_path)
+ : item(_item), menu_path(_menu_path) {}
+
+protected:
+ virtual int testService(svc_contextCmd *svc) {
+ return svc->testItem(item, menu_path);
+ }
+
+private:
+ DragItem *item;
+ StringW menu_path;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_coreadmin.cpp b/Src/Wasabi/api/service/svcs/svc_coreadmin.cpp
new file mode 100644
index 00000000..5b7890e9
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_coreadmin.cpp
@@ -0,0 +1,70 @@
+#include <precomp.h>
+
+#include "svc_coreadmin.h"
+
+#define CBCLASS svc_coreAdminI
+START_DISPATCH;
+ CB(CREATECORE,createCore)
+ CB(NAMETOTOKEN,nameToToken)
+ CB(FREECOREBYTOKEN,freeCoreByToken)
+ CB(FREECOREBYNAME,freeCoreByName)
+ CB(VERIFYTOKEN,verifyToken)
+
+ CB(GETSUPPORTEDEXTENSIONS,getSupportedExtensions)
+ CB(GETEXTSUPPORTEDEXTENSIONS,getExtSupportedExtensions)
+ VCB(REGISTEREXTENSION,registerExtension)
+ CB(GETEXTENSIONFAMILY, getExtensionFamily);
+ VCB(UNREGISTEREXTENSION,unregisterExtension)
+
+ CB(SETNEXTFILE,setNextFile)
+ CB(SETNEXTFILEOLD,setNextFile)
+
+ CB(GETSTATUS,getStatus)
+ CB(GETCURRENT,getCurrent)
+ CB(GETCURPLAYBACKNUMBER,getCurPlaybackNumber)
+ CB(GETNUMTRACKS, getNumTracks);
+ CB(GETPOSITION,getPosition)
+ CB(GETWRITEPOSITION,getWritePosition)
+ CB(GETLENGTH,getLength)
+ CB(GETPLUGINDATA,getPluginData)
+ CB(GETVOLUME,getVolume)
+ CB(GETPAN,getPan)
+ CB(GETVISDATA,getVisData)
+ CB(GETLEFTVUMETER,getLeftVuMeter)
+ CB(GETRIGHTVUMETER,getRightVuMeter)
+ CB(GETEQSTATUS,getEqStatus)
+ CB(GETEQPREAMP,getEqPreamp)
+ CB(GETEQBAND,getEqBand)
+ CB(GETEQAUTO,getEqAuto)
+ CB(GETMUTE,getMute)
+
+ CB(SETPOSITION,setPosition)
+ VCB(SETVOLUME,setVolume)
+ VCB(SETPAN,setPan)
+ VCB(SETEQSTATUS,setEqStatus)
+ VCB(SETEQPREAMP,setEqPreamp)
+ VCB(SETEQBAND,setEqBand)
+ VCB(SETEQAUTO,setEqAuto)
+ VCB(SETMUTE,setMute)
+ CB(GETTITLE,getTitle);
+
+ VCB(ADDCALLBACK,addCallback)
+ VCB(DELCALLBACK,delCallback)
+
+ CB(REGISTERSEQUENCER,registerSequencer)
+ CB(DEREGISTERSEQUENCER,deregisterSequencer)
+ CB(GETSEQUENCER,getSequencer)
+
+ VCB(USERBUTTON,userButton)
+
+ VCB(SETCUSTOMMSG, setCustomMsg)
+
+ VCB(SETPRIORITY, setPriority)
+ CB(GETPRIORITY, getPriority)
+
+ VCB(REBUILDCONVERTERSCHAIN, rebuildConvertersChain)
+ CB(SENDCONVERTERSMSG, sendConvertersMsg)
+
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_coreadmin.h b/Src/Wasabi/api/service/svcs/svc_coreadmin.h
new file mode 100644
index 00000000..276b48c2
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_coreadmin.h
@@ -0,0 +1,230 @@
+#ifndef _SVC_COREADMIN_H
+#define _SVC_COREADMIN_H
+
+#include <bfc/dispatch.h>
+#include <api/core/corehandle.h>
+#include <api/core/sequence.h>
+#include <api/service/services.h>
+
+// There is only ONE INSTANCE of the coreadmin running in the application
+class NOVTABLE svc_coreAdmin : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::COREADMIN; }
+
+ // create a new playback core
+ CoreToken createCore(const char *name=NULL) { return _call(CREATECORE,0,name); }
+
+ // (CoreToken)0 is the maincore
+ // "main" is the maincore
+ CoreToken nameToToken(const char *name) { return _call(NAMETOTOKEN,0,name); }
+
+ int freeCoreByToken(CoreToken core) { return _call(FREECOREBYTOKEN,0,core); }
+ int freeCoreByName(const char *name) { return _call(FREECOREBYNAME,0,name); }
+
+ // returns 1 if present, 0 if non existent
+ int verifyToken(CoreToken token) { return _call(VERIFYTOKEN,0,token); }
+
+ //just the *.mp3 or whatever
+ const char *getSupportedExtensions() { return _call(GETSUPPORTEDEXTENSIONS,(const char *)0); }
+ // including names
+ const char *getExtSupportedExtensions() { return _call(GETEXTSUPPORTEDEXTENSIONS,(const char *)0); }
+ void registerExtension(const char *extensions, const char *extension_name, const char *family=NULL) { _voidcall(REGISTEREXTENSION,extensions,extension_name,family); }
+ const char *getExtensionFamily(const char *extension) {
+ return _call(GETEXTENSIONFAMILY, (const char *)0, extension);
+ }
+ void unregisterExtension(const char *extensions) { _voidcall(UNREGISTEREXTENSION,extensions); }
+
+ int setNextFile(CoreToken core, const char *playstring, const char *destination=NULL) { return _call(SETNEXTFILE,0,core,playstring,destination); }
+ // returns -1 if paused, 0 if stopped and 1 if playing
+ int getStatus(CoreToken core) { return _call(GETSTATUS,0,core); }
+ const char *getCurrent(CoreToken core) { return _call(GETCURRENT,(const char *)0,core); }
+ int getCurPlaybackNumber(CoreToken core) { return _call(GETCURPLAYBACKNUMBER,-1,core); }
+ int getNumTracks(CoreToken core) { return _call(GETNUMTRACKS, -1, core); }
+ int getPosition(CoreToken core) { return _call(GETPOSITION,0,core); }
+ int getWritePosition(CoreToken core) { return _call(GETWRITEPOSITION,0,core); }
+ int setPosition(CoreToken core, int ms) { return _call(SETPOSITION,0,core,ms); }
+ int getLength(CoreToken core) { return _call(GETLENGTH,-1,core); }
+ // this method queries the core plugins directly, bypassing the db
+ // returns size of data
+ int getPluginData(const char *playstring, const char *name,
+ char *data, int data_len, int data_type=0) { return _call(GETPLUGINDATA,0,playstring,name,data,data_len,data_type); }
+ unsigned int getVolume(CoreToken core) { return _call(GETVOLUME,0,core); }
+ // 0..255
+ void setVolume(CoreToken core, unsigned int vol) { _voidcall(SETVOLUME,core,vol); }
+ // -127..127
+ int getPan(CoreToken core) { return _call(GETPAN,0,core); }
+ // -127..127
+ void setPan(CoreToken core, int bal) { _voidcall(SETPAN,core,bal); }
+
+ void setMute(CoreToken core, int mute) { _voidcall(SETMUTE,core,mute); }
+ int getMute(CoreToken core) { return _call(GETMUTE,0,core); }
+
+ // register here for general callbacks in core status.
+ void addCallback(CoreToken core, CoreCallback *cb) { _voidcall(ADDCALLBACK,core,cb); }
+ void delCallback(CoreToken core, CoreCallback *cb) { _voidcall(DELCALLBACK,core,cb); }
+ // get visualization data, returns 0 if you should blank out
+ int getVisData(CoreToken core, void *dataptr, int sizedataptr) { return _call(GETVISDATA,0,core,dataptr,sizedataptr); }
+ int getLeftVuMeter(CoreToken core) { return _call(GETLEFTVUMETER,0,core); }
+ int getRightVuMeter(CoreToken core) { return _call(GETRIGHTVUMETER,0,core); }
+
+ int registerSequencer(CoreToken core, ItemSequencer *seq) { return _call(REGISTERSEQUENCER,0,core,seq); }
+ int deregisterSequencer(CoreToken core, ItemSequencer *seq) { return _call(DEREGISTERSEQUENCER,0,core,seq); }
+ ItemSequencer *getSequencer(CoreToken core) { return _call(GETSEQUENCER, (ItemSequencer*)NULL,core); }
+ // see buttons.h
+ void userButton(CoreToken core, int button) { _voidcall(USERBUTTON,core,button); }
+
+ // returns 1 if on, 0 if off
+ int getEqStatus(CoreToken core) { return _call(GETEQSTATUS,0,core); }
+ void setEqStatus(CoreToken core, int enable) { _voidcall(SETEQSTATUS,core,enable); }
+ // -127 to 127 (-20db to +20db)
+ int getEqPreamp(CoreToken core) { return _call(GETEQPREAMP,0,core); }
+ void setEqPreamp(CoreToken core, int pre) { _voidcall(SETEQPREAMP,core,pre); }
+ // band=0-9
+ int getEqBand(CoreToken core, int band) { return _call(GETEQBAND,0,core,band); }
+ void setEqBand(CoreToken core, int band, int val) { _voidcall(SETEQBAND,core,band,val); }
+ // returns 1 if on, 0 if off
+ int getEqAuto(CoreToken core) { return _call(GETEQAUTO,0,core); }
+ void setEqAuto(CoreToken core, int enable) { _voidcall(SETEQAUTO,core,enable); }
+
+ // for status msgs
+ void setCustomMsg(CoreToken core, const char *text) { _voidcall(SETCUSTOMMSG,core,text); }
+
+ void setPriority(CoreToken core, int priority) { _voidcall(SETPRIORITY,core,priority); }
+ int getPriority(CoreToken core) { return _call(GETPRIORITY,0,core); }
+
+ void rebuildConvertersChain(CoreToken core) { _voidcall(REBUILDCONVERTERSCHAIN,core); }
+
+ int sendConvertersMsg(CoreToken core, const char *msg, const char *value) { return _call(SENDCONVERTERSMSG,0,core,msg,value); }
+ const char *getTitle(CoreToken core) { return _call(GETTITLE,(const char *)NULL, core); }
+
+ enum {
+ CREATECORE=10,
+ NAMETOTOKEN=20,
+ FREECOREBYTOKEN=30,
+ FREECOREBYNAME=40,
+ VERIFYTOKEN=50,
+
+ GETSUPPORTEDEXTENSIONS=100,
+ GETEXTSUPPORTEDEXTENSIONS=110,
+ REGISTEREXTENSION=121, //120 retired
+ GETEXTENSIONFAMILY=122,
+ UNREGISTEREXTENSION=130,
+
+ SETNEXTFILEOLD=200,
+ SETNEXTFILE=210,
+
+ GETSTATUS=300,
+ GETCURRENT=310,
+ GETCURPLAYBACKNUMBER=315,
+ GETNUMTRACKS=317,
+ GETPOSITION=320,
+ GETWRITEPOSITION=330,
+ GETLENGTH=340,
+ GETPLUGINDATA=350,
+ GETVOLUME=360,
+ GETPAN=370,
+ GETVISDATA=380,
+ GETLEFTVUMETER=390,
+ GETRIGHTVUMETER=400,
+ GETEQSTATUS=410,
+ GETEQPREAMP=420,
+ GETEQBAND=430,
+ GETEQAUTO=440,
+ GETMUTE=450,
+
+ SETPOSITION=500,
+ SETVOLUME=510,
+ SETPAN=520,
+ SETEQSTATUS=530,
+ SETEQPREAMP=540,
+ SETEQBAND=550,
+ SETEQAUTO=560,
+ SETMUTE=570,
+
+ ADDCALLBACK=700,
+ DELCALLBACK=710,
+
+ REGISTERSEQUENCER=800,
+ DEREGISTERSEQUENCER=810,
+ GETSEQUENCER=812,
+
+ USERBUTTON=820,
+
+ SETCUSTOMMSG=900,
+
+ SETPRIORITY=1000,
+ GETPRIORITY=1100,
+
+ REBUILDCONVERTERSCHAIN=1200,
+
+ SENDCONVERTERSMSG=1300,
+ GETTITLE=1400,
+ };
+};
+
+class NOVTABLE svc_coreAdminI : public svc_coreAdmin {
+public:
+ virtual CoreToken createCore(const char *name=NULL)=0;
+ virtual CoreToken nameToToken(const char *name)=0;
+ virtual int freeCoreByToken(CoreToken core)=0;
+ virtual int freeCoreByName(const char *name)=0;
+
+ virtual int verifyToken(CoreToken token)=0;
+
+ virtual const char *getSupportedExtensions()=0;
+ virtual const char *getExtSupportedExtensions()=0;
+ virtual void registerExtension(const char *extensions, const char *extension_name, const char *family=NULL)=0;
+ virtual const char *getExtensionFamily(const char *extension)=0;
+ virtual void unregisterExtension(const char *extensions)=0;
+
+ virtual int setNextFile(CoreToken core, const char *playstring, const char *destination)=0;
+ virtual int getStatus(CoreToken core)=0;
+ virtual const char *getCurrent(CoreToken core)=0;
+ virtual int getCurPlaybackNumber(CoreToken core)=0;
+ virtual int getNumTracks(CoreToken core)=0;
+ virtual int getPosition(CoreToken core)=0;
+ virtual int getWritePosition(CoreToken core)=0;
+ virtual int setPosition(CoreToken core, int ms)=0;
+ virtual int getLength(CoreToken core)=0;
+ virtual int getPluginData(const char *playstring, const char *name, char *data, int data_len, int data_type=0)=0;
+ virtual unsigned int getVolume(CoreToken core)=0;
+ virtual void setVolume(CoreToken core, unsigned int vol)=0;
+ virtual int getPan(CoreToken core)=0;
+ virtual void setPan(CoreToken core, int bal)=0;
+ virtual void addCallback(CoreToken core, CoreCallback *cb)=0;
+ virtual void delCallback(CoreToken core, CoreCallback *cb)=0;
+ virtual int getVisData(CoreToken core, void *dataptr, int sizedataptr)=0;
+ virtual int getLeftVuMeter(CoreToken core)=0;
+ virtual int getRightVuMeter(CoreToken core)=0;
+ virtual void setMute(CoreToken core, int mute)=0;
+ virtual int getMute(CoreToken core)=0;
+
+ virtual int registerSequencer(CoreToken core, ItemSequencer *seq)=0;
+ virtual int deregisterSequencer(CoreToken core, ItemSequencer *seq)=0;
+ virtual ItemSequencer *getSequencer(CoreToken core)=0;
+ virtual void userButton(CoreToken core, int button)=0;
+
+ virtual int getEqStatus(CoreToken core)=0;
+ virtual void setEqStatus(CoreToken core, int enable)=0;
+ virtual int getEqPreamp(CoreToken core)=0;
+ virtual void setEqPreamp(CoreToken core, int pre)=0;
+ virtual int getEqBand(CoreToken core, int band)=0;
+ virtual void setEqBand(CoreToken core, int band, int val)=0;
+ virtual int getEqAuto(CoreToken core)=0;
+ virtual void setEqAuto(CoreToken core, int enable)=0;
+
+ virtual void setCustomMsg(CoreToken core, const char *text)=0;
+
+ virtual void setPriority(CoreToken core, int priority)=0;
+ virtual int getPriority(CoreToken core)=0;
+
+ virtual void rebuildConvertersChain(CoreToken core)=0;
+
+ virtual int sendConvertersMsg(CoreToken core, const char *msg, const char *value)=0;
+ virtual const char *getTitle(CoreToken core)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_db.cpp b/Src/Wasabi/api/service/svcs/svc_db.cpp
new file mode 100644
index 00000000..7a5852b2
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_db.cpp
@@ -0,0 +1,78 @@
+#include <precomp.h>
+
+#include "svc_db.h"
+
+#define CBCLASS svc_dbI
+START_DISPATCH;
+ CB(OPENTABLE, openTable);
+ VCB(CLOSETABLE, closeTable);
+ CB(TESTQUERYFORMAT, testQueryFormat);
+END_DISPATCH;
+#undef CBCLASS
+
+
+#define CBCLASS dbSvcTableI
+START_DISPATCH;
+ CB(GETSCANNER, getScanner);
+ CB(NEWSCANNER, newScanner);
+ VCB(DELETESCANNER, deleteScanner);
+ VCB(CBNEW, _new);
+ VCB(CBINSERT, insert);
+ VCB(CBCANCEL, cancel);
+ VCB(CBEDIT, edit);
+ VCB(CBPOST, post);
+ VCB(CBDELETE, _delete);
+ CB(EDITING, editing);
+ VCB(SETFIELDBYNAME, setFieldByName);
+ VCB(SETFIELDBYID, setFieldById);
+ VCB(DELETEFIELDBYNAME, deleteFieldByName);
+ VCB(DELETEFIELDBYID, deleteFieldById);
+ VCB(ADDCOLUMN, addColumn);
+ VCB(ADDINDEXBYNAME, addIndexByName);
+ VCB(ADDINDEXBYID, addIndexById);
+ VCB(DROPINDEXBYNAME, dropIndexByName);
+ VCB(DROPINDEXBYID, dropIndexById);
+ VCB(SYNC, sync);
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS dbSvcScannerI
+START_DISPATCH;
+ VCB(CBFIRST, first);
+ VCB(CBLAST, last);
+ VCB(CBNEXT, block_next);
+ VCB(CBPREVIOUS, block_previous);
+ CB(CBNEXT2, next);
+ CB(CBPREVIOUS2, previous);
+ VCB(CBPUSH, push);
+ VCB(CBPOP, pop);
+ CB(CBEOF, eof);
+ CB(CBBOF, bof);
+ CB(GETNUMROWS, getNumRows);
+ VCB(MOVETOROW, moveToRow);
+ CB(GETCURROW, getCurRow);
+ CB(LOCATEBYNAME, locateByName);
+ CB(LOCATEBYID, locateById);
+ CB(GETNUMCOLS, getNumCols);
+ CB(ENUMCOL, enumCol);
+ CB(GETCOLBYNAME, getColByName);
+ CB(GETCOLBYID, getColByName);
+ CB(GETFIELDBYNAME, getFieldByName);
+ CB(GETFIELDBYID, getFieldById);
+ VCB(SETINDEXBYNAME, setIndexByName);
+ VCB(SETINDEXBYID, setIndexById);
+ CB(UNIQUEBYNAME, newUniqueScannerByName);
+ CB(UNIQUEBYID, newUniqueScannerById);
+ VCB(DELETEUNIQUE, deleteUniqueScanner);
+ CB(QUERY, query);
+ VCB(CANCELQUERY, cancelQuery);
+ CB(INDEXCHANGED, hasIndexChanged);
+ VCB(CLEARDIRTYBIT, clearDirtyBit);
+ VCB(JOINSCANNER, joinScanner);
+ VCB(UNJOINSCANNER, unjoinScanner);
+ CB(GETLASTQUERY, getLastQuery);
+ VCB(SETBLOCKING, setBlocking);
+END_DISPATCH;
+#undef CBCLASS
+
+
diff --git a/Src/Wasabi/api/service/svcs/svc_db.h b/Src/Wasabi/api/service/svcs/svc_db.h
new file mode 100644
index 00000000..6ea5b8d4
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_db.h
@@ -0,0 +1,512 @@
+#ifndef _SVC_DB_H
+#define _SVC_DB_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+typedef enum {
+ DBSVC_DATATYPE_UNKNOWN = 0,
+ DBSVC_DATATYPE_INT = 1,
+ DBSVC_DATATYPE_STRING = 2,
+ DBSVC_DATATYPE_BINARY = 3,
+ DBSVC_DATATYPE_GUID = 4,
+ DBSVC_DATATYPE_FLOAT = 5,
+} dbSvcDatatypeEnum;
+
+typedef struct {
+ void *data;
+ dbSvcDatatypeEnum datatype;
+ int datalen;
+} dbSvcDatachunk;
+
+typedef struct {
+ const char *name;
+ dbSvcDatatypeEnum datatype;
+ int id;
+ int indexed;
+ int uniques_indexed;
+} dbSvcColInfo;
+
+class dbSvcScanner;
+
+class NOVTABLE dbSvcScanner : public Dispatchable {
+
+ public:
+
+ void first();
+ void last();
+ void block_next(); // blocking call for baclkward compat
+ void block_previous(); // blocking call for baclkward compat
+ int next(); // if non blocking, returns 0 for "HOLD ON!" and 1 for "GOT A ROW!"
+ int previous(); // if non blocking, returns 0 for "HOLD ON!" and 1 for "GOT A ROW!"
+ void push();
+ void pop();
+ int eof();
+ int bof();
+
+ int getNumRows();
+ void moveToRow(int row);
+ int getCurRow();
+
+ int locateByName(const char *col, int from_row, dbSvcDatachunk *data);
+ int locateById(int id, int from_row, dbSvcDatachunk *data);
+
+ int getNumCols();
+ dbSvcColInfo *enumCol(int n);
+ dbSvcColInfo *getColById(int n);
+ dbSvcColInfo *getColByName(const char *col);
+
+ dbSvcDatachunk *getFieldByName(const char *col);
+ dbSvcDatachunk *getFieldById(int id);
+
+ void setIndexByName(const char *col);
+ void setIndexById(int id);
+
+ dbSvcScanner *newUniqueScannerByName(const char *col);
+ dbSvcScanner *newUniqueScannerById(int colid);
+ void deleteUniqueScanner(dbSvcScanner *);
+
+ int query(const char *query);
+ const char *getLastQuery();
+ void cancelQuery();
+ int hasIndexChanged();
+ void clearDirtyBit();
+
+ void joinScanner(dbSvcScanner *scanner, const char *field);
+ void unjoinScanner(dbSvcScanner *scanner);
+
+ void setBlocking(int b); // blocking is the default behavior
+
+ enum {
+ CBFIRST = 100,
+ CBLAST = 110,
+ CBNEXT = 120, // retired
+ CBPREVIOUS = 130, // retired
+ CBNEXT2 = 121,
+ CBPREVIOUS2 = 131,
+ CBPUSH = 140,
+ CBPOP = 150,
+ CBEOF = 160,
+ CBBOF = 170,
+ GETNUMROWS = 180,
+ MOVETOROW = 190,
+ GETCURROW = 200,
+ LOCATEBYNAME = 210,
+ LOCATEBYID = 220,
+ GETNUMCOLS = 230,
+ ENUMCOL = 240,
+ GETCOLBYID = 250,
+ GETCOLBYNAME = 260,
+ GETFIELDBYNAME = 270,
+ GETFIELDBYID = 280,
+ SETINDEXBYNAME = 290,
+ SETINDEXBYID = 300,
+ QUERY = 310,
+ CANCELQUERY = 320,
+ INDEXCHANGED = 330,
+ CLEARDIRTYBIT = 340,
+ UNIQUEBYNAME = 350,
+ UNIQUEBYID = 360,
+ DELETEUNIQUE = 370,
+ GETLASTQUERY = 380,
+ JOINSCANNER = 390,
+ UNJOINSCANNER = 400,
+ SETBLOCKING = 410,
+ };
+};
+
+
+inline void dbSvcScanner::first() {
+ _voidcall(CBFIRST);
+}
+
+inline void dbSvcScanner::last() {
+ _voidcall(CBLAST);
+}
+
+inline void dbSvcScanner::block_next() {
+ _voidcall(CBNEXT);
+}
+
+inline int dbSvcScanner::next() {
+ return _call(CBNEXT2, 0);
+}
+
+inline void dbSvcScanner::block_previous() {
+ _voidcall(CBPREVIOUS);
+}
+
+inline int dbSvcScanner::previous() {
+ return _call(CBPREVIOUS2, 0);
+}
+
+inline void dbSvcScanner::push() {
+ _voidcall(CBPUSH);
+}
+
+inline void dbSvcScanner::pop() {
+ _voidcall(CBPOP);
+}
+
+inline int dbSvcScanner::eof() {
+ return _call(CBEOF, 0);
+}
+
+inline int dbSvcScanner::bof() {
+ return _call(CBBOF, 0);
+}
+
+inline int dbSvcScanner::getNumRows() {
+ return _call(GETNUMROWS, 0);
+}
+
+inline void dbSvcScanner::moveToRow(int row) {
+ _voidcall(MOVETOROW, row);
+}
+
+inline int dbSvcScanner::getCurRow() {
+ return _call(GETCURROW, 0);
+}
+
+inline int dbSvcScanner::locateByName(const char *col, int from_row, dbSvcDatachunk *data) {
+ return _call(LOCATEBYNAME, 0, col, from_row, data);
+}
+
+inline int dbSvcScanner::locateById(int colid, int from_row, dbSvcDatachunk *data) {
+ return _call(LOCATEBYNAME, 0, colid, from_row, data);
+}
+
+inline int dbSvcScanner::getNumCols() {
+ return _call(GETNUMCOLS, 0);
+}
+
+inline dbSvcColInfo *dbSvcScanner::enumCol(int n) {
+ return _call(ENUMCOL, ((dbSvcColInfo *)NULL), n);
+}
+
+inline dbSvcColInfo *dbSvcScanner::getColByName(const char *col) {
+ return _call(GETCOLBYNAME, ((dbSvcColInfo *)NULL), col);
+}
+
+inline dbSvcColInfo *dbSvcScanner::getColById(int colid) {
+ return _call(GETCOLBYID, ((dbSvcColInfo *)NULL), colid);
+}
+
+inline dbSvcDatachunk *dbSvcScanner::getFieldByName(const char *col) {
+ return _call(GETFIELDBYNAME, ((dbSvcDatachunk *)NULL), col);
+}
+
+inline dbSvcDatachunk *dbSvcScanner::getFieldById(int colid) {
+ return _call(GETFIELDBYNAME, ((dbSvcDatachunk *)NULL), colid);
+}
+
+inline void dbSvcScanner::setIndexByName(const char *col) {
+ _voidcall(SETINDEXBYNAME, col);
+}
+
+inline void dbSvcScanner::setIndexById(int colid) {
+ _voidcall(SETINDEXBYID, colid);
+}
+
+inline dbSvcScanner *dbSvcScanner::newUniqueScannerByName(const char *col) {
+ return _call(UNIQUEBYNAME, (dbSvcScanner *)NULL, col);
+}
+
+inline dbSvcScanner *dbSvcScanner::newUniqueScannerById(int colid) {
+ return _call(UNIQUEBYID, (dbSvcScanner *)NULL, colid);
+}
+
+inline void dbSvcScanner::deleteUniqueScanner(dbSvcScanner *s) {
+ _voidcall(DELETEUNIQUE, s);
+}
+
+inline int dbSvcScanner::query(const char *q) {
+ return _call(QUERY, 0, q);
+}
+
+inline void dbSvcScanner::cancelQuery() {
+ _voidcall(CANCELQUERY);
+}
+
+inline int dbSvcScanner::hasIndexChanged() {
+ return _call(INDEXCHANGED, 0);
+}
+
+inline void dbSvcScanner::clearDirtyBit() {
+ _voidcall(CLEARDIRTYBIT);
+}
+
+inline const char *dbSvcScanner::getLastQuery() {
+ return _call(GETLASTQUERY, (const char *)NULL);
+}
+
+inline void dbSvcScanner::joinScanner(dbSvcScanner *scanner, const char *field) {
+ _voidcall(JOINSCANNER, scanner, field);
+}
+
+inline void dbSvcScanner::unjoinScanner(dbSvcScanner *scanner) {
+ _voidcall(UNJOINSCANNER, scanner);
+}
+
+inline void dbSvcScanner::setBlocking(int b) {
+ _voidcall(SETBLOCKING, b);
+}
+
+class NOVTABLE dbSvcScannerI : public dbSvcScanner {
+public:
+ virtual void first()=0;
+ virtual void last()=0;
+ virtual void block_next()=0;
+ virtual void block_previous()=0;
+ virtual int next()=0;
+ virtual int previous()=0;
+ virtual void push()=0;
+ virtual void pop()=0;
+ virtual int eof()=0;
+ virtual int bof()=0;
+ virtual int getNumRows()=0;
+ virtual void moveToRow(int row)=0;
+ virtual int getCurRow()=0;
+ virtual int locateByName(const char *col, int from_row, dbSvcDatachunk *data)=0;
+ virtual int locateById(int id, int from_row, dbSvcDatachunk *data)=0;
+ virtual int getNumCols()=0;
+ virtual dbSvcColInfo *enumCol(int n)=0;
+ virtual dbSvcColInfo *getColById(int n)=0;
+ virtual dbSvcColInfo *getColByName(const char *col)=0;
+ virtual dbSvcDatachunk *getFieldByName(const char *col)=0;
+ virtual dbSvcDatachunk *getFieldById(int id)=0;
+ virtual void setIndexByName(const char *col)=0;
+ virtual void setIndexById(int id)=0;
+ virtual dbSvcScanner *newUniqueScannerByName(const char *col)=0;
+ virtual dbSvcScanner *newUniqueScannerById(int colid)=0;
+ virtual void deleteUniqueScanner(dbSvcScanner *)=0;
+ virtual int query(const char *query)=0;
+ virtual void cancelQuery()=0;
+ virtual int hasIndexChanged()=0;
+ virtual void clearDirtyBit()=0;
+ virtual const char *getLastQuery()=0;
+ virtual void joinScanner(dbSvcScanner *scanner, const char *field)=0;
+ virtual void unjoinScanner(dbSvcScanner *scanner)=0;
+ virtual void setBlocking(int block)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+class NOVTABLE dbSvcTable : public Dispatchable {
+public:
+ dbSvcScanner *getScanner();
+ dbSvcScanner *newScanner();
+ void deleteScanner(dbSvcScanner *scanner);
+ void _new();
+ void insert();
+ void cancel();
+ void edit();
+ void post();
+ void _delete();
+ int editing();
+ void setFieldByName(const char *col, dbSvcDatachunk *data);
+ void setFieldById(int colid, dbSvcDatachunk *data);
+ void deleteFieldByName(const char *col);
+ void deleteFieldById(int colid);
+ void addColumn(const char *colname, int colid, int datatype, int uniques_indexed);
+ void addIndexByName(const char *col);
+ void addIndexById(int colid);
+ void dropIndexByName(const char *col);
+ void dropIndexById(int colid);
+ void sync();
+
+ enum {
+ GETSCANNER = 100,
+ NEWSCANNER = 110,
+ DELETESCANNER = 111,
+ CBNEW = 120,
+ CBINSERT = 130,
+ CBCANCEL = 140,
+ CBEDIT = 150,
+ CBPOST = 160,
+ CBDELETE = 170,
+ EDITING = 180,
+ SETFIELDBYNAME = 190,
+ SETFIELDBYID = 200,
+ DELETEFIELDBYNAME = 210,
+ DELETEFIELDBYID = 220,
+ ADDCOLUMN = 230,
+ ADDINDEXBYNAME = 240,
+ ADDINDEXBYID = 250,
+ SYNC = 260,
+ DROPINDEXBYNAME = 270,
+ DROPINDEXBYID = 280,
+ };
+};
+
+inline dbSvcScanner *dbSvcTable::getScanner() {
+ return _call(GETSCANNER, static_cast<dbSvcScanner *>(NULL));
+}
+
+inline dbSvcScanner *dbSvcTable::newScanner() {
+ return _call(NEWSCANNER, static_cast<dbSvcScanner *>(NULL));
+}
+
+inline void dbSvcTable::deleteScanner(dbSvcScanner *scanner) {
+ _voidcall(DELETESCANNER, scanner);
+}
+
+inline void dbSvcTable::_new() {
+ _voidcall(CBNEW);
+}
+
+inline void dbSvcTable::insert() {
+ _voidcall(CBINSERT);
+}
+
+inline void dbSvcTable::cancel() {
+ _voidcall(CBCANCEL);
+}
+
+inline void dbSvcTable::edit() {
+ _voidcall(CBEDIT);
+}
+
+inline void dbSvcTable::post() {
+ _voidcall(CBPOST);
+}
+
+inline void dbSvcTable::_delete() {
+ _voidcall(CBDELETE);
+}
+
+inline int dbSvcTable::editing() {
+ return _call(EDITING, 0);
+}
+
+inline void dbSvcTable::setFieldByName(const char *col, dbSvcDatachunk *data) {
+ _voidcall(SETFIELDBYNAME, col, data);
+}
+
+inline void dbSvcTable::setFieldById(int colid, dbSvcDatachunk *data) {
+ _voidcall(SETFIELDBYID, colid, data);
+}
+
+inline void dbSvcTable::deleteFieldByName(const char *col) {
+ _voidcall(DELETEFIELDBYNAME, col);
+}
+
+inline void dbSvcTable::deleteFieldById(int colid) {
+ _voidcall(DELETEFIELDBYID, colid);
+}
+
+inline void dbSvcTable::addColumn(const char *colname, int colid, int datatype, int index_uniques) {
+ _voidcall(ADDCOLUMN, colname, colid, datatype, index_uniques);
+}
+
+inline void dbSvcTable::addIndexByName(const char *col) {
+ _voidcall(ADDINDEXBYNAME, col);
+}
+
+inline void dbSvcTable::addIndexById(int colid) {
+ _voidcall(ADDINDEXBYID, colid);
+}
+
+inline void dbSvcTable::dropIndexByName(const char *col) {
+ _voidcall(DROPINDEXBYNAME, col);
+}
+
+inline void dbSvcTable::dropIndexById(int colid) {
+ _voidcall(DROPINDEXBYID, colid);
+}
+
+inline void dbSvcTable::sync() {
+ _voidcall(SYNC);
+}
+
+class NOVTABLE dbSvcTableI : public dbSvcTable {
+public:
+ virtual dbSvcScanner *getScanner()=0;
+ virtual dbSvcScanner *newScanner()=0;
+ virtual void deleteScanner(dbSvcScanner *scanner)=0;
+ virtual void _new()=0;
+ virtual void insert()=0;
+ virtual void cancel()=0;
+ virtual void edit()=0;
+ virtual void post()=0;
+ virtual void _delete()=0;
+ virtual int editing()=0;
+ virtual void setFieldByName(const char *col, dbSvcDatachunk *data)=0;
+ virtual void setFieldById(int colid, dbSvcDatachunk *data)=0;
+ virtual void deleteFieldByName(const char *col)=0;
+ virtual void deleteFieldById(int colid)=0;
+ virtual void addColumn(const char *colname, int colid, int datatype, int index_uniques)=0;
+ virtual void addIndexByName(const char *col)=0;
+ virtual void addIndexById(int colid)=0;
+ virtual void dropIndexByName(const char *col)=0;
+ virtual void dropIndexById(int colid)=0;
+ virtual void sync()=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+class NOVTABLE svc_db : public Dispatchable {
+protected:
+ svc_db() {}
+ ~svc_db() {}
+public:
+ static FOURCC getServiceType() { return WaSvc::DB; }
+
+ int testQueryFormat(int queryformat);
+
+ dbSvcTable *openTable(const char *tablefilename, int create_if_not_exist, int cache_in_memory);
+ void closeTable(dbSvcTable *table);
+
+ enum {
+ TESTQUERYFORMAT = 10,
+ OPENTABLE = 20,
+ CLOSETABLE = 30,
+ };
+};
+
+inline int svc_db::testQueryFormat(int queryformat) {
+ return _call(TESTQUERYFORMAT, 0, queryformat);
+}
+
+inline dbSvcTable *svc_db::openTable(const char *tablename, int create_if_not_exist, int cache_in_memory) {
+ return _call(OPENTABLE, static_cast<dbSvcTable *>(NULL), tablename, create_if_not_exist, cache_in_memory);
+}
+
+inline void svc_db::closeTable(dbSvcTable *table) {
+ _voidcall(CLOSETABLE, table);
+}
+
+// derive from this one
+class NOVTABLE svc_dbI : public svc_db{
+public:
+ virtual int testQueryFormat(int queryformat)=0;
+ virtual dbSvcTable *openTable(const char *filename, int create_if_not_exist, int cache_in_memory)=0;
+ virtual void closeTable(dbSvcTable *table)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+
+enum {
+ DBQFORMAT_MINIQUERY =1,
+ DBQFORMAT_SQL =2,
+};
+
+class DatabaseEnum : public SvcEnumT<svc_db> {
+public:
+ DatabaseEnum(int queryformat=DBQFORMAT_MINIQUERY) :
+ query_format(queryformat) {}
+protected:
+ virtual int testService(svc_db *svc) {
+ return svc->testQueryFormat(query_format);
+ }
+
+private:
+ int query_format;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_debuggerui.cpp b/Src/Wasabi/api/service/svcs/svc_debuggerui.cpp
new file mode 100644
index 00000000..240baad2
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_debuggerui.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+
+#include "svc_debuggerui.h"
+
+#define CBCLASS svc_debuggerUII
+START_DISPATCH;
+ CB(CREATEUI, createUI);
+ VCB(DESTROYUI, destroyUI);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_debuggerui.h b/Src/Wasabi/api/service/svcs/svc_debuggerui.h
new file mode 100644
index 00000000..5e96a15f
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_debuggerui.h
@@ -0,0 +1,44 @@
+#ifndef _SVC_DEBUGGERUI_H
+#define _SVC_DEBUGGERUI_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class DebuggerUI;
+
+// {8B055A0D-9A57-428c-BCFC-88F75AEF2CAD}
+static const GUID SERVICE_DEBUGGERUI =
+{ 0x8b055a0d, 0x9a57, 0x428c, { 0xbc, 0xfc, 0x88, 0xf7, 0x5a, 0xef, 0x2c, 0xad } };
+
+class svc_debuggerUI : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::UNIQUE; }
+
+ DebuggerUI *createUI();
+ void destroyUI(DebuggerUI *ui);
+
+protected:
+ enum {
+ CREATEUI=10,
+ DESTROYUI=20,
+ };
+};
+
+inline DebuggerUI *svc_debuggerUI::createUI() {
+ return _call(CREATEUI, (DebuggerUI *)NULL);
+}
+
+inline void svc_debuggerUI::destroyUI(DebuggerUI *ui) {
+ _voidcall(DESTROYUI, ui);
+}
+
+class svc_debuggerUII : public svc_debuggerUI {
+public:
+ virtual DebuggerUI *createUI()=0;
+ virtual void destroyUI(DebuggerUI *ui)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_device.h b/Src/Wasabi/api/service/svcs/svc_device.h
new file mode 100644
index 00000000..9a75f2b0
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_device.h
@@ -0,0 +1,54 @@
+#ifndef _SVC_DEVICE_H
+#define _SVC_DEVICE_H
+
+#include <bfc/dispatch.h>
+
+// not done at all :) BU
+
+class NOVTABLE svc_device : public Dispatchable {
+public:
+ const char *getDeviceName();
+ const char *getDeviceUID(); // some kind of unique per-device id if possible
+
+ // return total storage space and
+ int getDeviceSpace(unsigned int *space, unsigned int *spacefree);
+ // return (estimated) # of seconds stored/available
+ int getDeviceTime(unsigned int *time, unsigned int *timefree);
+
+ // high-level stuff
+ // give us a filename we should use if we transfer object to you
+ // this name will be used as the media conversion pipeline's output
+ // filename so your transfer filter will kick in... of course something
+ // like d:\music\blah.mp3 is fine too
+ int getTargetFilename(const char *playstring, char *fn, int buflen);
+
+ // file/directory enumeration
+// int opendir(const char *path);
+// int readdir(const char *path);
+
+#if 0
+ // return a handle like C-style open
+ int openFile(const char *filename, const char *mode);
+ void closeFile(int handle);
+
+ int writeToFile(int handle, const void *data, int length);
+ int seek(int handle, int
+
+ int putFile(const char *filename, const void *data, unsigned int length);
+ int readFile(const char *filename, void *buffer, unsigned int offset, unsigned int length)=0;
+ int getFileAttrib(const char *filename, const char *name, char *buf, int len);
+ int setFileAttrib(const char *filename, const char *name, const char *buf, int len);
+#endif
+
+ // playlist manipulation
+ int playlistCreate(const char *playlist_name);
+ int playlistDelete(const char *playlist_name);
+
+ int playlistGetNumItems(const char *playlist_name);
+ int playlistEnumItem(const char *playlist_name, char *playstring, int len);
+
+ int playlistAppendItem(const char *playlist_name, const char *playstring);
+ int playlistRemoveItem(const char *playlist_name, int position);
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_droptarget.cpp b/Src/Wasabi/api/service/svcs/svc_droptarget.cpp
new file mode 100644
index 00000000..42ff876e
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_droptarget.cpp
@@ -0,0 +1,11 @@
+#include <precomp.h>
+
+#include "svc_droptarget.h"
+
+#define CBCLASS svc_dropTargetI
+START_DISPATCH;
+ CB(TESTTARGET, testTarget);
+ CB(GETDRAGINTERFACEFORTYPE, getDragInterfaceForType);
+ CB(RELEASEDRAGINTERFACE, releaseDragInterface);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_droptarget.h b/Src/Wasabi/api/service/svcs/svc_droptarget.h
new file mode 100644
index 00000000..73b4b6aa
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_droptarget.h
@@ -0,0 +1,82 @@
+#ifndef _SVC_DROPTARGET_H
+#define _SVC_DROPTARGET_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class DragInterface; // see bfc/drag.h
+
+class NOVTABLE svc_dropTarget : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::DROPTARGET; }
+
+ int testTarget(FOURCC type);
+
+ DragInterface *getDragInterfaceForType(FOURCC type);
+ int releaseDragInterface(DragInterface *di);
+
+protected:
+ enum {
+ TESTTARGET=100,
+ GETDRAGINTERFACEFORTYPE=200,
+ RELEASEDRAGINTERFACE=210,
+ };
+};
+
+inline
+int svc_dropTarget::testTarget(FOURCC type) {
+ return _call(TESTTARGET, 0, type);
+}
+
+inline
+DragInterface *svc_dropTarget::getDragInterfaceForType(FOURCC type) {
+ return _call(GETDRAGINTERFACEFORTYPE, (DragInterface*)NULL, type);
+}
+
+inline
+int svc_dropTarget::releaseDragInterface(DragInterface *di) {
+ return _call(RELEASEDRAGINTERFACE, 0, di);
+}
+
+class svc_dropTargetI : public svc_dropTarget {
+public:
+ virtual int testTarget(FOURCC type)=0;
+
+ virtual DragInterface *getDragInterfaceForType(FOURCC type)=0;
+ virtual int releaseDragInterface(DragInterface *di)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class DropTargetCreator : public waServiceFactoryTSingle<svc_dropTarget, T> { };
+
+#include <api/service/svc_enum.h>
+#include <api/wnd/drag.h>
+
+class DropTargetEnum : public SvcEnumT<svc_dropTarget> {
+public:
+ DropTargetEnum(FOURCC type) : dt_type(type) {}
+ static int throwDrop(FOURCC type, ifc_window *sourceWnd, int x=0, int y=0) {
+ DropTargetEnum dte(type);
+ svc_dropTarget *sdt = dte.getFirst();
+ if (sdt == NULL) return 0;
+ DragInterface *di = sdt->getDragInterfaceForType(type);
+ int r = 0;
+ if (di != NULL) r = di->dragDrop(sourceWnd, 0, 0);
+ sdt->releaseDragInterface(di);
+ return r;
+ }
+protected:
+ virtual int testService(svc_dropTarget *svc) {
+ return (svc->testTarget(dt_type));
+ }
+private:
+ FOURCC dt_type;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_eval.cpp b/Src/Wasabi/api/service/svcs/svc_eval.cpp
new file mode 100644
index 00000000..cb03f2de
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_eval.cpp
@@ -0,0 +1,11 @@
+#include <precomp.h>
+
+#include "svc_eval.h"
+
+#define CBCLASS svc_evaluatorI
+START_DISPATCH
+ CB(GETEVALTYPE, getEvalType);
+ CB(SETEVALSTRING, setEvalString);
+ CB(EVALUATE, evaluate);
+END_DISPATCH
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_eval.h b/Src/Wasabi/api/service/svcs/svc_eval.h
new file mode 100644
index 00000000..d198c1d1
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_eval.h
@@ -0,0 +1,64 @@
+#ifndef _SVC_EVAL_H
+#define _SVC_EVAL_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class NOVTABLE svc_evaluator : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::EVALUATOR; }
+
+ const char *getEvalType(); // "php", "perl", "math", "xmlgen", etc.
+
+// these are for future optimization -- BU
+ // void assignVar(const char *name, const char *value);
+ // const char *getVarValue(const char *name);
+ // int getVarIndex(const char *name);
+ // const char *getVarValueByIndex(int pos);
+
+ int setEvalString(const char *string, int length, BOOL isBinary);
+ // free the returned memory with api->sysFree()
+ const char *evaluate(int *length, BOOL *isBinary);
+
+protected:
+ enum {
+ GETEVALTYPE, ASSIGNVAR, GETVARVALUE, GETVARINDEX, GETVARVALUEBYINDEX,
+ SETEVALSTRING, EVALUATE
+ };
+};
+
+inline
+const char *svc_evaluator::getEvalType() {
+ return _call(GETEVALTYPE, (const char *)NULL);
+}
+
+inline
+int svc_evaluator::setEvalString(const char *string, int length, BOOL isBinary){
+ return _call(SETEVALSTRING, FALSE, string, length, isBinary);
+}
+
+inline
+const char *svc_evaluator::evaluate(int *length, BOOL *isBinary) {
+ return _call(EVALUATE, (const char *)NULL, length, isBinary);
+}
+
+// implementor derives from this one
+class NOVTABLE svc_evaluatorI : public svc_evaluator {
+public:
+ virtual const char *getEvalType()=0;
+
+// void assignVar(const char *name, const char *value);
+// const char *getVarValue(const char *name);
+// int getVarIndex(const char *name);
+// const char *getVarValueByIndex(int pos);
+
+ // implementor should make a copy of the string (if needed)
+ virtual int setEvalString(const char *string, int length, BOOL isBinary)=0;
+ // implementor should alloc returned mem w/ api->sysMalloc()
+ virtual const char *evaluate(int *length, BOOL *isBinary)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_export.h b/Src/Wasabi/api/service/svcs/svc_export.h
new file mode 100644
index 00000000..4b6085f1
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_export.h
@@ -0,0 +1,32 @@
+#ifndef _SVC_EXPORT_H
+#define _SVC_EXPORT_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class svc_fileReader;
+
+class svc_exporter /*: public Dispatchable*/ {
+public:
+ static FOURCC getServiceType() { return WaSvc::EXPORTER; }
+
+ virtual int isMine(const char *exportid, const char *family)=0;
+
+ virtual svc_fileReader *open()=0;
+ virtual close(svc_fileReader *reader)=0;
+};
+
+class ExporterEnum : public SvcEnumT<svc_exporter> {
+public:
+ ExporterEnum(const char *exportid, const char *family=NULL) :
+ id(exportid), fam(family) { }
+
+ virtual int testService(svc_exporter *svc) {
+ return svc->isMine(id, fam);
+ }
+
+private:
+ String id, fam;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_fileread.cpp b/Src/Wasabi/api/service/svcs/svc_fileread.cpp
new file mode 100644
index 00000000..95fbfd5a
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_fileread.cpp
@@ -0,0 +1,30 @@
+#include <precomp.h>
+
+#include <api/filereader/svc_filereadI.h>
+
+#define CBCLASS svc_fileReaderI
+START_DISPATCH;
+ CB(ISMINE, isMine);
+ CB(OPEN, open);
+ CB(READ, read);
+ CB(WRITE, write);
+ VCB(CLOSE, close);
+ VCB(ABORT, abort);
+ CB(GETLENGTH, getLength);
+ CB(GETPOS, getPos);
+ CB(CANSEEK, canSeek);
+ CB(SEEK, seek);
+ CB(HASHEADERS,hasHeaders);
+ CB(GETHEADER,getHeader);
+ CB(EXISTS,exists);
+ CB(REMOVE,remove);
+ CB(REMOVEUNDOABLE,removeUndoable);
+ CB(MOVE,move);
+ CB(BYTESAVAILABLE,bytesAvailable);
+ VCB(SETMETADATACALLBACK,setMetaDataCallback);
+ CB(CANPREFETCH,canPrefetch);
+ CB(CANSETEOF, canSetEOF);
+ CB(SETEOF, setEOF);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_fileread.h b/Src/Wasabi/api/service/svcs/svc_fileread.h
new file mode 100644
index 00000000..c26007dc
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_fileread.h
@@ -0,0 +1,199 @@
+#ifndef _SVC_FILEREAD_H
+#define _SVC_FILEREAD_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include <api/service/services.h>
+#include <stdint.h>
+
+namespace SvcFileReader
+{
+ enum {
+ READ = 1,
+ WRITE = 2,
+ APPEND = 4,
+ PLUS = 8,
+ BINARY = 16,
+ TEXT = 32,
+ };
+};
+
+class api_readercallback;
+
+class NOVTABLE svc_fileReader : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::FILEREADER; }
+
+ int isMine(const wchar_t *filename, int mode = SvcFileReader::READ); //don't really open. returns -1 if "don't know until I open it"
+ int open(const wchar_t *filename, int mode = SvcFileReader::READ);
+ size_t read(int8_t *buffer, size_t length);
+ size_t write(const int8_t *buffer, size_t length);
+ void close(); // safe to call even when not open
+
+ int canSetEOF();
+ /**
+ Asks the file reader to change the file length to newlen. Will fail if file
+ was not opened for writing.
+ @ret 1 on success, 0 on failure, -1 if operation is unsupported by this reader.
+ */
+ int setEOF(uint64_t newlen);
+
+ void abort();
+
+ uint64_t getLength();
+ uint64_t getPos();
+
+ int canSeek();
+ int seek(uint64_t position);
+ uint64_t bytesAvailable(uint64_t requested);
+
+ int hasHeaders();
+ const char *getHeader(const char *header);
+
+ int exists(const wchar_t *filename);
+
+ int remove(const wchar_t *filename);
+
+ int removeUndoable(const wchar_t *filename);
+
+ int move(const wchar_t *filename, const wchar_t *destfilename);
+
+ int canPrefetch();
+
+ void setMetaDataCallback(api_readercallback *cb);
+
+ enum
+ {
+ ISMINE = 0,
+ OPEN = 10,
+ READ = 20,
+ WRITE = 30,
+ CLOSE = 40,
+ ABORT = 50,
+ GETLENGTH = 60,
+ GETPOS = 70,
+ CANSEEK = 80,
+ SEEK = 90,
+ HASHEADERS = 100,
+ GETHEADER = 110,
+ EXISTS = 120,
+ REMOVE = 130,
+ REMOVEUNDOABLE = 135,
+ BYTESAVAILABLE = 140,
+ SETMETADATACALLBACK = 150,
+ MOVE = 160,
+ CANPREFETCH = 170,
+ CANSETEOF = 180,
+ SETEOF = 190,
+ };
+};
+
+inline
+int svc_fileReader::isMine(const wchar_t *filename, int mode)
+{
+ return _call(ISMINE, -1, filename, mode);
+}
+
+inline int svc_fileReader::open(const wchar_t *filename, int mode)
+{
+ return _call(OPEN, 0, filename, mode);
+}
+
+inline size_t svc_fileReader::read(int8_t *buffer, size_t length)
+{
+ return _call(READ, 0, buffer, length);
+}
+
+inline size_t svc_fileReader::write(const int8_t *buffer, size_t length)
+{
+ return _call(WRITE, 0, buffer, length);
+}
+
+inline void svc_fileReader::close()
+{
+ _voidcall(CLOSE);
+}
+
+inline int svc_fileReader::canSetEOF()
+{
+ return _call(CANSETEOF, 0);
+}
+
+inline int svc_fileReader::setEOF(uint64_t newlen)
+{
+ return _call(SETEOF, -1, newlen);
+}
+
+inline void svc_fileReader::abort()
+{
+ _voidcall(ABORT);
+}
+
+inline uint64_t svc_fileReader::getLength()
+{
+ return _call(GETLENGTH, (uint64_t)-1);
+}
+
+inline uint64_t svc_fileReader::getPos()
+{
+ return _call(GETPOS, (uint64_t)0);
+}
+
+inline int svc_fileReader::canSeek()
+{
+ return _call(CANSEEK, 0);
+}
+
+inline int svc_fileReader::seek(uint64_t position)
+{
+ return _call(SEEK, 0, position);
+}
+
+inline uint64_t svc_fileReader::bytesAvailable(uint64_t requested)
+{
+ return _call(BYTESAVAILABLE, requested, requested);
+}
+
+inline int svc_fileReader::hasHeaders()
+{
+ return _call(HASHEADERS, 0);
+}
+
+inline const char *svc_fileReader::getHeader(const char *header)
+{
+ return _call(GETHEADER, (const char *)NULL, header);
+}
+
+inline int svc_fileReader::exists(const wchar_t *filename)
+{
+ return _call(EXISTS, -1, filename);
+}
+
+inline int svc_fileReader::remove(const wchar_t *filename)
+{
+ return _call(REMOVE, 0, filename);
+}
+
+inline
+int svc_fileReader::removeUndoable(const wchar_t *filename)
+{
+ return _call(REMOVEUNDOABLE, -1, filename);
+}
+
+inline int svc_fileReader::move(const wchar_t *filename, const wchar_t *destfilename)
+{
+ return _call(MOVE, 0, filename, destfilename);
+}
+
+inline void svc_fileReader::setMetaDataCallback(api_readercallback *cb)
+{
+ _voidcall(SETMETADATACALLBACK, cb);
+}
+
+inline int svc_fileReader::canPrefetch()
+{
+ return _call(CANPREFETCH, 1);
+}
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_filesel.cpp b/Src/Wasabi/api/service/svcs/svc_filesel.cpp
new file mode 100644
index 00000000..fc8826b5
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_filesel.cpp
@@ -0,0 +1,15 @@
+#include <precomp.h>
+
+#include "svc_filesel.h"
+
+#define CBCLASS svc_fileSelectorI
+START_DISPATCH;
+ CB(TESTPREFIX, testPrefix);
+ CB(GETPREFIX, getPrefix);
+ CB(SETEXTLIST, setExtList);
+ CB(RUNSELECTOR, runSelector);
+ CB(GETNUMFILESSELECTED, getNumFilesSelected);
+ CB(ENUMFILENAME, enumFilename);
+ CB(GETDIRECTORY, getDirectory);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_filesel.h b/Src/Wasabi/api/service/svcs/svc_filesel.h
new file mode 100644
index 00000000..870a18cc
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_filesel.h
@@ -0,0 +1,89 @@
+#ifndef _SVC_FILESEL_H
+#define _SVC_FILESEL_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class ifc_window;
+
+class NOVTABLE svc_fileSelector : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::FILESELECTOR; }
+
+ int testPrefix(const wchar_t *prefix) {
+ return _call(TESTPREFIX, 0, prefix);
+ }
+ const wchar_t *getPrefix() {
+ return _call(GETPREFIX, L"");
+ }
+ int setTitle(const wchar_t *title) {
+ return _call(SETTITLE, 0, title);
+ }
+ int setExtList(const wchar_t *ext) {
+ return _call(SETEXTLIST, 0, ext);
+ }
+ int runSelector(ifc_window *parWnd, int type, int allow_multiple, const wchar_t *ident=NULL, const wchar_t *default_dir=NULL) {
+ return _call(RUNSELECTOR, 0, parWnd, type, allow_multiple, ident, default_dir);
+ }
+ int getNumFilesSelected() {
+ return _call(GETNUMFILESSELECTED, 0);
+ }
+ const wchar_t *enumFilename(int n) {
+ return _call(ENUMFILENAME, L"", n);
+ }
+ const wchar_t *getDirectory() {
+ return _call(GETDIRECTORY, L"");
+ }
+
+protected:
+ enum {
+ TESTPREFIX=0,
+ GETPREFIX=10,
+ SETTITLE=20,
+ SETEXTLIST=30,
+ RUNSELECTOR=40,
+ GETNUMFILESSELECTED=50,
+ ENUMFILENAME=60,
+ GETDIRECTORY=70,
+ };
+};
+
+namespace FileSel {
+ enum {
+ OPEN=1, SAVEAS=2,
+ };
+};
+
+
+class NOVTABLE svc_fileSelectorI : public svc_fileSelector {
+public:
+ virtual int testPrefix(const wchar_t *prefix)=0;
+ virtual const wchar_t *getPrefix()=0;
+ virtual int setTitle(const wchar_t *title) { return 0; }
+ virtual int setExtList(const wchar_t *ext) { return 0; }
+ virtual int runSelector(ifc_window *parWnd, int type, int allow_multiple, const wchar_t *ident=NULL, const wchar_t *default_dir=NULL)=0;
+ virtual int getNumFilesSelected()=0;
+ virtual const wchar_t *enumFilename(int n)=0;
+ virtual const wchar_t *getDirectory()=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class FileSelectorEnum : public SvcEnumT<svc_fileSelector> {
+public:
+ FileSelectorEnum(const wchar_t *_prefix=L"files") : prefix(_prefix) { }
+
+protected:
+ virtual int testService(svc_fileSelector *svc) {
+ return prefix.isempty() || svc->testPrefix(prefix);
+ }
+
+private:
+ StringW prefix;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_font.cpp b/Src/Wasabi/api/service/svcs/svc_font.cpp
new file mode 100644
index 00000000..61c77d5d
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_font.cpp
@@ -0,0 +1,27 @@
+#include <precomp.h>
+#include <api/font/svc_fonti.h>
+
+#define CBCLASS svc_fontI
+START_DISPATCH
+ VCB(TEXTOUT, textOut);
+ VCB(TEXTOUT2, textOut2);
+ VCB(TEXTOUTELLIPSED, textOutEllipsed);
+ VCB(TEXTOUTWRAPPED, textOutWrapped);
+ VCB(TEXTOUTWRAPPEDPATHED, textOutWrappedPathed);
+ VCB(TEXTOUTCENTERED, textOutCentered);
+ CB(GETTEXTWIDTH, getTextWidth);
+ CB(GETTEXTHEIGHT, getTextHeight);
+ CB(GETTEXTHEIGHT2, getTextHeight2);
+ VCB(GETTEXTEXTENT, getTextExtent);
+ VCB(SETFONTID, setFontId);
+ CB(GETFONTID, getFontId);
+ CB(GETFACENAME_, getFaceName);
+ CB(ISBITMAP, isBitmap);
+ CB(GETSCRIPTID, getScriptId);
+ VCB(SETSCRIPTID, setScriptId);
+ VCB(SETFONTFACE, setFontFace);
+ CB(ADDFONTRESOURCE, addFontResource);
+ CB(ADDFONTRESOURCE2, addFontResource2);
+ CB(GETFONTSVCNAME, getFontSvcName);
+END_DISPATCH
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_font.h b/Src/Wasabi/api/service/svcs/svc_font.h
new file mode 100644
index 00000000..9e301489
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_font.h
@@ -0,0 +1,178 @@
+#ifndef _SVC_FONT_H
+#define _SVC_FONT_H
+
+#include <bfc/dispatch.h>
+#include <bfc/std_file.h>
+#include <stdio.h>
+#include <api/service/services.h>
+//#include <api/service/servicei.h>
+
+class ifc_canvas;
+
+#ifdef _WIN32
+enum
+{
+ STDFONT_LEFT = DT_LEFT,
+ STDFONT_RIGHT = DT_RIGHT,
+ STDFONT_CENTER = DT_CENTER,
+};
+#else
+#warning TODO: find good values for these
+enum
+{
+ STDFONT_RIGHT = 1,
+ STDFONT_CENTER = 2,
+ STDFONT_LEFT = 4,
+};
+#endif
+
+class NOVTABLE svc_font : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::FONTRENDER; }
+
+ void textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias); // abstract interface
+ void textOut(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias);
+ void textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias);
+ void textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias);
+ void textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias);
+ void textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias);
+ int getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias);
+ int getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias);
+ int getTextHeight(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias);
+ void getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias);
+
+ void setFontId(const wchar_t *id);
+ const wchar_t *getFontId();
+ const wchar_t *getFaceName();
+ int isBitmap();
+ int getScriptId();
+ void setScriptId(int id);
+
+ void setFontFace(const wchar_t *face);
+ int addFontResource(HANDLE f, const wchar_t *name);
+ int addFontResource2(void *mem, int datalen, const wchar_t *name);
+
+ const wchar_t *getFontSvcName();
+
+protected:
+ enum {
+ TEXTOUT,
+ TEXTOUT2,
+ TEXTOUTELLIPSED,
+ TEXTOUTWRAPPED,
+ TEXTOUTWRAPPEDPATHED,
+ TEXTOUTCENTERED,
+ GETTEXTWIDTH,
+ GETTEXTHEIGHT,
+ GETTEXTHEIGHT2,
+ GETTEXTEXTENT,
+ SETFONTID,
+ GETFONTID,
+ GETFACENAME_, // GETFACENAME is taken in win32
+ ISBITMAP,
+ GETSCRIPTID,
+ SETSCRIPTID,
+ SETFONTFACE,
+ ADDFONTRESOURCE,
+ ADDFONTRESOURCE2,
+ GETFONTSVCNAME,
+ };
+};
+
+inline void svc_font::textOut(ifc_canvas *c, int x, int y, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)
+{
+ _voidcall(TEXTOUT, c, x, y, txt, size, bold, opaque, underline, italic, color, bkcolor, xoffset, yoffset, antialias);
+}
+
+inline void svc_font::textOut(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)
+{
+ _voidcall(TEXTOUT2, c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialias);
+}
+
+inline void svc_font::textOutEllipsed(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)
+{
+ _voidcall(TEXTOUTELLIPSED, c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialias);
+}
+
+inline void svc_font::textOutWrapped(ifc_canvas *c, int x, int y, int w, int h, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)
+{
+ _voidcall(TEXTOUTWRAPPED, c, x, y, w, h, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialias);
+}
+
+inline void svc_font::textOutWrappedPathed(ifc_canvas *c, int x, int y, int w, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)
+{
+ _voidcall(TEXTOUTWRAPPEDPATHED, c, x, y, w, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialias);
+}
+
+inline void svc_font::textOutCentered(ifc_canvas *c, RECT *r, const wchar_t *txt, int size, int bold, int opaque, int underline, int italic, int align, ARGB32 color, ARGB32 bkcolor, int xoffset, int yoffset, int antialias)
+{
+ _voidcall(TEXTOUTCENTERED, c, r, txt, size, bold, opaque, underline, italic, align, color, bkcolor, xoffset, yoffset, antialias);
+}
+
+inline int svc_font::getTextWidth(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias)
+{
+ return _call(GETTEXTWIDTH, (int)0, c, text, size, bold, underline, italic, antialias);
+}
+
+inline int svc_font::getTextHeight(ifc_canvas *c, const wchar_t *text, int size, int bold, int underline, int italic, int antialias) {
+ return _call(GETTEXTHEIGHT, (int)0, c, text, size, bold, underline, italic, antialias);
+}
+
+inline int svc_font::getTextHeight(ifc_canvas *c, int size, int bold, int underline, int italic, int antialias) {
+ return _call(GETTEXTHEIGHT, (int)0, c, size, bold, underline, italic, antialias);
+}
+
+inline void svc_font::getTextExtent(ifc_canvas *c, const wchar_t *text, int *w, int *h, int size, int bold, int underline, int italic, int antialias) {
+ _voidcall(GETTEXTEXTENT, c, text, w, h, size, bold, underline, italic, antialias);
+}
+
+inline void svc_font::setFontId(const wchar_t *id) {
+ _voidcall(SETFONTID, id);
+}
+
+inline const wchar_t *svc_font::getFontId()
+{
+ return _call(GETFONTID, (const wchar_t *)0);
+}
+
+inline const wchar_t *svc_font::getFaceName()
+{
+ return _call(GETFACENAME_, (const wchar_t *)0);
+}
+
+inline int svc_font::isBitmap() {
+ return _call(ISBITMAP, (int)0);
+}
+
+inline int svc_font::getScriptId() {
+ return _call(GETSCRIPTID, (int)0);
+}
+
+inline void svc_font::setScriptId(int id) {
+ _voidcall(SETSCRIPTID, id);
+}
+
+inline void svc_font::setFontFace(const wchar_t *face)
+{
+ _voidcall(SETFONTFACE, face);
+}
+
+inline int svc_font::addFontResource(HANDLE f, const wchar_t *name) {
+ return _call(ADDFONTRESOURCE, (int)0, f, name);
+}
+
+inline int svc_font::addFontResource2(void *mem, int datalen, const wchar_t *name) {
+ return _call(ADDFONTRESOURCE2, (int)0, mem, datalen, name);
+}
+
+inline const wchar_t *svc_font::getFontSvcName() {
+ return _call(GETFONTSVCNAME, (const wchar_t *)0);
+}
+
+
+
+
+
+
+#endif // _SVC_FONT_H
diff --git a/Src/Wasabi/api/service/svcs/svc_fontmaker.cpp b/Src/Wasabi/api/service/svcs/svc_fontmaker.cpp
new file mode 100644
index 00000000..5003d8fe
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_fontmaker.cpp
@@ -0,0 +1,9 @@
+#include "svc_fontmaker.h"
+
+#define CBCLASS svc_fontMakerI
+START_DISPATCH
+ CB(GETFONTMAKERNAME, getFontMakerName);
+ CB(NEWTRUETYPEFONT, newTrueTypeFont);
+ CB(DELETETRUETYPEFONT, deleteTrueTypeFont);
+END_DISPATCH
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_fontmaker.h b/Src/Wasabi/api/service/svcs/svc_fontmaker.h
new file mode 100644
index 00000000..5ea25875
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_fontmaker.h
@@ -0,0 +1,73 @@
+#ifndef _SVC_FONTMAKER_H
+#define _SVC_FONTMAKER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/string.h>
+#include <api/service/svc_enum.h>
+#include <api/service/services.h>
+#include <api/service/servicei.h>
+
+class svc_font;
+
+//
+// This class doesn't do anything fantastic. It's just the way
+// you make your OS-Specific font class available to the system.
+
+class NOVTABLE svc_fontMaker : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::FONTRENDER; }
+
+ // You implement these:
+ const char *getFontMakerName();
+ svc_font *newTrueTypeFont();
+ int deleteTrueTypeFont(svc_font *font);
+
+protected:
+ enum {
+ GETFONTMAKERNAME,
+ NEWTRUETYPEFONT,
+ DELETETRUETYPEFONT,
+ };
+};
+
+
+inline const char *svc_fontMaker::getFontMakerName() {
+ return _call(GETFONTMAKERNAME, (const char *)0);
+}
+
+inline svc_font *svc_fontMaker::newTrueTypeFont() {
+ return _call(NEWTRUETYPEFONT, (svc_font *)0);
+}
+
+inline int svc_fontMaker::deleteTrueTypeFont(svc_font *font) {
+ return _call(DELETETRUETYPEFONT, (int)0, font);
+}
+
+// implementor derives from this one
+class NOVTABLE svc_fontMakerI : public svc_fontMaker {
+public:
+ virtual const char *getFontMakerName() = 0;
+ virtual svc_font *newTrueTypeFont() = 0;
+ virtual int deleteTrueTypeFont(svc_font *font) = 0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+class FontMakerEnum : public SvcEnumT<svc_fontMaker> {
+public:
+ FontMakerEnum(const char *_maker_name = NULL) : maker_name(_maker_name) {}
+protected:
+ virtual int testService(svc_fontMaker *svc) {
+ if (!maker_name.len()) return 1; // blank name returns all services.
+ return (STRCASEEQL(svc->getFontMakerName(),maker_name));
+ }
+private:
+ String maker_name;
+};
+
+template <class T>
+class FontMakerCreator : public waServiceFactoryTSingle<svc_fontMaker, T> {};
+
+
+#endif // _SVC_FONTMAKER_H
diff --git a/Src/Wasabi/api/service/svcs/svc_fontrender.cpp b/Src/Wasabi/api/service/svcs/svc_fontrender.cpp
new file mode 100644
index 00000000..67577fd2
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_fontrender.cpp
@@ -0,0 +1,16 @@
+#include "svc_fontrender.h"
+
+#define CBCLASS svc_fontRenderI
+START_DISPATCH
+ CB(ISNAMED, isNamed);
+ VCB(INSTALLTRUETYPEFONT, installTrueTypeFont);
+ VCB(INSTALLBITMAPFONT, installBitmapFont);
+ VCB(UNINSTALLALL, uninstallAll);
+ VCB(UNINSTALLBYSCRIPTID, uninstallByScriptId);
+ CB(REQUESTSKINFONT, requestSkinFont);
+ VCB(DISPATCHTEXTOUT, dispatchTextOut);
+ CB(DISPATCHGETINFO, dispatchGetInfo);
+ CB(USETRUETYPEOVERRIDE, useTrueTypeOverride);
+ CB(GETTRUETYPEOVERRIDE, getTrueTypeOverride);
+END_DISPATCH
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_fontrender.h b/Src/Wasabi/api/service/svcs/svc_fontrender.h
new file mode 100644
index 00000000..a377e76c
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_fontrender.h
@@ -0,0 +1,126 @@
+#ifndef _svc_fONTRENDER_H
+#define _svc_fONTRENDER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/string.h>
+#include <api/service/svc_enum.h>
+#include <api/service/services.h>
+#include <api/service/servicei.h>
+
+class svc_font;
+class ifc_canvas;
+
+class NOVTABLE svc_fontRender : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::FONTRENDER; }
+
+ // test the type.
+ int isNamed(const char *renderer_name);
+
+ // static methods from Font::
+ void installTrueTypeFont(const char *filename, const char *path, const char *id, int scriptid); // call this to install a new font
+ void installBitmapFont(const char *filename, const char *path, const char *id, int charwidth, int charheight, int hspacing, int vspacing, int scriptid);
+ void uninstallAll();
+ void uninstallByScriptId(int scriptid);
+ svc_font *requestSkinFont(const char *id); // call this to get a Font pointer to a font id
+ void dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const char *txt);
+ int dispatchGetInfo(ifc_canvas *c, const char *font, int infoid, const char *txt, int *w, int *h);
+ int useTrueTypeOverride();
+ const char *getTrueTypeOverride();
+
+
+protected:
+ enum {
+ ISNAMED,
+ INSTALLTRUETYPEFONT,
+ INSTALLBITMAPFONT,
+ UNINSTALLALL,
+ UNINSTALLBYSCRIPTID,
+ REQUESTSKINFONT,
+ DISPATCHTEXTOUT,
+ DISPATCHGETINFO,
+ USETRUETYPEOVERRIDE,
+ GETTRUETYPEOVERRIDE,
+ };
+};
+
+
+inline int svc_fontRender::isNamed(const char *renderer_name) {
+ return _call(ISNAMED, (int)0, renderer_name);
+}
+
+inline void svc_fontRender::installTrueTypeFont(const char *filename, const char *path, const char *id, int scriptid) {
+ _voidcall(INSTALLTRUETYPEFONT, filename, path, id, scriptid);
+}
+
+inline void svc_fontRender::installBitmapFont(const char *filename, const char *path, const char *id, int charwidth, int charheight, int hspacing, int vspacing, int scriptid) {
+ _voidcall(INSTALLBITMAPFONT, filename, path, id, charwidth, charheight, hspacing, vspacing, scriptid);
+}
+
+inline void svc_fontRender::uninstallAll() {
+ _voidcall(UNINSTALLALL);
+}
+
+inline void svc_fontRender::uninstallByScriptId(int scriptid) {
+ _voidcall(UNINSTALLBYSCRIPTID, scriptid);
+}
+
+inline svc_font *svc_fontRender::requestSkinFont(const char *id) {
+ return _call(REQUESTSKINFONT, (svc_font *)0, id);
+}
+
+inline void svc_fontRender::dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const char *txt) {
+ _voidcall(DISPATCHTEXTOUT, c, style, x, y, w, h, txt);
+}
+
+inline int svc_fontRender::dispatchGetInfo(ifc_canvas *c, const char *font, int infoid, const char *txt, int *w, int *h) {
+ return _call(DISPATCHGETINFO, (int)0, c, font, infoid, txt, w, h );
+}
+
+inline int svc_fontRender::useTrueTypeOverride() {
+ return _call(USETRUETYPEOVERRIDE, (int)0);
+}
+
+inline const char *svc_fontRender::getTrueTypeOverride() {
+ return _call(GETTRUETYPEOVERRIDE, (const char *)0);
+}
+
+// implementor derives from this one
+class NOVTABLE svc_fontRenderI : public svc_fontRender {
+public:
+
+ // test the type
+ virtual int isNamed(const char *renderer_name) = 0;
+
+ // static methods from Font::
+ virtual void installTrueTypeFont(const char *filename, const char *path, const char *id, int scriptid) = 0;
+ virtual void installBitmapFont(const char *filename, const char *path, const char *id, int charwidth, int charheight, int hspacing, int vspacing, int scriptid) = 0;
+ virtual void uninstallAll() = 0;
+ virtual void uninstallByScriptId(int scriptid) = 0;
+ virtual svc_font *requestSkinFont(const char *id) = 0; // call this to get a Font pointer to a font id
+ virtual void dispatchTextOut(ifc_canvas *c, int style, int x, int y, int w, int h, const char *txt) = 0;
+ virtual int dispatchGetInfo(ifc_canvas *c, const char *font, int infoid, const char *txt, int *w, int *h) = 0;
+ virtual int useTrueTypeOverride() = 0;
+ virtual const char *getTrueTypeOverride() = 0;
+
+
+protected:
+ RECVS_DISPATCH;
+};
+
+class FontRenderEnum : public SvcEnumT<svc_fontRender> {
+public:
+ FontRenderEnum(const char *_renderer_name = NULL) : renderer_name(_renderer_name) {}
+protected:
+ virtual int testService(svc_fontRender *svc) {
+ return (svc->isNamed(renderer_name));
+ }
+private:
+ String renderer_name;
+};
+
+template <class T>
+class FontRenderCreator : public waServiceFactoryTSingle<svc_fontRender, T> {};
+
+
+#endif // _svc_fONTRENDER_H
diff --git a/Src/Wasabi/api/service/svcs/svc_imggen.cpp b/Src/Wasabi/api/service/svcs/svc_imggen.cpp
new file mode 100644
index 00000000..44f25d24
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_imggen.cpp
@@ -0,0 +1,11 @@
+#include <precomp.h>
+
+#include "svc_imggen.h"
+
+#define CBCLASS svc_imageGeneratorI
+START_DISPATCH;
+ CB(TESTDESC, testDesc);
+ CB(GENIMAGE, genImage);
+ CB(OUTPUTCACHEABLE, outputCacheable);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_imggen.h b/Src/Wasabi/api/service/svcs/svc_imggen.h
new file mode 100644
index 00000000..a36377c8
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_imggen.h
@@ -0,0 +1,68 @@
+#ifndef _SVC_IMGGEN_H
+#define _SVC_IMGGEN_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+
+class NOVTABLE svc_imageGenerator : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::IMAGEGENERATOR; }
+ int testDesc(const wchar_t *desc);
+ ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params = NULL);
+ int outputCacheable();
+
+ enum {
+ TESTDESC = 10,
+ GENIMAGE = 30,
+ OUTPUTCACHEABLE = 40,
+ };
+};
+
+inline int svc_imageGenerator::testDesc(const wchar_t *desc)
+{
+ return _call(TESTDESC, 0, desc);
+}
+
+inline ARGB32 *svc_imageGenerator::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params)
+{
+ return _call(GENIMAGE, (ARGB32 *)0, desc, has_alpha, w, h, params);
+}
+
+inline int svc_imageGenerator::outputCacheable()
+{
+ return _call(OUTPUTCACHEABLE, 0);
+}
+
+// derive from this one
+class NOVTABLE svc_imageGeneratorI : public svc_imageGenerator
+{
+public:
+ virtual int testDesc(const wchar_t *desc) = 0;
+ virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params = NULL) = 0;
+ virtual int outputCacheable() { return 0; }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class ImgGeneratorEnum : public SvcEnumT<svc_imageGenerator>
+{
+public:
+ ImgGeneratorEnum(const wchar_t *_desc) : desc(_desc) { }
+
+protected:
+ virtual int testService(svc_imageGenerator *svc)
+ {
+ return svc->testDesc(desc);
+ }
+
+private:
+ StringW desc;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_imgload.cpp b/Src/Wasabi/api/service/svcs/svc_imgload.cpp
new file mode 100644
index 00000000..d8eb3cfc
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_imgload.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+
+#include "svc_imgload.h"
+
+#define CBCLASS svc_imageLoaderI
+START_DISPATCH;
+ CB(ISMINE, isMine);
+ CB(TESTDATA, testData);
+ CB(GETHEADERSIZE, getHeaderSize);
+ CB(GETDIMENSIONS, getDimensions);
+ CB(LOADIMAGE, loadImage);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_imgload.h b/Src/Wasabi/api/service/svcs/svc_imgload.h
new file mode 100644
index 00000000..22f3851c
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_imgload.h
@@ -0,0 +1,101 @@
+#ifndef _SVC_IMGLOAD_H
+#define _SVC_IMGLOAD_H
+
+#include <api/service/services.h>
+#include <bfc/platform/platform.h>
+#include <bfc/dispatch.h>
+
+
+class ifc_xmlreaderparams;
+
+class NOVTABLE svc_imageLoader : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::IMAGELOADER; }
+
+ // assuming there is an extension of this type, is it yours?
+ int isMine(const wchar_t *filename);
+
+ // returns the mime type for this type of image
+ const wchar_t *mimeType();
+
+ // returns how many bytes needed to get image info
+ int getHeaderSize();
+
+ // test image data, return TRUE if you can load it
+ int testData(const void *data, int datalen);
+
+ // just gets the width and height from the data, if possible
+ int getDimensions(const void *data, int datalen, int *w, int *h);
+
+ // converts the data into pixels + premultiply, use api->sysFree to deallocate
+ ARGB32 *loadImage(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params=NULL);\
+
+ // converts the data into pixels, use api->sysFree to deallocate
+ ARGB32 *loadImageData(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params=NULL);
+
+ enum {
+ ISMINE=50,
+ MIMETYPE=75,
+ GETHEADERSIZE=100,
+ TESTDATA=200,
+ GETDIMENSIONS=300,
+ LOADIMAGE=400,
+ LOADIMAGEDATA=500,
+ };
+};
+
+inline int svc_imageLoader::isMine(const wchar_t *filename) {
+ return _call(ISMINE, 0, filename);
+}
+
+inline const wchar_t *svc_imageLoader::mimeType() {
+ return _call(MIMETYPE, L"");
+}
+
+inline int svc_imageLoader::getHeaderSize() {
+ return _call(GETHEADERSIZE, -1);
+}
+
+inline int svc_imageLoader::testData(const void *data, int datalen) {
+ return _call(TESTDATA, 0, data, datalen);
+}
+
+inline int svc_imageLoader::getDimensions(const void *data, int datalen, int *w, int *h) {
+ return _call(GETDIMENSIONS, 0, data, datalen, w, h);
+}
+
+inline ARGB32 *svc_imageLoader::loadImage(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params) {
+ return _call(LOADIMAGE, (ARGB32*)0, data, datalen, w, h, params);
+}
+
+inline ARGB32 *svc_imageLoader::loadImageData(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params) {
+ return _call(LOADIMAGEDATA, (ARGB32*)0, data, datalen, w, h, params);
+}
+
+// derive from this one
+class NOVTABLE svc_imageLoaderI : public svc_imageLoader
+{
+public:
+ virtual int isMine(const wchar_t *filename)=0;
+ virtual const wchar_t *mimeType(void)=0;
+ // return the header size needed to get w/h and determine if it can be loaded
+ virtual int getHeaderSize() { return -1; }//don't know
+ // test image data, return TRUE if you can load it
+ virtual int testData(const void *data, int datalen)=0;
+ // just gets the width and height from the data, if possible
+ virtual int getDimensions(const void *data, int datalen, int *w, int *h) { return 0; }
+ // converts the data into pixels + premultiply, use api->sysFree to deallocate
+ virtual ARGB32 *loadImage(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params=NULL)=0;
+#if 0
+ // converts the data into pixels, use api->sysFree to deallocate
+ virtual ARGB32 *loadImageData(const void *data, int datalen, int *w, int *h, ifc_xmlreaderparams *params=NULL)=0;
+#endif
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_imgwrite.h b/Src/Wasabi/api/service/svcs/svc_imgwrite.h
new file mode 100644
index 00000000..e699bc57
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_imgwrite.h
@@ -0,0 +1,101 @@
+#ifndef _SVC_IMGWRITE_H
+#define _SVC_IMGWRITE_H
+
+#include <api/service/services.h>
+#include <bfc/platform/platform.h>
+#include <bfc/dispatch.h>
+
+class NOVTABLE svc_imageWriter : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::IMAGEWRITER; }
+
+ // returns a human readable string about the format. eg "JPEG"
+ const wchar_t * getImageTypeName();
+
+ // returns a semi-colon delimited list of file extensions for this format. eg "jpg;jpeg"
+ // MUST BE LOWER CASE
+ const wchar_t * getExtensions();
+
+ // valid items include "quality" for jpeg files with value "0" to "100"
+ // return value is 1 if the config item is supported, 0 if it is not.
+ int setConfig(const wchar_t * item, const wchar_t * value);
+
+ // valid items include "quality" for jpeg files with value "0" to "100", "lossless" returns "1" if it is "0" otherwise
+ // return value is 1 if the config item is supported, 0 if it is not.
+ int getConfig(const wchar_t * item, wchar_t * value, int valuelen);
+
+ // returns 1 if the bit depth is supported (eg 32 for ARGB32, 24 for RGB24)
+ // ARGB32 MUST be supported
+ int bitDepthSupported(int depth);
+
+ // returns the image in our format, free the returned buffer with api_memmgr::sysFree()
+ void * convert(const void *pixels, int bitDepth, int w, int h, int *length);
+
+ enum {
+ GETIMAGETYPENAME=10,
+ GETEXTENSIONS=20,
+ SETCONFIG=30,
+ GETCONFIG=40,
+ BITDEPTHSUPPORTED=50,
+ CONVERT=60,
+ };
+};
+
+inline const wchar_t *svc_imageWriter::getImageTypeName() {
+ return _call(GETIMAGETYPENAME, L"");
+}
+
+inline const wchar_t *svc_imageWriter::getExtensions() {
+ return _call(GETEXTENSIONS, L"");
+}
+
+inline int svc_imageWriter::setConfig(const wchar_t * item, const wchar_t * value) {
+ return _call(SETCONFIG, (int)0, item, value);
+}
+
+inline int svc_imageWriter::getConfig(const wchar_t * item, wchar_t * value, int valuelen) {
+ return _call(GETCONFIG, (int)0, item, value, valuelen);
+}
+
+inline int svc_imageWriter::bitDepthSupported(int depth) {
+ return _call(BITDEPTHSUPPORTED, (int)0, depth);
+}
+
+inline void * svc_imageWriter::convert(const void *pixels, int bitDepth, int w, int h, int *length) {
+ return _call(CONVERT, (void*)0, pixels, bitDepth, w, h, length);
+}
+
+// derive from this one
+class NOVTABLE svc_imageWriterI : public svc_imageWriter {
+public:
+ virtual const wchar_t * getExtensions()=0;
+ virtual const wchar_t * getImageTypeName()=0;
+ virtual int setConfig(const wchar_t * item, const wchar_t * value){return 0;}
+ virtual int getConfig(const wchar_t * item, wchar_t * value, int valuelen){return 0;}
+ virtual int bitDepthSupported(int depth)=0;
+ virtual void * convert(const void *pixels, int bitDepth, int w, int h, int *length)=0;
+protected:
+ RECVS_DISPATCH;
+};
+
+/* do we still use svc_enum?
+#include <bfc/svc_enum.h>
+
+class ImgWriterEnum : public SvcEnumT<svc_imageWriter> {
+public:
+ ImgWriterEnum(const char *_ext=NULL) : ext(_ext) { }
+
+protected:
+ virtual int testService(svc_imageWriter *svc) {
+ if (ext.isempty()) return 1;
+ else {
+ PathParser pp(svc->getExtensions(), ";");
+ for (int i = 0; i < pp.getNumStrings(); i++)
+ if (STRCASEEQL(ext, pp.enumString(i))) return 1;
+ return 0;
+ }
+ }
+ String ext;
+};
+*/
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_itemmgr.cpp b/Src/Wasabi/api/service/svcs/svc_itemmgr.cpp
new file mode 100644
index 00000000..3cadb94e
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_itemmgr.cpp
@@ -0,0 +1,20 @@
+#include <precomp.h>
+
+#include "svc_itemmgr.h"
+
+#define CBCLASS svc_itemMgrI
+START_DISPATCH;
+ CB(ISMINE, isMine);
+ CB(OPTIMIZEPLAYSTRING, optimizePlaystring);
+ CB(CREATEINITIALNAME, createInitialName);
+ CB(OPTIMIZEFILEDATA, optimizeFileData);
+ CB(ONDATABASEADD, onDatabaseAdd);
+ CB(ONDATABASEDEL, onDatabaseDel);
+ CB(ONTITLECHANGE, onTitleChange);
+ CB(ONTITLE2CHANGE, onTitle2Change);
+ VCB(ONNEXTFILE, onNextFile);
+ VCB(ONFILECOMPLETE, onFileComplete);
+ CB(WANTSCANDATA, wantScanData);
+ CB(GETSORTORDER, getSortOrder);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_itemmgr.h b/Src/Wasabi/api/service/svcs/svc_itemmgr.h
new file mode 100644
index 00000000..c2e3e416
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_itemmgr.h
@@ -0,0 +1,112 @@
+#ifndef _SVC_ITEMMGR_H
+#define _SVC_ITEMMGR_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class NOVTABLE svc_itemMgr : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::ITEMMANAGER; }
+
+ int isMine(const char *playstring) { return _call(ISMINE, 0, playstring); }
+
+ int optimizePlaystring(char *playstring) {
+ return _call(OPTIMIZEPLAYSTRING, 0, playstring);
+ }
+ int createInitialName(const char *playstring, char *buf, int buflen) {
+ return _call(CREATEINITIALNAME, 0, playstring, buf, buflen);
+ }
+ int optimizeFileData(const char *playstring, const char *fieldname, int datatype, char *data, int datalen) {
+ return _call(OPTIMIZEFILEDATA, -1, playstring, fieldname, datatype, data, datalen);
+ }
+
+ int onDatabaseAdd(const char *playstring) {
+ return _call(ONDATABASEADD, 0, playstring);
+ }
+ int onDatabaseDel(const char *playstring) {
+ return _call(ONDATABASEDEL, 0, playstring);
+ }
+
+ //return 1 if changed
+ int onTitleChange(const char *playstring, const char *newtitle) {
+ return _call(ONTITLECHANGE, 0, playstring, newtitle);
+ }
+ int onTitle2Change(const char *playstring, const char *newtitle) {
+ return _call(ONTITLE2CHANGE, 0, playstring, newtitle);
+ }
+
+ void onNextFile(const char *playstring) {
+ _voidcall(ONNEXTFILE, playstring);
+ }
+
+ void onFileComplete(const char *playstring) {
+ _voidcall(ONFILECOMPLETE, playstring);
+ }
+
+ int wantScanData(const char *playstring) {
+ return _call(WANTSCANDATA, 1, playstring);
+ }
+
+ int getSortOrder() {
+ return _call(GETSORTORDER, 0);
+ }
+
+ enum {
+ ISMINE=100,
+ OPTIMIZEPLAYSTRING=200,
+ OPTIMIZEFILEDATA=211, //210 retired
+ CREATEINITIALNAME=300,
+ ONDATABASEADD=400,
+ ONDATABASEDEL=401,
+ ONTITLECHANGE=600,
+ ONTITLE2CHANGE=601,
+ ONNEXTFILE=700,
+ ONFILECOMPLETE=800,
+ WANTSCANDATA=900,
+ GETSORTORDER=1000,
+ };
+};
+
+// derive from this one
+class NOVTABLE svc_itemMgrI : public svc_itemMgr {
+public:
+ virtual int isMine(const char *playstring)=0;
+ virtual int optimizePlaystring(char *playstring) { return 0; }
+ virtual int createInitialName(const char *playstring, char *buf, int buflen) { return 0; }
+ virtual int optimizeFileData(const char *playstring, const char *fieldname, int datatype, char *data, int datalen) { return -1; }
+ virtual int onDatabaseAdd(const char *playstring) { return 0; }
+ virtual int onDatabaseDel(const char *playstring) { return 0; }
+ virtual int onTitleChange(const char *playstring, const char *newtitle) { return 0; }
+ virtual int onTitle2Change(const char *playstring, const char *newtitle) { return 0; }
+ virtual void onNextFile(const char *playstring) { }
+ virtual void onFileComplete(const char *playstring) { }
+
+ virtual int wantScanData(const char *playstring) { return 1; }
+
+ virtual int getSortOrder() { return 0; }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <bfc/named.h>
+#include <api/service/svc_enum.h>
+
+class ItemMgrEnum : private Named, public SvcEnumT<svc_itemMgr> {
+public:
+ ItemMgrEnum(const char *ps) : Named(ps) { }
+
+ void setPlaystring(const char *ps) { Named::setName(ps); }
+
+protected:
+ virtual int testService(svc_itemMgr *svc) {
+ return svc->isMine(getName());
+ }
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class ItemMgrCreator : public waServiceFactoryTSingle<svc_itemMgr, T> { };
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_loadlib.h b/Src/Wasabi/api/service/svcs/svc_loadlib.h
new file mode 100644
index 00000000..25a72a06
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_loadlib.h
@@ -0,0 +1,16 @@
+#ifndef _LOADLIB_H
+#define _LOADLIB_H
+
+//UNDER CONSTRUCTION
+
+class NOVTABLE svc_loadLib
+{
+public:
+ int isMine(const char *filename);
+
+ int load(const char *filename);
+ void unload();
+ void *getProcAddress(const char *name);
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_mediaconverter.cpp b/Src/Wasabi/api/service/svcs/svc_mediaconverter.cpp
new file mode 100644
index 00000000..98ab19f0
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_mediaconverter.cpp
@@ -0,0 +1,23 @@
+#include <precomp.h>
+
+#include "svc_mediaconverter.h"
+
+#define CBCLASS svc_mediaConverterNI
+START_DISPATCH;
+ CB(CANCONVERTFROM,canConvertFrom)
+ CB(GETCONVERTERTO,getConverterTo)
+ CB(GETINFOS,getInfos)
+ CB(SETINFOS,setInfos)
+ CB(GETINFOSXMLGROUP,getInfosXmlGroup)
+ CB(PROCESSDATA,processData)
+ CB(GETPOSITION,getPosition)
+ CB(GETLATENCY,getLatency)
+ CB(GETCORECALLBACK,getCoreCallback)
+ CB(SORTPLACEMENT,sortPlacement)
+ CB(ISSELECTABLEOUTPUT,isSelectableOutput)
+ CB(CANSUPPORTCONTENTTYPE,canSupportContentType)
+ VCB(SETCORETOKEN,setCoreToken)
+ CB(ONCOREUSERMSG,onCoreUserMsg)
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_mediaconverter.h b/Src/Wasabi/api/service/svcs/svc_mediaconverter.h
new file mode 100644
index 00000000..c08c2932
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_mediaconverter.h
@@ -0,0 +1,161 @@
+#ifndef _SVC_MEDIACONVERTER_H
+#define _SVC_MEDIACONVERTER_H
+
+#include <bfc/dispatch.h>
+
+#include <api/core/chunklist.h>
+#include <api/core/mediainfo.h>
+#include <api/syscb/callbacks/corecbi.h>
+
+#include <api/service/services.h>
+
+// do NOT derive from these ones
+class NOVTABLE svc_mediaConverter : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::MEDIACONVERTER; }
+
+ // test if the converter can handle that stream, filename or chunktype:
+ // if your converter can accept streams depending on the data stream you should
+ // test the file thru the reader interface (like to test if the file header is ok)
+ // if your converter can accept files thru a test on the filename string, you should
+ // test the name string (like tone://... or *.wav)
+ // if your converter can accept depending on the chunktype, you should test the chunktype
+ // (like MP3, PCM, etc...)
+ // returns 1 if ok
+ int canConvertFrom(svc_fileReader *reader, const char *name, const char *chunktype) { return _call(CANCONVERTFROM,0,reader,name,chunktype); }
+
+ // returns the chunk type that the converter will convert to
+ // (PCM, MP3, etc...)
+ const char *getConverterTo() { return _call(GETCONVERTERTO,""); }
+
+ // override this one if your converter can decode depending on a "Content-Type:" HTTP header
+ int canSupportContentType(const char *contenttype) { return _call(CANSUPPORTCONTENTTYPE,0,contenttype); }
+
+ // fills up the infos class
+ int getInfos(MediaInfo *infos) { return _call(GETINFOS,0,infos); }
+
+ // writes back the infos on the file.
+ // note: the reader you get in the infos class has the filename opened in read/write mode
+ // return 1 if update succeeded, 0 if error
+ int setInfos(MediaInfo *infos) { return _call(SETINFOS,0,infos); }
+
+ // returns the id of the xml group the media info editor will use for displaying/editing infos
+ const char *getInfosXmlGroup() { return _call(GETINFOSXMLGROUP,(const char *)NULL); }
+
+ // process current file data
+ // returns 1 if ok, 0 when file/stream has ended
+ int processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch) { return _call(PROCESSDATA,0,infos,chunk_list,killswitch); }
+
+ // returns the current position in ms
+ // usually the position is automatically calculated with the amount of PCM data converters send back to the core
+ // so you don't have to override this function. however, if you want to force the position, return a value other than -1
+ int getPosition(void) { return _call(GETPOSITION,-1); }
+
+ // returns the latency of the converter in ms
+ int getLatency(void) { return _call(GETLATENCY,0); }
+
+ // sort function to be able to specify where you want your converter placed in the converter list
+ // (like if you want to be before or after the crossfader for example, override this function)
+ // return -1 to be placed before "otherconverter", 1 to be placed after "otherconverter", otherwise 0
+ int sortPlacement(const char *otherconverter) { return _call(SORTPLACEMENT,0,otherconverter); }
+
+ // return 1 if you want this converter to be selectable as output in prefs->audio
+ int isSelectableOutput(void) { return _call(ISSELECTABLEOUTPUT,0); }
+
+ // message received by sendConvertersMsg() in the core
+ int onCoreUserMsg(const char *msg, const char *value) { return _call(ONCOREUSERMSG,0,msg,value); }
+
+
+ // internally used by wasabi
+ CoreCallback *getCoreCallback(void) { return _call(GETCORECALLBACK,(CoreCallback *)0); }
+ void setCoreToken(CoreToken t) { _voidcall(SETCORETOKEN,t); }
+
+ enum {
+ CANCONVERTFROM=10,
+ GETCONVERTERTO=20,
+ GETINFOS=30,
+ PROCESSDATA=40,
+ GETPOSITION=50,
+ GETLATENCY=60,
+ GETCORECALLBACK=70,
+ SORTPLACEMENT=80,
+ CANSUPPORTCONTENTTYPE=90,
+ SETCORETOKEN=100,
+ SETINFOS=110,
+ GETINFOSXMLGROUP=120,
+ ISSELECTABLEOUTPUT=130,
+ ONCOREUSERMSG=140,
+ };
+};
+
+class NOVTABLE svc_mediaConverterNI : public svc_mediaConverter {
+public:
+ virtual int canConvertFrom(svc_fileReader *reader, const char *name, const char *chunktype)=0;
+ virtual const char *getConverterTo()=0;
+ virtual int canSupportContentType(const char *contenttype) { return 0; }
+
+ virtual int getInfos(MediaInfo *infos)=0;
+
+ virtual int setInfos(MediaInfo *infos)=0;
+
+ virtual const char *getInfosXmlGroup()=0;
+
+ virtual int processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)=0;
+
+ virtual int getPosition(void) { return -1; }
+
+ virtual int getLatency(void) { return 0; }
+
+ virtual int sortPlacement(const char *otherconverter) { return 0; }
+
+ virtual int isSelectableOutput(void) { return 0; }
+
+ virtual int onCoreUserMsg(const char *msg, const char *value) { return 0; }
+
+ virtual CoreCallback *getCoreCallback(void)=0;
+
+ virtual void setCoreToken(CoreToken t)=0;
+protected:
+ RECVS_DISPATCH;
+};
+
+// derive from this one
+class NOVTABLE svc_mediaConverterI : public svc_mediaConverterNI, public CoreCallbackI {
+public:
+ svc_mediaConverterI() : m_coretoken(0) { }
+
+ virtual int canConvertFrom(svc_fileReader *reader, const char *name, const char *chunktype)=0;
+ virtual const char *getConverterTo()=0;
+ virtual int canSupportContentType(const char *contenttype) { return 0; }
+
+ virtual int getInfos(MediaInfo *infos)=0;
+
+ virtual int setInfos(MediaInfo *infos) { return 0; }
+
+ virtual const char *getInfosXmlGroup() { return (const char *)NULL; }
+
+ virtual int processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)=0;
+
+ virtual int getPosition(void) { return -1; }
+
+ virtual int getLatency(void) { return 0; }
+
+ virtual int sortPlacement(const char *otherconverter) { return 0; }
+
+ virtual int isSelectableOutput(void) { return 0; }
+
+ virtual int onCoreUserMsg(const char *msg, const char *value) { return 0; }
+
+ virtual CoreCallback *getCoreCallback(void) { return this; }
+
+ virtual void setCoreToken(CoreToken t) { m_coretoken=t; }
+
+protected:
+ CoreToken m_coretoken;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class MediaConverterCreator : public waServiceFactoryT<svc_mediaConverter, T> { };
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_mediacore.cpp b/Src/Wasabi/api/service/svcs/svc_mediacore.cpp
new file mode 100644
index 00000000..154b7a00
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_mediacore.cpp
@@ -0,0 +1,45 @@
+#include <precomp.h>
+
+#include "svc_mediacore.h"
+
+#define CBCLASS svc_mediaCoreI
+START_DISPATCH;
+ VCB(SETCALLBACK,setCallback);
+ VCB(SETNEXTFILE,setNextFile);
+ VCB(START,start);
+ VCB(PAUSE,pause);
+ VCB(SETPOSITION,setPosition);
+ VCB(SETVOLUME,setVolume);
+ VCB(SETPAN,setPan);
+ VCB(ABORTCURRENTSONG,abortCurrentSong);
+ VCB(STOP,stop);
+ CB(GETPLAYING,getPlaying);
+ CB(GETPOSITION,getPosition);
+ CB(GETWRITEPOSITION,getWritePosition);
+ CB(GETTITLE,getTitle);
+ VCB(GETINFO,getInfo);
+ CB(GETLENGTH,getLength);
+ CB(GETVOLUME,getVolume);
+ CB(GETPAN,getPan);
+ VCB(SETEQSTATUS,setEQStatus);
+ CB(GETEQSTATUS,getEQStatus);
+ VCB(SETEQPREAMP,setEQPreamp);
+ CB(GETEQPREAMP,getEQPreamp);
+ VCB(SETEQBAND,setEQBand);
+ CB(GETEQBAND,getEQBand);
+ VCB(SETEQBANDS,setEQBands);
+ VCB(GETEQBANDS,getEQBands);
+ VCB(SETEQ,setEQ);
+ VCB(GETEQ,getEQ);
+ CB(GETMETADATA,getMetaData);
+ CB(GETVISDATA,getVisData);
+ VCB(MUTE,mute);
+ CB(ISMUTED,isMuted);
+ VCB(SETCORETOKEN,setCoreToken);
+ VCB(SETPRIORITY,setPriority);
+ CB(GETPRIORITY,getPriority);
+ VCB(REBUILDCONVERTERSCHAIN, rebuildConvertersChain)
+ CB(SENDCONVERTERSMSG, sendConvertersMsg)
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_mediacore.h b/Src/Wasabi/api/service/svcs/svc_mediacore.h
new file mode 100644
index 00000000..2ddbdceb
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_mediacore.h
@@ -0,0 +1,172 @@
+#ifndef _SVC_MEDIACORE_H
+#define _SVC_MEDIACORE_H
+
+#include <api/service/services.h>
+#include <bfc/dispatch.h>
+#include <api/syscb/callbacks/corecbi.h>
+
+class NOVTABLE svc_mediaCore : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::MEDIACORE; }
+
+ void setCallback(CoreCallback *callback) { _voidcall(SETCALLBACK,callback); }
+ void setCoreToken(CoreToken t) { _voidcall(SETCORETOKEN,t); }
+
+ void setNextFile(const char *file, const char *to=NULL, int uniqueid=0) { _voidcall(SETNEXTFILE,file,to,uniqueid); }
+
+ void start(void) { _voidcall(START); }
+ void pause(int pause) { _voidcall(PAUSE,pause); }
+ void setPosition(int ms) { _voidcall(SETPOSITION,ms); }
+
+ void setVolume(int volume) { _voidcall(SETVOLUME,volume); }
+ void setPan(int pan) { _voidcall(SETPAN,pan); }
+
+ void abortCurrentSong() { _voidcall(ABORTCURRENTSONG); }
+ void stop(int suppress_callback=FALSE) { _voidcall(STOP,suppress_callback); }
+
+ int getPlaying(void) { return _call(GETPLAYING,0); }
+ int getPosition(void) { return _call(GETPOSITION,0); }
+ int getWritePosition(void) { return _call(GETWRITEPOSITION,0); }
+
+ int getTitle(char *title, int maxlen) { return _call(GETTITLE,0,title,maxlen); }
+ void getInfo(char *info, int maxlen) { _voidcall(GETINFO,info,maxlen); }
+ int getLength(void) { return _call(GETLENGTH,0); }
+
+ int getVolume(void) { return _call(GETVOLUME,0); }
+ int getPan(void) { return _call(GETPAN,0); }
+
+ void mute(int mute) { _voidcall(MUTE,mute); }
+ int isMuted() { return _call(ISMUTED,0); }
+
+ void setEQStatus(int enable) { _voidcall(SETEQSTATUS,enable); }
+ int getEQStatus() { return _call(GETEQSTATUS,0); }
+ void setEQPreamp(char pre) { _voidcall(SETEQPREAMP,pre); }
+ char getEQPreamp() { return _call(GETEQPREAMP,0); }
+ void setEQBand(int band, char val) { _voidcall(SETEQBAND,band,val); }
+ char getEQBand(int band) { return _call(GETEQBAND,0,band); }
+ void setEQBands(char tab[10]) { _voidcall(SETEQBANDS,tab); }
+ void getEQBands(char *tab) { _voidcall(GETEQBANDS,tab); }
+
+ void setEQ(int enable, char pre, char tab[10]) { _voidcall(SETEQ,enable,pre,tab); }
+ void getEQ(int *enable, char *pre, char *tab) { _voidcall(GETEQ,enable,pre,tab); }
+
+ int getMetaData(const char *name, char *data, int data_len) { return _call(GETMETADATA,0,name,data,data_len); }
+
+ int getVisData(void *dataptr, int sizedataptr) { return _call(GETVISDATA,0,dataptr,sizedataptr); }
+
+ void setPriority(int priority) { _voidcall(SETPRIORITY,priority); }
+ int getPriority() { return _call(GETPRIORITY,0); }
+
+ void rebuildConvertersChain() { _voidcall(REBUILDCONVERTERSCHAIN); }
+
+ int sendConvertersMsg(const char *msg, const char *value) { return _call(SENDCONVERTERSMSG,0,msg,value); }
+
+ enum {
+ SETCALLBACK=10,
+ SETNEXTFILE=20,
+ START=30,
+ PAUSE=40,
+ SETPOSITION=50,
+ SETVOLUME=60,
+ SETPAN=70,
+ ABORTCURRENTSONG=80,
+ STOP=90,
+ GETPLAYING=100,
+ GETPOSITION=110,
+ GETWRITEPOSITION=120,
+ GETTITLE=130,
+ GETINFO=140,
+ GETLENGTH=150,
+ GETVOLUME=160,
+ GETPAN=170,
+ SETEQSTATUS=180,
+ GETEQSTATUS=190,
+ SETEQPREAMP=200,
+ GETEQPREAMP=210,
+ SETEQBAND=220,
+ GETEQBAND=230,
+ SETEQBANDS=240,
+ GETEQBANDS=250,
+ SETEQ=260,
+ GETEQ=270,
+ GETMETADATA=280,
+ GETVISDATA=290,
+ MUTE=300,
+ ISMUTED=310,
+ SETCORETOKEN=320,
+ SETPRIORITY=330,
+ GETPRIORITY=340,
+ REBUILDCONVERTERSCHAIN=350,
+ SENDCONVERTERSMSG=360,
+ };
+};
+
+// derive from this one
+class NOVTABLE svc_mediaCoreI : public svc_mediaCore {
+public:
+ svc_mediaCoreI() : m_coretoken(0) { }
+
+ virtual void setCallback(CoreCallback *callback)=0;
+ virtual void setCoreToken(CoreToken t) { m_coretoken=t; }
+
+ virtual void setNextFile(const char *file, const char *to=NULL, int uniqueid=0)=0;
+ /* call to specify next file from WCM_NEEDNEXTFILE, or before calling start() */
+
+ virtual void start(void)=0; /* start playback */
+ virtual void pause(int pause)=0; /* set/unset paused state (nonzero is paused, zero is unpaused) */
+ virtual void setPosition(int ms)=0; /* set position of current stream in ms */
+
+ virtual void setVolume(int volume)=0; /* volume is 0 to 255 */
+ virtual void setPan(int pan)=0; /* pan is -127 to 127 */
+ virtual void abortCurrentSong()=0; /* abort decoding of current song and start playing the next one */
+ virtual void stop(int suppress_callback=FALSE)=0;
+
+ virtual int getPlaying(void)=0; /* 0 is not playing, 1 is playing, -1 is paused */
+ virtual int getPosition(void)=0; /* get position of current stream in ms */
+ virtual int getWritePosition(void)=0; /* get written position of current stream in ms */
+
+ virtual int getTitle(char *title, int maxlen)=0; // returns uniqueid
+ virtual void getInfo(char *info, int maxlen)=0;
+ virtual int getLength(void)=0; /* get length of track in ms. -1 indicates infinite/unknown */
+
+ virtual int getVolume(void)=0; /* get volume (0-255) */
+ virtual int getPan(void)=0; /* get panning (-127 to 127) */
+
+ virtual void mute(int mute)=0;
+ virtual int isMuted()=0;
+
+ virtual void setEQStatus(int enable)=0; /* 0 if off, 1 if on */
+ virtual int getEQStatus()=0; /* 0 if off, 1 if on */
+ virtual void setEQPreamp(char pre)=0; /* -127 to 127 (-20db to +20db) */
+ virtual char getEQPreamp()=0; /* -127 to 127 (-20db to +20db) */
+ virtual void setEQBand(int band, char val)=0; /* band=0-9 */
+ virtual char getEQBand(int band)=0; /* band=0-9 */
+ virtual void setEQBands(char tab[10])=0; /* eq values are -127 to 127 (-20db to +20db) */
+ virtual void getEQBands(char *tab)=0; /* eq values are -127 to 127 (-20db to +20db) */
+
+ virtual void setEQ(int enable, char pre, char tab[10])=0;
+ virtual void getEQ(int *enable, char *pre, char *tab)=0;
+
+ virtual int getMetaData(const char *name, char *data, int data_len)=0; // returns size of data
+
+ virtual int getVisData(void *dataptr, int sizedataptr)=0; // returns size of data it wanted to copy, if any.
+
+ virtual void setPriority(int priority)=0;
+ virtual int getPriority()=0;
+
+ virtual void rebuildConvertersChain()=0;
+
+ virtual int sendConvertersMsg(const char *msg, const char *value)=0;
+
+protected:
+ RECVS_DISPATCH;
+
+ CoreToken m_coretoken;
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class MediaCoreCreator : public waServiceFactoryT<svc_mediaCore, T> { };
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_metadata.cpp b/Src/Wasabi/api/service/svcs/svc_metadata.cpp
new file mode 100644
index 00000000..dfacc342
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_metadata.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+
+#include "svc_metadata.h"
+
+#define CBCLASS svc_metaDataI
+START_DISPATCH;
+ CB(ENUMMETADATA, enumMetaData);
+ CB(HASMETADATA, hasMetaData);
+ CB(ALLOWOPERATION, allowOperation);
+ CB(GETGUID, getGUID);
+ CB(GETMETANAME, getMetaTableName);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/service/svcs/svc_metadata.h b/Src/Wasabi/api/service/svcs/svc_metadata.h
new file mode 100644
index 00000000..f237849d
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_metadata.h
@@ -0,0 +1,97 @@
+#ifndef _SVC_METADATA_H
+#define _SVC_METADATA_H
+
+// see helper class in common/metadatasvc.h to implement this
+
+#include <api/service/services.h>
+#include <bfc/dispatch.h>
+#include <bfc/string/string.h>
+#include <api/db/metatags.h>
+
+class NOVTABLE svc_metaData : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::METADATA; }
+
+ int enumMetaData(int n, char *mdName, int mdNameMaxLength, int *mdType, BOOL *mdIndexed, BOOL *mdMaintainUniques);
+ int hasMetaData(const char *name, int type);
+ int allowOperation(GUID whom, const char *playstring, int op, char *field, void *data, int data_len);
+ GUID getGUID();
+ const char *getMetaTableName();
+
+ enum {
+ HASMETADATA=10,
+ ENUMMETADATA=20,
+ ALLOWOPERATION=30,
+ GETGUID=40,
+ GETMETANAME=50,
+ };
+
+};
+
+inline int svc_metaData::hasMetaData(const char *name, int type) {
+ return _call(HASMETADATA, 0, name, type);
+}
+
+inline int svc_metaData::enumMetaData(int n, char *mdName, int mdNameMaxLength, int *mdType, BOOL *mdIndexed, BOOL *mdMaintainUniques) {
+ return _call(ENUMMETADATA, 0, n, mdName, mdNameMaxLength, mdType, mdIndexed, mdMaintainUniques);
+}
+
+inline int svc_metaData::allowOperation(GUID whom, const char *playstring, int op, char *field, void *data, int data_len) {
+ return _call(ALLOWOPERATION, 0, whom, playstring, op, field, data, data_len);
+}
+
+inline GUID svc_metaData::getGUID() {
+ return _call(GETGUID, INVALID_GUID);
+}
+
+inline const char *svc_metaData::getMetaTableName() {
+ return _call(GETMETANAME, (const char *)NULL);
+}
+
+// see helper class in common/metadatasvc.h to implement this
+class NOVTABLE svc_metaDataI : public svc_metaData {
+public:
+ virtual int enumMetaData(int n, char *mdName, int mdNameMaxLength, int *mdType, BOOL *mdIndexed, BOOL *mdMaintainUniques)=0;
+ virtual int hasMetaData(const char *name, int type)=0;
+ virtual int allowOperation(GUID whom, const char *playstring, int op, char *field, void *data, int data_len)=0;
+ virtual GUID getGUID()=0;
+ virtual const char *getMetaTableName()=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+
+// if you want to use class MetaDataSvc (instead of deriving from
+// svc_metaDataI yourself) use class MetaDataSvcFactory in common/metadatasvc.h
+template <class T>
+class MetaDataSvcCreator : public waServiceFactoryTSingle<svc_metaData, T> {};
+
+#include <api/service/svc_enum.h>
+
+class MetaDataSvcEnum : public SvcEnumT<svc_metaData> {
+public:
+ MetaDataSvcEnum(const char *metadata=NULL, int mdtype=MDT_NONE) : md(metadata), type(mdtype) {}
+protected:
+ virtual int testService(svc_metaData *svc) {
+ if (md.isempty() || type == MDT_NONE) return TRUE;
+ return svc->hasMetaData(md, type);
+ }
+private:
+ String md;
+ int type;
+};
+
+class MetaDataSvcEnumGuid : public SvcEnumT<svc_metaData> {
+public:
+ MetaDataSvcEnumGuid(GUID g) : guid(g) {}
+protected:
+ virtual int testService(svc_metaData *svc) {
+ return (svc->getGUID() == guid);
+ }
+private:
+ GUID guid;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_minibrowser.cpp b/Src/Wasabi/api/service/svcs/svc_minibrowser.cpp
new file mode 100644
index 00000000..65c3c0dd
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_minibrowser.cpp
@@ -0,0 +1,12 @@
+#include <precomp.h>
+#include "svc_minibrowser.h"
+
+#define CBCLASS svc_miniBrowserI
+START_DISPATCH;
+ CB(TESTGUID, testGuid);
+ CB(CREATEMINIBROWSER, createMiniBrowser);
+ VCB(DESTROYMINIBROWSER, destroyMiniBrowser);
+END_DISPATCH;
+#undef CBCLASS
+
+
diff --git a/Src/Wasabi/api/service/svcs/svc_minibrowser.h b/Src/Wasabi/api/service/svcs/svc_minibrowser.h
new file mode 100644
index 00000000..9772131b
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_minibrowser.h
@@ -0,0 +1,69 @@
+#ifndef _SVC_MINIBROWSER_H
+#define _SVC_MINIBROWSER_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class MiniBrowser;
+
+#include <bfc/nsguid.h>
+
+// {2E41D2E8-19A5-4029-9339-8FDF7481000A}
+static const GUID GUID_MINIBROWSER_ANY =
+{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
+
+// {C0A3D1AC-2430-45a7-B51B-AB04B74DD9EA}
+static const GUID GUID_MINIBROWSER_IEACTIVEX =
+{ 0xc0a3d1ac, 0x2430, 0x45a7, { 0xb5, 0x1b, 0xab, 0x4, 0xb7, 0x4d, 0xd9, 0xea } };
+
+class NOVTABLE svc_miniBrowser : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::MINIBROWSER; }
+
+ int testGuid(GUID g);
+ MiniBrowser *createMiniBrowser();
+ void destroyMiniBrowser(MiniBrowser *b);
+
+ enum {
+ TESTGUID =10,
+ CREATEMINIBROWSER =20,
+ DESTROYMINIBROWSER =30,
+ };
+};
+
+inline int svc_miniBrowser::testGuid(GUID g) {
+ return _call(TESTGUID, 0, g);
+}
+
+inline MiniBrowser *svc_miniBrowser::createMiniBrowser() {
+ return _call(CREATEMINIBROWSER, (MiniBrowser *)0);
+}
+
+inline void svc_miniBrowser::destroyMiniBrowser(MiniBrowser *b) {
+ _voidcall(DESTROYMINIBROWSER, b);
+}
+
+class NOVTABLE svc_miniBrowserI : public svc_miniBrowser {
+public:
+ virtual int testGuid(GUID g)=0;
+ virtual MiniBrowser *createMiniBrowser()=0;
+ virtual void destroyMiniBrowser(MiniBrowser *b)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+
+class MiniBrowserSvcEnum : public SvcEnumT<svc_miniBrowser> {
+public:
+ MiniBrowserSvcEnum(GUID g) : guid(g) {}
+protected:
+ virtual int testService(svc_miniBrowser *svc) {
+ return (svc->testGuid(guid));
+ }
+private:
+ GUID guid;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_objectdir.cpp b/Src/Wasabi/api/service/svcs/svc_objectdir.cpp
new file mode 100644
index 00000000..e79e5a48
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_objectdir.cpp
@@ -0,0 +1,32 @@
+#include <precomp.h>
+
+#include "svc_objectdir.h"
+#include <api/api.h>
+
+#define CBCLASS svc_objectDirI
+START_DISPATCH;
+ CB(GETDEPENDENCYPTR, getDependencyPtr);
+ CB(GETDIRTYPE, getDirType);
+ CB(GETNUMOBJECTS, getNumObjects);
+ CB(ENUMOBJECT, enumObject);
+ CB(GETOBJECT, getObject);
+ CB(GETOBJECTLABEL, getObjectLabel);
+ CB(SETOBJECTLABEL, setObjectLabel);
+ CB(INSERTOBJECT, insertObject);
+ CB(REMOVEOBJECT, removeObject);
+ VCB(CLEARALL, clearAll);
+ CB(ONACTION, onAction);
+ VCB(ONPRERENDER, onPrerender);
+ VCB(ONPOSTRENDER, onPostrender);
+ CB(GETOBJECTPATH, getObjectPath);
+ CB(GETOBJECTDISPLAYGROUP, getObjectDisplayGroup);
+ CB(GETOBJECTICON, getObjectIcon);
+ CB(GETOBJECTSELECTABLE, getObjectSelectable);
+ CB(GETOBJECTSORTORDER, getObjectSortOrder);
+ CB(TAGOBJECT, tagObject);
+ CB(UNTAGOBJECT, untagObject);
+ CB(ENUMOBJECTBYTAG, enumObjectByTag);
+ CB(ISTAGGED, isTagged);
+ CB(CONTEXTMENU, contextMenu);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_objectdir.h b/Src/Wasabi/api/service/svcs/svc_objectdir.h
new file mode 100644
index 00000000..fdf5cd2f
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_objectdir.h
@@ -0,0 +1,294 @@
+#ifndef _SVC_OBJECTDIR_H
+#define _SVC_OBJECTDIR_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/StringW.h>
+#include <api/service/services.h>
+#include <api/syscb/callbacks/runlevelcb.h>
+
+// there is class ObjectDir in bfc/wnds, you should derive from it
+// also class ContextCmdObjDir
+
+typedef size_t ObjectHandle;
+#define INVALID_OBJECT_HANDLE ((ObjectHandle)0)
+
+#define DD_OBJECTDIR L"service:svc_objectDir"
+
+class ifc_window;
+class ifc_dependent;
+class BaseCanvas;
+
+class svc_objectDir : public Dispatchable
+{
+public:
+ static int getServiceType() { return WaSvc::OBJECTDIR; }
+ static const wchar_t *dragitem_getDatatype() { return DD_OBJECTDIR; }
+ static const GUID *depend_getClassGuid() {
+ // {2364D110-0F12-40d4-BBAE-D2DA174751B5}
+ static const GUID ret =
+ { 0x2364d110, 0xf12, 0x40d4, { 0xbb, 0xae, 0xd2, 0xda, 0x17, 0x47, 0x51, 0xb5 } };
+ return &ret;
+ }
+
+ api_dependent *getDependencyPtr();
+
+ const wchar_t *getDirType();
+
+ int getNumObjects();
+ ObjectHandle enumObject(int n);
+
+ void *getObject(ObjectHandle handle);
+
+ const wchar_t *getObjectLabel(ObjectHandle handle);
+ int setObjectLabel(ObjectHandle handle, const wchar_t *newlabel);
+
+ ObjectHandle insertObject(const wchar_t *parameter=NULL, const wchar_t *label=NULL, const wchar_t *path=NULL);
+ int removeObject(ObjectHandle handle);
+
+ void clearAll();
+
+ const wchar_t *getObjectPath(ObjectHandle handle);
+ const wchar_t *getObjectDisplayGroup(ObjectHandle handle);
+ const wchar_t *getObjectIcon(ObjectHandle handle);
+ int getObjectSelectable(ObjectHandle handle);
+ int getObjectSortOrder(ObjectHandle handle); // -32767..32767
+
+ // tagging
+ int tagObject(const wchar_t *tag, ObjectHandle handle, int exclusive=FALSE);
+ int untagObject(const wchar_t *tag, ObjectHandle handle);
+ ObjectHandle enumObjectByTag(const wchar_t *tag, int n);
+ int isTagged(const wchar_t *tag, ObjectHandle handle);
+
+ int onAction(int action, ifc_window *from, const wchar_t *target, ObjectHandle handle);
+ enum {
+ ODACTION_SELECTED=100,
+ ODACTION_DESELECTED=200,
+ ODACTION_CONTEXTMENU=300,
+ };
+
+ int contextMenu(ifc_window *from, int x, int y, ObjectHandle handle);
+
+ void onPrerender(ObjectHandle handle, const RECT *r, BaseCanvas *c, int style);
+ void onPostrender(ObjectHandle handle, const RECT *r, BaseCanvas *c, int style);
+ // render styles
+ enum {
+ RENDERSTYLE_TREEWND=10,
+ };
+
+ // dependency events, param is handle of object in question
+ enum {
+ Event_OBJECT_ADDED=100,
+ Event_OBJECT_REMOVED=110,
+ Event_OBJECT_LABELCHANGE=200,
+ Event_OBJECT_ICONCHANGE=300,
+ Event_OBJECT_PATHCHANGE=400,
+ Event_OBJECT_SELECTABLECHANGE=500,
+ Event_OBJECT_SORTORDERCHANGE=600,
+ Event_OBJECT_TAGCHANGE=700,
+ };
+
+ // dispatchable codes
+ enum {
+ GETDEPENDENCYPTR=100,
+ GETNUMOBJECTS=200,
+ ENUMOBJECT=300,
+ GETOBJECT=400,
+ GETOBJECTLABEL=500,
+ SETOBJECTLABEL=510,
+ INSERTOBJECT=600,
+ REMOVEOBJECT=610,
+ CLEARALL=700,
+ GETDIRTYPE=800,
+ ONACTION=900,
+ ONPRERENDER=1000,
+ ONPOSTRENDER=1010,
+ GETOBJECTPATH=1100,
+ GETOBJECTDISPLAYGROUP=1200,
+ GETOBJECTICON=1300,
+ GETOBJECTSELECTABLE=1400,
+ GETOBJECTSORTORDER=1500,
+ TAGOBJECT=1600,
+ UNTAGOBJECT=1700,
+ ENUMOBJECTBYTAG=1800,
+ ISTAGGED=1900,
+ CONTEXTMENU=3000,
+ };
+};
+
+inline
+api_dependent *svc_objectDir::getDependencyPtr() {
+ return _call(GETDEPENDENCYPTR, (api_dependent*)NULL);
+}
+
+inline
+const wchar_t *svc_objectDir::getDirType() {
+ return _call(GETDIRTYPE, (const wchar_t *)NULL);
+}
+
+inline
+int svc_objectDir::getNumObjects() {
+ return _call(GETNUMOBJECTS, 0);
+}
+
+inline
+ObjectHandle svc_objectDir::enumObject(int n) {
+ return _call(ENUMOBJECT, INVALID_OBJECT_HANDLE, n);
+}
+
+inline
+void *svc_objectDir::getObject(ObjectHandle handle) {
+ return _call(GETOBJECT, (void*)NULL, handle);
+}
+
+inline
+const wchar_t *svc_objectDir::getObjectLabel(ObjectHandle handle) {
+ return _call(GETOBJECTLABEL, (const wchar_t *)NULL, handle);
+}
+
+inline
+int svc_objectDir::setObjectLabel(ObjectHandle handle, const wchar_t *newlabel) {
+ return _call(SETOBJECTLABEL, 0, handle, newlabel);
+}
+
+inline
+ObjectHandle svc_objectDir::insertObject(const wchar_t *parameter, const wchar_t *label, const wchar_t *path) {
+ return _call(INSERTOBJECT, INVALID_OBJECT_HANDLE, parameter, label, path);
+}
+
+inline
+int svc_objectDir::removeObject(ObjectHandle handle) {
+ return _call(REMOVEOBJECT, 0, handle);
+}
+
+inline
+void svc_objectDir::clearAll() {
+ _voidcall(CLEARALL);
+}
+
+inline
+const wchar_t *svc_objectDir::getObjectPath(ObjectHandle handle) {
+ return _call(GETOBJECTPATH, (const wchar_t *)NULL, handle);
+}
+
+inline
+const wchar_t *svc_objectDir::getObjectDisplayGroup(ObjectHandle handle) {
+ return _call(GETOBJECTDISPLAYGROUP, L"", handle);
+}
+
+inline
+const wchar_t *svc_objectDir::getObjectIcon(ObjectHandle handle) {
+ return _call(GETOBJECTICON, (const wchar_t *)NULL, handle);
+}
+
+inline
+int svc_objectDir::getObjectSelectable(ObjectHandle handle) {
+ return _call(GETOBJECTSELECTABLE, TRUE, handle);
+}
+
+inline
+int svc_objectDir::getObjectSortOrder(ObjectHandle handle) {
+ return _call(GETOBJECTSORTORDER, 0, handle);
+}
+
+inline
+int svc_objectDir::tagObject(const wchar_t *tag, ObjectHandle handle, int exclusive) {
+ return _call(TAGOBJECT, 0, tag, handle, exclusive);
+}
+inline
+int svc_objectDir::untagObject(const wchar_t *tag, ObjectHandle handle) {
+ return _call(UNTAGOBJECT, 0, tag, handle);
+}
+inline
+ObjectHandle svc_objectDir::enumObjectByTag(const wchar_t *tag, int n) {
+ return _call(ENUMOBJECTBYTAG, INVALID_OBJECT_HANDLE, tag, n);
+}
+inline
+int svc_objectDir::isTagged(const wchar_t *tag, ObjectHandle handle) {
+ return _call(ISTAGGED, 0, tag, handle);
+}
+
+inline
+int svc_objectDir::onAction(int action, ifc_window *from, const wchar_t *target, ObjectHandle handle) {
+ return _call(ONACTION, 0, action, from, target, handle);
+}
+
+inline
+int svc_objectDir::contextMenu(ifc_window *from, int x, int y, ObjectHandle handle) {
+ return _call(CONTEXTMENU, 0, from, x, y, handle);
+}
+
+inline
+void svc_objectDir::onPrerender(ObjectHandle handle, const RECT *r, BaseCanvas *c, int style) {
+ _voidcall(ONPRERENDER, handle, r, c, style);
+}
+inline
+void svc_objectDir::onPostrender(ObjectHandle handle, const RECT *r, BaseCanvas *c, int style) {
+ _voidcall(ONPOSTRENDER, handle, r, c, style);
+}
+
+
+/**
+ Service implementation. Usually you'll derive from ObjectDir, not this.
+ You can still derive from this if you want to fully implement the interface yourself for some reason though.
+ @see ObjectDir
+*/
+class svc_objectDirI : public svc_objectDir {
+public:
+ virtual api_dependent *getDependencyPtr()=0;
+
+ virtual const wchar_t *getDirType()=0;
+
+ virtual int getNumObjects()=0;
+ virtual ObjectHandle enumObject(int n)=0;
+
+ virtual void *getObject(ObjectHandle handle)=0;
+
+ virtual const wchar_t *getObjectLabel(ObjectHandle handle)=0;
+ virtual int setObjectLabel(ObjectHandle handle, const wchar_t *newlabel)=0;
+
+ virtual ObjectHandle insertObject(const wchar_t *parameter=NULL, const wchar_t *label=NULL, const wchar_t *path=NULL)=0;
+ virtual int removeObject(ObjectHandle handle)=0;
+
+ virtual void clearAll()=0;
+
+ virtual const wchar_t *getObjectPath(ObjectHandle handle)=0;
+ virtual const wchar_t *getObjectDisplayGroup(ObjectHandle handle)=0;
+ virtual const wchar_t *getObjectIcon(ObjectHandle handle)=0;
+ virtual int getObjectSelectable(ObjectHandle handle)=0;
+ virtual int getObjectSortOrder(ObjectHandle handle)=0;
+
+ virtual int tagObject(const wchar_t *tag, ObjectHandle handle, int exclusive=FALSE)=0;
+ virtual int untagObject(const wchar_t *tag, ObjectHandle handle)=0;
+ virtual ObjectHandle enumObjectByTag(const wchar_t *tag, int n)=0;
+ virtual int isTagged(const wchar_t *tag, ObjectHandle handle)=0;
+
+ virtual int onAction(int action, ifc_window *from, const wchar_t *target, ObjectHandle handle)=0;
+
+ // return -1 to request renaming the item, 0 normally
+ virtual int contextMenu(ifc_window *from, int x, int y, ObjectHandle handle)=0;
+
+ virtual void onPrerender(ObjectHandle handle, const RECT *r, BaseCanvas *c, int style) { }
+ virtual void onPostrender(ObjectHandle handle, const RECT *r, BaseCanvas *c, int style) { }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class ObjectDirCreator : public waServiceFactoryTSingle<svc_objectDir, T> { };
+
+#include <api/service/svc_enum.h>
+
+class ObjectDirEnum : public SvcEnumT<svc_objectDir> {
+public:
+ ObjectDirEnum(const wchar_t *_name) : name(_name) {}
+ virtual int testService(svc_objectDir *svc) {
+ return !WCSICMP(svc->getDirType(), name);
+ }
+private:
+ StringW name;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_player.h b/Src/Wasabi/api/service/svcs/svc_player.h
new file mode 100644
index 00000000..cf6f136e
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_player.h
@@ -0,0 +1,35 @@
+#ifndef _SVC_PLAYER_H
+#define _SVC_PLAYER_H
+
+#include <bfc/dispatch.h>
+
+#include <api/service/services.h>
+
+class api_window;
+
+class svc_player {
+public:
+ static const char *getServiceName() { return "Standard player service"; }
+ static int getServiceType() { return WaSvc::UNIQUE; }
+ static GUID getServiceGuid() {
+ // {9DE79C4A-B9E6-46f4-9AE2-40E0F09CCA51}
+ const GUID guid =
+ { 0x9de79c4a, 0xb9e6, 0x46f4, { 0x9a, 0xe2, 0x40, 0xe0, 0xf0, 0x9c, 0xca, 0x51 } };
+ return guid;
+ }
+ virtual void openFile(const char *filename, FOURCC droptarg=MK3CC('d','e','f'))=0;
+ virtual void openFiles(api_window *parent=NULL, const char *type=NULL, FOURCC droptarg=MK3CC('d','e','f'))=0;
+};
+
+class svc_playerI : public svc_player {
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class PlayerCreator : public waServiceFactoryTSingle<svc_player, T> {
+public:
+ PlayerCreator() : waServiceFactoryTSingle<svc_player, T>(svc_player::getServiceGuid()) {}
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_playlist.cpp b/Src/Wasabi/api/service/svcs/svc_playlist.cpp
new file mode 100644
index 00000000..88b81c53
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_playlist.cpp
@@ -0,0 +1,28 @@
+#include <precomp.h>
+
+#include "svc_playlist.h"
+
+#define CBCLASS svc_playlistReaderI
+START_DISPATCH;
+ CB(GETEXTENSION, getExtension);
+ CB(TESTFILENAME, testFilename);
+ CB(GETDESCRIPTION, getDescription);
+ CB(READPLAYLIST, readPlaylist);
+ CB(GETLABEL, getLabel);
+ CB(GETNUMENTRIES, getNumEntries);
+ CB(ENUMENTRY, enumEntry);
+ VCB(ENABLEDATABASEADD, enableDatabaseAdd);
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS svc_playlistWriterI
+START_DISPATCH;
+ CB(GETEXTENSION, getExtension);
+ CB(GETDESCRIPTION, getDescription);
+ CB(WRITEPLAYLIST, writePlaylist);
+ CB(BEGINWRITE, beginWrite);
+ VCB(WRITEENTRY, writeEntry);
+ VCB(ENDWRITE, endWrite);
+ VCB(ENABLEMETADATA, enableMetadata);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_playlist.h b/Src/Wasabi/api/service/svcs/svc_playlist.h
new file mode 100644
index 00000000..928da339
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_playlist.h
@@ -0,0 +1,216 @@
+#ifndef _SVC_PLAYLIST_H
+#define _SVC_PLAYLIST_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class Playlist;
+
+class NOVTABLE svc_playlistReader : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::PLAYLISTREADER; }
+
+ const char *getExtension();
+ int testFilename(const char *filename);
+ const char *getDescription();
+
+ void setAllowedMetadataColumns(const char *columnslist); // "a;b;c" ""=all
+ void setBannedMetadataColumns(const char *columnslist); // "a;b;c" ""==all
+
+ void enableDatabaseAdd(int enabled); // defaults to TRUE
+// void enableMetadata(int enabled); // defaults to TRUE
+
+ int readPlaylist(const char *filename);
+
+ const char *getLabel();
+ int getNumEntries();
+ const char *enumEntry(int n);
+
+protected:
+ enum {
+ GETEXTENSION=0, READPLAYLIST=1, GETLABEL=2, GETNUMENTRIES=3, ENUMENTRY=4,
+ TESTFILENAME=100,
+ GETDESCRIPTION=110,
+ ENABLEDATABASEADD=200,
+ };
+};
+
+inline
+const char *svc_playlistReader::getExtension() {
+ return _call(GETEXTENSION, "");
+}
+
+inline
+int svc_playlistReader::testFilename(const char *filename) {
+ return _call(TESTFILENAME, -1, filename);
+}
+
+inline
+const char *svc_playlistReader::getDescription() {
+ return _call(GETDESCRIPTION, (const char *)NULL);
+}
+
+inline
+void svc_playlistReader::enableDatabaseAdd(int enabled) {
+ _voidcall(ENABLEDATABASEADD, enabled);
+}
+
+inline
+int svc_playlistReader::readPlaylist(const char *filename) {
+ return _call(READPLAYLIST, 0, filename);
+}
+
+inline
+const char *svc_playlistReader::getLabel() {
+ return _call(GETLABEL, (const char *)0);
+}
+
+inline
+int svc_playlistReader::getNumEntries() {
+ return _call(GETNUMENTRIES, 0);
+}
+
+inline
+const char *svc_playlistReader::enumEntry(int n) {
+ return _call(ENUMENTRY, (const char *)NULL, n);
+}
+
+class NOVTABLE svc_playlistReaderI : public svc_playlistReader {
+public:
+ virtual const char *getExtension()=0;
+ virtual int testFilename(const char *filename) { return -1; }
+ virtual const char *getDescription() { return NULL; }
+
+ virtual void enableDatabaseAdd(int enabled)=0;
+
+ virtual int readPlaylist(const char *filename)=0;
+
+ virtual const char *getLabel()=0;
+ virtual int getNumEntries()=0;
+ virtual const char *enumEntry(int n)=0;
+
+private:
+ RECVS_DISPATCH;
+};
+
+class NOVTABLE svc_playlistWriter : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::PLAYLISTWRITER; }
+
+ const char *getExtension();
+ const char *getDescription();
+
+ void enableMetadata(int enabled);
+
+ int writePlaylist(const char *filename, Playlist *pl, int full_data, int first, int last);
+
+// old-style, DEPRECATED
+ int beginWrite(const char *filename, int n, const char *label);
+ void writeEntry(const char *playstring);
+ void endWrite();
+
+protected:
+ enum {
+ GETEXTENSION=0,
+ GETDESCRIPTION=1,
+ BEGINWRITE=2,
+ WRITEENTRY=3,
+ ENDWRITE=4,
+ WRITEPLAYLIST=100,
+ ENABLEMETADATA=200,
+ };
+};
+
+inline
+const char *svc_playlistWriter::getExtension() {
+ return _call(GETEXTENSION, (const char *)0);
+}
+
+inline
+const char *svc_playlistWriter::getDescription() {
+ return _call(GETDESCRIPTION, (const char *)0);
+}
+
+inline
+void svc_playlistWriter::enableMetadata(int enabled) {
+ _voidcall(ENABLEMETADATA, enabled);
+}
+
+inline
+int svc_playlistWriter::writePlaylist(const char *filename, Playlist *pl, int full_data, int first, int last) {
+ return _call(WRITEPLAYLIST, -1, filename, pl, full_data, first, last);
+}
+
+inline
+int svc_playlistWriter::beginWrite(const char *filename, int n, const char *label) {
+ return _call(BEGINWRITE, 0, filename, n, label);
+}
+
+inline
+void svc_playlistWriter::writeEntry(const char *playstring) {
+ _voidcall(WRITEENTRY, playstring);
+}
+
+inline
+void svc_playlistWriter::endWrite() {
+ _voidcall(ENDWRITE);
+}
+
+class NOVTABLE svc_playlistWriterI : public svc_playlistWriter {
+public:
+ virtual const char *getExtension()=0;
+ virtual const char *getDescription() { return NULL; }
+
+ virtual void enableMetadata(int enabled) { }
+
+ virtual int writePlaylist(const char *filename, Playlist *pl, int full_data, int first, int last) { return -1; }
+
+// old-style, DEPRECATED
+ virtual int beginWrite(const char *filename, int n, const char *label) { return 0; }
+ virtual void writeEntry(const char *playstring) { }
+ virtual void endWrite() { }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+
+template <class T>
+class PlaylistReaderCreator : public waServiceFactoryT<svc_playlistReader, T> {};
+
+template <class T>
+class PlaylistWriterCreator : public waServiceFactoryT<svc_playlistWriter, T> {};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/string.h>
+
+class PlaylistReaderEnum : public SvcEnumT<svc_playlistReader> {
+public:
+ PlaylistReaderEnum(const char *filename) : fn(filename) {}
+
+protected:
+ virtual int testService(svc_playlistReader *svc) {
+ int r = svc->testFilename(fn);
+ if (r == -1) return STRCASEEQL(svc->getExtension(), Std::extension(fn));
+ return r;
+ }
+
+private:
+ String fn;
+};
+
+class PlaylistWriterEnum : public SvcEnumT<svc_playlistWriter> {
+public:
+ PlaylistWriterEnum(const char *filename) :
+ ext(Std::extension(filename)) {}
+protected:
+ virtual int testService(svc_playlistWriter *svc) {
+ return STRCASEEQL(svc->getExtension(), ext);
+ }
+
+private:
+ String ext;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_redir.cpp b/Src/Wasabi/api/service/svcs/svc_redir.cpp
new file mode 100644
index 00000000..ab7d42f6
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_redir.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+
+#include "svc_redir.h"
+
+#define CBCLASS svc_redirectI
+START_DISPATCH;
+ CB(ISMINE, isMine);
+ CB(REDIRECT, redirect);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_redir.h b/Src/Wasabi/api/service/svcs/svc_redir.h
new file mode 100644
index 00000000..9ab82b8a
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_redir.h
@@ -0,0 +1,63 @@
+#ifndef _SVC_REDIR_H
+#define _SVC_REDIR_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+/* Domains:
+ "Filename"
+ "Url"
+*/
+
+// if you want to redirect a string easily, look at RedirString in
+// bfc/util/redirstr.h
+
+class svc_redirect : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::REDIRECT; }
+
+ int isMine(const wchar_t *str, const wchar_t *domain);
+ int redirect(const wchar_t *orig_str, const wchar_t *domain, wchar_t *buf, int buflen);
+
+protected:
+ enum {
+ ISMINE=100,
+ REDIRECT=200,
+ };
+};
+
+inline int svc_redirect::isMine(const wchar_t *str, const wchar_t *domain) {
+ return _call(ISMINE, 0, str, domain);
+}
+
+inline int svc_redirect::redirect(const wchar_t *orig_str, const wchar_t *domain, wchar_t *buf, int buflen) {
+ return _call(REDIRECT, 0, orig_str, domain, buf, buflen);
+}
+
+class svc_redirectI : public svc_redirect {
+public:
+ virtual int isMine(const wchar_t *str, const wchar_t *domain)=0;
+ virtual int redirect(const wchar_t *orig_str, const wchar_t *domain, wchar_t *buf, int buflen)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+
+class RedirectEnum : public SvcEnumT<svc_redirect> {
+public:
+ RedirectEnum(const wchar_t *filename, const wchar_t *domain=L"Filename") :
+ fn(filename), dom(domain) {
+ }
+
+ virtual int testService(svc_redirect *svc) {
+ if (svc->isMine(fn, dom)) return 1;
+ return 0;
+ }
+
+private:
+ const wchar_t *fn, *dom;
+};
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_scriptobj.cpp b/Src/Wasabi/api/service/svcs/svc_scriptobj.cpp
new file mode 100644
index 00000000..4d154c85
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_scriptobj.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+
+#include "svc_scriptobji.h"
+
+#define CBCLASS svc_scriptObjectI
+START_DISPATCH;
+ CB(GETCONTROLLER, getController);
+ VCB(ONREGISTER, onRegisterClasses);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_scriptobj.h b/Src/Wasabi/api/service/svcs/svc_scriptobj.h
new file mode 100644
index 00000000..8cdae362
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_scriptobj.h
@@ -0,0 +1,29 @@
+#ifndef _SVC_SCRIPTOBJECT_H
+#define _SVC_SCRIPTOBJECT_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class ScriptObjectController;
+
+class svc_scriptObject : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::SCRIPTOBJECT; }
+ ScriptObjectController *getController(int n);
+ void onRegisterClasses(ScriptObjectController *rootController);
+
+ enum {
+ GETCONTROLLER=10,
+ ONREGISTER=20,
+ };
+};
+
+inline ScriptObjectController *svc_scriptObject::getController(int n) {
+ return _call(GETCONTROLLER, (ScriptObjectController *)0, n);
+}
+
+inline void svc_scriptObject::onRegisterClasses(ScriptObjectController *rootController) {
+ _voidcall(ONREGISTER, rootController);
+}
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_scriptobji.h b/Src/Wasabi/api/service/svcs/svc_scriptobji.h
new file mode 100644
index 00000000..59014cf0
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_scriptobji.h
@@ -0,0 +1,51 @@
+#pragma once
+#include "svc_scriptobji.h"
+// derive from this one
+class svc_scriptObjectI : public svc_scriptObject {
+public:
+ virtual ScriptObjectController *getController(int n)=0;
+ virtual void onRegisterClasses(ScriptObjectController *rootController) {};
+
+protected:
+ RECVS_DISPATCH;
+};
+
+template <class T>
+class ScriptObjectControllerCreator : public svc_scriptObjectI {
+public:
+ static const char *getServiceName() { return "ScriptObjectControllerCreator"; }
+
+ ScriptObjectControllerCreator()
+ {
+ }
+
+ virtual ~ScriptObjectControllerCreator()
+ {
+ }
+
+ virtual ScriptObjectController *getController(int n)
+ {
+ if (n == 0) return &single_controller;
+ return NULL;
+ }
+
+private:
+ T single_controller;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class ScriptObjectCreator : public waServiceFactoryTSingle<svc_scriptObject, T> {};
+
+#include <api/service/svc_enum.h>
+
+class ExternalScriptObjectEnum : public SvcEnumT<svc_scriptObject> {
+public:
+ ExternalScriptObjectEnum() { }
+
+protected:
+ virtual int testService(svc_scriptObject*svc) {
+ return (svc->getController(0) != NULL);
+ }
+};
+
diff --git a/Src/Wasabi/api/service/svcs/svc_skinfilter.cpp b/Src/Wasabi/api/service/svcs/svc_skinfilter.cpp
new file mode 100644
index 00000000..34d2adf4
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_skinfilter.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+
+#include "svc_skinfilter.h"
+
+#define CBCLASS svc_skinFilterI
+START_DISPATCH;
+ CB(FILTERBITMAP, filterBitmap);
+ CB(FILTERCOLOR, filterColor);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_skinfilter.h b/Src/Wasabi/api/service/svcs/svc_skinfilter.h
new file mode 100644
index 00000000..ef3fae71
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_skinfilter.h
@@ -0,0 +1,56 @@
+#ifndef _SVC_SKINFILTER_H
+#define _SVC_SKINFILTER_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+// TODO: make some sort of ifc_bitmap so we can do OS-level manipulations if necessary
+
+class NOVTABLE svc_skinFilter : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::SKINFILTER; }
+ int filterBitmap(uint8_t *bits, int w, int h, int bpp, const wchar_t *element_id, const wchar_t *forcegroup=NULL);
+ ARGB32 filterColor(ARGB32 color, const wchar_t *element_id, const wchar_t *forcegroup=NULL);
+
+ enum {
+ FILTERBITMAP=100,
+ FILTERCOLOR=200,
+ };
+};
+
+inline int svc_skinFilter::filterBitmap(uint8_t *bits, int w, int h, int bpp, const wchar_t *element_id, const wchar_t *forcegroup) {
+ return _call(FILTERBITMAP, 0, bits, w, h, bpp, element_id, forcegroup);
+}
+
+inline ARGB32 svc_skinFilter::filterColor(ARGB32 color, const wchar_t *element_id, const wchar_t *forcegroup) {
+ return _call(FILTERCOLOR, (ARGB32)0, color, element_id, forcegroup);
+}
+
+// derive from this one
+class NOVTABLE svc_skinFilterI : public svc_skinFilter
+{
+public:
+ virtual int filterBitmap(uint8_t *bits, int w, int h, int bpp, const wchar_t *element_id, const wchar_t *forcegroup=NULL)=0;
+ virtual ARGB32 filterColor(ARGB32 color, const wchar_t *element_id, const wchar_t *forcegroup=NULL)
+ {
+ // easy cheesy helper
+ filterBitmap((uint8_t *)&color, 1, 1, 32, element_id, forcegroup);
+ return color;
+ }
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+
+class SkinFilterEnum : public SvcEnumT<svc_skinFilter> {
+public:
+ SkinFilterEnum() {}
+protected:
+ virtual int testService(svc_skinFilter* svc) {
+ return TRUE;
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_storagevolenum.cpp b/Src/Wasabi/api/service/svcs/svc_storagevolenum.cpp
new file mode 100644
index 00000000..8e26b793
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_storagevolenum.cpp
@@ -0,0 +1,30 @@
+#include <precomp.h>
+#include "svc_storagevolenum.h"
+
+//-----------------------------------------------------------------
+
+#define CBCLASS StorageVolumeI
+START_DISPATCH;
+ CB(GETVOLUMENAME, getVolumeName);
+ CB(GETMOUNTPATH, getMountPath);
+ CB(GETLABEL, getLabel);
+ CB(GETTYPE, getType);
+ CB(ISREMOVABLE, isRemovable);
+ CB(ISWRITABLE, isWritable);
+ CB(GETFREESPACE, getFreeSpace);
+ CB(GETSIZE, getSize);
+END_DISPATCH;
+#undef CBCLASS
+
+//-----------------------------------------------------------------
+
+#define CBCLASS svc_storageVolumeEnumI
+START_DISPATCH;
+ CB(GETNUMVOLUMES, getNumVolumes);
+ CB(ENUMVOLUME, enumVolume);
+END_DISPATCH;
+#undef CBCLASS
+
+//-----------------------------------------------------------------
+
+
diff --git a/Src/Wasabi/api/service/svcs/svc_storagevolenum.h b/Src/Wasabi/api/service/svcs/svc_storagevolenum.h
new file mode 100644
index 00000000..15d60ed7
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_storagevolenum.h
@@ -0,0 +1,96 @@
+#ifndef __SVC_STORAGEVOLENUM_H
+#define __SVC_STORAGEVOLENUM_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+enum StorageVolumeTypes {
+ NOT_VALID = 0, //Not a valid Volume.
+ UNKNOWN = 1, //Unknown Drive Type.
+ LOCAL = 1<<1, //Local (Fixed) Hard Drive.
+ REMOVABLE = 1<<2, //Removable Drive (Floppy, LS-120, Zip, USB FlashCard Reader, etc.)
+ NETWORK = 1<<3, //Network Drive (SMB, NFS, etc.)
+ CDROM = 1<<4, //CD / DVD ROM, WRITER, Re-WRITER, etc.
+ RAMDISK = 1<<5, //RAM Drive.
+};
+
+//-----------------------------------------------------------------
+
+class NOVTABLE StorageVolume : public Dispatchable {
+public:
+ const char *getVolumeName() { return _call(GETVOLUMENAME, (const char *) NULL); }
+ const char *getMountPath() { return _call(GETMOUNTPATH, (const char *) NULL); }
+ const char *getLabel() { return _call(GETLABEL, (const char *) NULL); }
+
+ int getType() { return _call(GETTYPE, 0); }
+
+ int isRemovable() { return _call(ISREMOVABLE, -1); }
+ int isWritable() { return _call(ISWRITABLE, -1); }
+
+ __int64 getFreeSpace() { return _call(GETFREESPACE, -1); }
+ __int64 getSize() { return _call(GETSIZE, -1); }
+
+ enum {
+ GETVOLUMENAME = 10,
+ GETMOUNTPATH = 20,
+ GETLABEL = 30,
+ GETTYPE = 40,
+ ISREMOVABLE = 50,
+ ISWRITABLE = 60,
+ GETFREESPACE = 70,
+ GETSIZE = 80
+ };
+};
+
+//-----------------------------------------------------------------
+
+class StorageVolumeI : public StorageVolume {
+public:
+ virtual const char *getVolumeName()=0;
+ virtual const char *getMountPath()=0;
+ virtual const char *getLabel()=0;
+
+ virtual int getType()=0;
+
+ virtual int isRemovable()=0;
+ virtual int isWritable()=0;
+
+ virtual __int64 getFreeSpace()=0;
+ virtual __int64 getSize()=0;
+
+protected:
+ RECVS_DISPATCH;
+
+};
+
+//-----------------------------------------------------------------
+
+class NOVTABLE svc_storageVolumeEnum : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::STORAGEVOLENUM; }
+
+ int getNumVolumes() { return _call(GETNUMVOLUMES, (int) 0); }
+ StorageVolume *enumVolume(int which) { return _call(ENUMVOLUME, (StorageVolume *)NULL); }
+
+ enum {
+ GETNUMVOLUMES = 10,
+ ENUMVOLUME = 20,
+ };
+
+};
+
+//-----------------------------------------------------------------
+
+class svc_storageVolumeEnumI : public svc_storageVolumeEnum {
+public:
+ virtual int getNumVolumes()=0; //Get the number of Storage Volumes.
+ //Enum a Storage Volume.
+ virtual StorageVolume *enumVolume(int which)=0;
+
+protected:
+ RECVS_DISPATCH;
+
+};
+
+#endif //__SVC_STORAGEVOLENUM_H \ No newline at end of file
diff --git a/Src/Wasabi/api/service/svcs/svc_stringconverter.cpp b/Src/Wasabi/api/service/svcs/svc_stringconverter.cpp
new file mode 100644
index 00000000..cf1c1222
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_stringconverter.cpp
@@ -0,0 +1,12 @@
+#include <precomp.h>
+#include "svc_stringconverter.h"
+
+#define CBCLASS svc_stringConverterI
+START_DISPATCH
+ CB(CANCONVERT, canConvert);
+ CB(CONVERTTOUTF8, convertToUTF8);
+ CB(PREFLIGHTTOUTF8, preflightToUTF8);
+ CB(CONVERTFROMUTF8, convertFromUTF8);
+ CB(PREFLIGHTFROMUTF8, preflightFromUTF8);
+END_DISPATCH
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_stringconverter.h b/Src/Wasabi/api/service/svcs/svc_stringconverter.h
new file mode 100644
index 00000000..c03baac0
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_stringconverter.h
@@ -0,0 +1,94 @@
+#ifndef _SVC_STRINGCONVERTER_H
+#define _SVC_STRINGCONVERTER_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+#include <api/service/svcs/svc_stringtypes.h>
+
+// Porting Rule: A new service to respond to at least OSNATIVE and UTF16 shall be
+// provided for every new platform. This service should provide transcoding
+// to and from the platform's native internationalized string encoding format
+// (ie: MBCS under Win9x, WorldScript on the Mac, etc etc etc).and to and from
+// UTF16. If the OSNATIVE string _IS_ UTF16, just respond that you can convert
+// both.
+
+class NOVTABLE svc_stringConverter : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::STRINGCONVERTER; }
+
+ // test the type.
+ int canConvert(FOURCC encoding_type);
+
+ // The return code is the number of bytes written to the output buffer, or the error.
+ // A return code of 0 is not an error, other than you passing NULL or a size 0 buffer won't do much interesting.
+ int convertToUTF8(FOURCC encoding_type, const void *in_buffer, int size_in_bytes, char *out_buffer, int size_out_bytes);
+ int preflightToUTF8(FOURCC encoding_type, const void *in_buffer, int size_in_bytes);
+ int convertFromUTF8(FOURCC encoding_type, const char *in_buffer, int size_in_bytes, void *out_buffer, int size_out_bytes);
+ int preflightFromUTF8(FOURCC encoding_type, const char *in_buffer, int size_in_bytes);
+
+protected:
+ enum {
+ CANCONVERT,
+ CONVERTTOUTF8,
+ PREFLIGHTTOUTF8,
+ CONVERTFROMUTF8,
+ PREFLIGHTFROMUTF8
+ };
+};
+
+
+inline
+int svc_stringConverter::canConvert(FOURCC encoding_type) {
+ return _call(CANCONVERT, (int)0, encoding_type);
+}
+
+inline
+int svc_stringConverter::convertToUTF8(FOURCC encoding_type, const void *in_buffer, int size_in_bytes, char *out_buffer, int size_out_bytes) {
+ return _call(CONVERTTOUTF8, (int)0, encoding_type, in_buffer, size_in_bytes, out_buffer, size_out_bytes);
+}
+
+inline
+int svc_stringConverter::preflightToUTF8(FOURCC encoding_type, const void *in_buffer, int size_in_bytes) {
+ return _call(PREFLIGHTTOUTF8, (int)0, encoding_type, in_buffer, size_in_bytes);
+}
+
+inline
+int svc_stringConverter::convertFromUTF8(FOURCC encoding_type, const char *in_buffer, int size_in_bytes, void *out_buffer, int size_out_bytes) {
+ return _call(CONVERTFROMUTF8, (int)0, encoding_type, in_buffer, size_in_bytes, out_buffer, size_out_bytes);
+}
+
+inline
+int svc_stringConverter::preflightFromUTF8(FOURCC encoding_type, const char *in_buffer, int size_in_bytes) {
+ return _call(PREFLIGHTFROMUTF8, (int)0, encoding_type, in_buffer, size_in_bytes);
+}
+
+// implementor derives from this one
+class NOVTABLE svc_stringConverterI : public svc_stringConverter {
+public:
+
+ // test the type
+ virtual int canConvert(FOURCC encoding_type) = 0;
+
+ virtual int convertToUTF8(FOURCC encoding_type, const void *in_buffer, int size_in_bytes, char *out_buffer, int size_out_bytes) = 0;
+ virtual int preflightToUTF8(FOURCC encoding_type, const void *in_buffer, int size_in_bytes) = 0;
+ virtual int convertFromUTF8(FOURCC encoding_type, const char *in_buffer, int size_in_bytes, void *out_buffer, int size_out_bytes) = 0;
+ virtual int preflightFromUTF8(FOURCC encoding_type, const char *in_buffer, int size_in_bytes) = 0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+
+class StringConverterEnum : public SvcEnumT<svc_stringConverter> {
+public:
+ StringConverterEnum(FOURCC enc_type) : encoding_type(enc_type) {}
+protected:
+ virtual int testService(svc_stringConverter *svc) {
+ return (svc->canConvert(encoding_type));
+ }
+private:
+ FOURCC encoding_type;
+};
+
+#endif // _SVC_STRINGCONVERTER_H
diff --git a/Src/Wasabi/api/service/svcs/svc_stringtypes.h b/Src/Wasabi/api/service/svcs/svc_stringtypes.h
new file mode 100644
index 00000000..bff5cf9f
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_stringtypes.h
@@ -0,0 +1,35 @@
+#ifndef _SVC_STRINGTYPES_H
+#define _SVC_STRINGTYPES_H
+
+// Here, you look like you're in need of some error codes.
+namespace SvcStrCnv {
+ typedef enum {
+ // The conversion failed for some generic 'fatal' reason, not covered by the
+ // other reasons below. (Possibly a bug in the service implementation).
+ ERROR_FATAL = -1,
+
+ // The conversion failed because your output buffer was too small.
+ ERROR_BUFFER_OVERRUN = -2,
+
+ // The conversion failed because your input string had unrecoverable errors in it
+ ERROR_INPUT = -3,
+
+ // The service instance does not support that type of encoding for conversion
+ ERROR_INVALID = -4,
+
+ // The service instance isn't available (ONLY generated by EncodedStr.cpp, obviously)
+ ERROR_UNAVAILABLE = -5,
+
+ } ConvertErrors;
+
+ // These types MUST be supported by the platform port for this service.
+ typedef enum {
+ OSNATIVE=MK4CC('n','a','t','v'),
+ UTF16=MK4CC('u','-','1','6'),
+ } EncodingTypes;
+ // Other service instances may implement other encoding types.
+ // They all should provide their own FOURCC #define or enum in their headers.
+}
+
+
+#endif // _SVC_STRINGTYPES_H
diff --git a/Src/Wasabi/api/service/svcs/svc_textfeed.cpp b/Src/Wasabi/api/service/svcs/svc_textfeed.cpp
new file mode 100644
index 00000000..7ede4ce4
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_textfeed.cpp
@@ -0,0 +1,18 @@
+#include <precomp.h>
+
+#include "svc_textfeed.h"
+#include <bfc/depend.h>
+
+#define CBCLASS svc_textFeedI
+START_DISPATCH;
+ CB(SVCTEXTFEED_HASFEED, hasFeed);
+ CB(SVCTEXTFEED_GETFEEDTEXT, getFeedText);
+ CB(SVCTEXTFEED_GETFEEDDESC, getFeedDescription);
+ CB(SVCTEXTFEED_GETDEPENDENCYPTR, getDependencyPtr);
+END_DISPATCH;
+#undef CBCLASS
+
+void *svc_textFeedI::dependent_getInterface(const GUID *classguid) {
+ HANDLEGETINTERFACE(svc_textFeed);
+ return NULL;
+}
diff --git a/Src/Wasabi/api/service/svcs/svc_textfeed.h b/Src/Wasabi/api/service/svcs/svc_textfeed.h
new file mode 100644
index 00000000..c37754f7
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_textfeed.h
@@ -0,0 +1,21 @@
+#ifndef _SVC_TEXTFEED_H
+#define _SVC_TEXTFEED_H
+
+//#include <api/service/services.h>
+#include <api/skin/feeds/api_textfeed.h>
+
+class NOVTABLE svc_textFeedI : public svc_textFeed
+{
+public:
+ virtual int hasFeed(const wchar_t *name) = 0;
+ virtual const wchar_t *getFeedText(const wchar_t *name) = 0;
+ virtual const wchar_t *getFeedDescription(const wchar_t *name) = 0;
+ virtual api_dependent *getDependencyPtr() = 0;
+ virtual void *dependent_getInterface(const GUID *classguid); //implemented for you
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_tooltips.cpp b/Src/Wasabi/api/service/svcs/svc_tooltips.cpp
new file mode 100644
index 00000000..f42f7fed
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_tooltips.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+#include "svc_tooltips.h"
+
+#define CBCLASS svc_toolTipsRendererI
+START_DISPATCH;
+ CB(SPAWNTOOLTIP, spawnTooltip);
+END_DISPATCH;
+#undef CBCLASS
+
+
diff --git a/Src/Wasabi/api/service/svcs/svc_tooltips.h b/Src/Wasabi/api/service/svcs/svc_tooltips.h
new file mode 100644
index 00000000..c3591146
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_tooltips.h
@@ -0,0 +1,30 @@
+#ifndef _SVC_TOOLTIPS_H
+#define _SVC_TOOLTIPS_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class NOVTABLE svc_toolTipsRenderer : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::TOOLTIPSRENDERER; }
+
+ int spawnTooltip(const wchar_t *text);
+
+ enum {
+ SPAWNTOOLTIP =10,
+ };
+};
+
+inline int svc_toolTipsRenderer::spawnTooltip(const wchar_t *text) {
+ return _call(SPAWNTOOLTIP, 0, text);
+}
+
+class NOVTABLE svc_toolTipsRendererI : public svc_toolTipsRenderer {
+public:
+ virtual int spawnTooltip(const wchar_t *text)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_wndcreate.cpp b/Src/Wasabi/api/service/svcs/svc_wndcreate.cpp
new file mode 100644
index 00000000..168e7a2f
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_wndcreate.cpp
@@ -0,0 +1,16 @@
+#include <precomp.h>
+
+#include "svc_wndcreate.h"
+
+#define CBCLASS svc_windowCreateI
+START_DISPATCH;
+ CB(TESTGUID, testGuid);
+ CB(CREATEWINDOWBYGUID, createWindowByGuid);
+ CB(TESTTYPE, testType);
+ CB(CREATEWINDOWOFTYPE, createWindowOfType);
+ CB(DESTROYWINDOW, destroyWindow);
+ CB(REFCOUNT, refcount);
+END_DISPATCH;
+#undef CBCLASS
+
+
diff --git a/Src/Wasabi/api/service/svcs/svc_wndcreate.h b/Src/Wasabi/api/service/svcs/svc_wndcreate.h
new file mode 100644
index 00000000..95e46f89
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_wndcreate.h
@@ -0,0 +1,120 @@
+#ifndef _SVC_WNDCREATE_H
+#define _SVC_WNDCREATE_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+#define BUCKETITEM L"buck"
+#define PLAYLISTSIDECAR L"plsc"
+
+class ifc_window;
+
+class NOVTABLE svc_windowCreate : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::WINDOWCREATE; }
+
+ int testGuid(GUID g);
+ ifc_window *createWindowByGuid(GUID g, ifc_window *parent);
+ int testType(const wchar_t *windowtype);
+ ifc_window *createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n = 0);
+ int destroyWindow(ifc_window *w);
+
+ int refcount(); // how many windows created
+
+ enum {
+ TESTGUID = 100,
+ CREATEWINDOWBYGUID = 200,
+ TESTTYPE = 301,
+ CREATEWINDOWOFTYPE = 402,
+ DESTROYWINDOW = 500,
+ REFCOUNT = 600,
+ };
+};
+
+inline int svc_windowCreate::testGuid(GUID g)
+{
+ return _call(TESTGUID, 0, g);
+}
+
+inline ifc_window *svc_windowCreate::createWindowByGuid(GUID g, ifc_window *parent)
+{
+ return _call(CREATEWINDOWBYGUID, (ifc_window*)0, g, parent);
+}
+
+inline int svc_windowCreate::destroyWindow(ifc_window *w)
+{
+ return _call(DESTROYWINDOW, 0, w);
+}
+
+inline int svc_windowCreate::testType(const wchar_t *windowtype)
+{
+ return _call(TESTTYPE, 0, windowtype);
+}
+
+inline ifc_window *svc_windowCreate::createWindowOfType(const wchar_t * windowtype, ifc_window *parent, int n)
+{
+ return _call(CREATEWINDOWOFTYPE, (ifc_window*)0, windowtype, parent, n);
+}
+
+inline int svc_windowCreate::refcount()
+{
+ return _call(REFCOUNT, -1);
+}
+
+class NOVTABLE svc_windowCreateI : public svc_windowCreate
+{
+public:
+ virtual ~svc_windowCreateI() { }
+ virtual int testGuid(GUID g) { return 0; }
+ virtual ifc_window *createWindowByGuid(GUID g, ifc_window *parent) { return NULL; }
+ virtual int testType(const wchar_t *windowtype) { return 0; }
+ virtual ifc_window *createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n) { return NULL; }
+ virtual int destroyWindow(ifc_window *w) = 0;
+
+ virtual int refcount() { return -1; } // FUCKO: make pure abstract
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class WndCreateCreator : public waServiceFactoryT<svc_windowCreate, T> {};
+
+template <class T>
+class WndCreateCreatorSingle : public waServiceFactoryTSingle<svc_windowCreate, T> {};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class WindowCreateByGuidEnum : public SvcEnumT<svc_windowCreate>
+{
+public:
+ WindowCreateByGuidEnum(GUID _g) : targetguid(_g) { }
+
+protected:
+ virtual int testService(svc_windowCreate *svc)
+ {
+ return svc->testGuid(targetguid);
+ }
+
+private:
+ GUID targetguid;
+};
+
+class WindowCreateByTypeEnum : public SvcEnumT<svc_windowCreate>
+{
+public:
+ WindowCreateByTypeEnum(const wchar_t *_wtype) : wtype(_wtype) { }
+
+protected:
+ virtual int testService(svc_windowCreate *svc)
+ {
+ return svc->testType(wtype);
+ }
+
+private:
+ StringW wtype;
+};
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_xmlprov.cpp b/Src/Wasabi/api/service/svcs/svc_xmlprov.cpp
new file mode 100644
index 00000000..b84826eb
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_xmlprov.cpp
@@ -0,0 +1,10 @@
+#include <precomp.h>
+
+#include "svc_xmlprov.h"
+
+#define CBCLASS svc_xmlProviderI
+START_DISPATCH;
+ CB(TESTDESC, testDesc);
+ CB(GETXMLDATA, getXmlData);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_xmlprov.h b/Src/Wasabi/api/service/svcs/svc_xmlprov.h
new file mode 100644
index 00000000..d6c27f01
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_xmlprov.h
@@ -0,0 +1,56 @@
+#ifndef _SVC_XMLPROVIDER_H
+#define _SVC_XMLPROVIDER_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+
+class skin_xmlreaderparams;
+
+class NOVTABLE svc_xmlProvider : public Dispatchable {
+public:
+ static FOURCC getServiceType() { return WaSvc::XMLPROVIDER; }
+
+ int testDesc(const wchar_t *desc);
+ const wchar_t *getXmlData(const wchar_t *desc, const wchar_t *incpath, skin_xmlreaderparams *params=NULL);
+
+ enum {
+ TESTDESC=10,
+ GETXMLDATA=20,
+ };
+};
+
+inline int svc_xmlProvider::testDesc(const wchar_t *desc) {
+ return _call(TESTDESC, 0, desc);
+}
+
+inline const wchar_t *svc_xmlProvider::getXmlData(const wchar_t *desc, const wchar_t *incpath, skin_xmlreaderparams *params) {
+ return _call(GETXMLDATA, (const wchar_t *)0, desc, incpath, params);
+}
+
+// derive from this one
+class NOVTABLE svc_xmlProviderI : public svc_xmlProvider {
+public:
+ virtual int testDesc(const wchar_t *desc)=0;
+ virtual const wchar_t *getXmlData(const wchar_t *desc, const wchar_t *incpath, skin_xmlreaderparams *params=NULL)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class XmlProviderEnum : public SvcEnumT<svc_xmlProvider> {
+public:
+ XmlProviderEnum(const wchar_t *_desc) : desc(_desc) { }
+
+protected:
+ virtual int testService(svc_xmlProvider *svc) {
+ return svc->testDesc(desc);
+ }
+
+private:
+ StringW desc;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/svcs/svc_xuiobject.cpp b/Src/Wasabi/api/service/svcs/svc_xuiobject.cpp
new file mode 100644
index 00000000..52973975
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_xuiobject.cpp
@@ -0,0 +1,12 @@
+#include <precomp.h>
+
+#include "svc_xuiobject.h"
+
+#define CBCLASS svc_xuiObjectI
+START_DISPATCH;
+ CB(XUI_TESTTAG, testTag);
+// CB(XUI_INSTANTIATE, instantiate);
+ CB(XUI_INSTANTIATEWITHPARAMS, instantiate);
+ VCB(XUI_DESTROY, destroy);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/svcs/svc_xuiobject.h b/Src/Wasabi/api/service/svcs/svc_xuiobject.h
new file mode 100644
index 00000000..de825b5b
--- /dev/null
+++ b/Src/Wasabi/api/service/svcs/svc_xuiobject.h
@@ -0,0 +1,76 @@
+#ifndef _SVC_XUIOBJECT_H
+#define _SVC_XUIOBJECT_H
+
+#include <bfc/dispatch.h>
+#include <api/service/services.h>
+#include <bfc/platform/platform.h>
+#include <bfc/string/StringW.h>
+class GuiObject;
+class skin_xmlreaderparams;
+
+class NOVTABLE svc_xuiObject : public Dispatchable
+{
+public:
+ static FOURCC getServiceType()
+ {
+ return WaSvc::XUIOBJECT;
+ }
+ int testTag( const wchar_t *xmltag );
+ GuiObject *instantiate( const wchar_t *xmltag, ifc_xmlreaderparams *params = NULL );
+ void destroy( GuiObject *g );
+
+ enum
+ {
+ XUI_TESTTAG = 10,
+ //XUI_INSTANTIATE=20, // RETIRED
+ XUI_INSTANTIATEWITHPARAMS = 25,
+ XUI_DESTROY = 30,
+ };
+};
+
+inline int svc_xuiObject::testTag(const wchar_t *xmltag) {
+ return _call(XUI_TESTTAG, 0, xmltag);
+}
+
+inline GuiObject *svc_xuiObject::instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params) {
+ return _call(XUI_INSTANTIATEWITHPARAMS, (GuiObject *)NULL, xmltag, params);
+}
+
+inline void svc_xuiObject::destroy(GuiObject *o) {
+ _voidcall(XUI_DESTROY, o);
+}
+
+// derive from this one
+class svc_xuiObjectI : public svc_xuiObject
+{
+public:
+ virtual int testTag(const wchar_t *xmltag)=0;
+ virtual GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params=NULL)=0;
+ virtual void destroy(GuiObject *o)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#include <api/service/servicei.h>
+template <class T>
+class XuiObjectCreator : public waServiceFactoryTSingle<svc_xuiObject, T> {
+public:
+ virtual const wchar_t *svc_getTestString() { return T::xuisvc_getXmlTag(); }
+};
+
+#include <api/service/svc_enum.h>
+#include <bfc/string/StringW.h>
+
+class XuiObjectSvcEnum : public SvcEnumT<svc_xuiObject> {
+public:
+ XuiObjectSvcEnum(const wchar_t *xmltag) : tag(xmltag) {}
+protected:
+ virtual int testService(svc_xuiObject *svc) {
+ return (svc->testTag(tag));
+ }
+private:
+ StringW tag;
+};
+
+#endif
diff --git a/Src/Wasabi/api/service/waservicefactory.cpp b/Src/Wasabi/api/service/waservicefactory.cpp
new file mode 100644
index 00000000..7ed88b65
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactory.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:57:16 2003]
+//
+// File : waservicefactory.cpp
+// Class : waServiceFactory
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "waservicefactory.h"
+
+
diff --git a/Src/Wasabi/api/service/waservicefactory.h b/Src/Wasabi/api/service/waservicefactory.h
new file mode 100644
index 00000000..88a72104
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactory.h
@@ -0,0 +1,109 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:57:16 2003]
+//
+// File : waservicefactory.h
+// Class : waServiceFactory
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __WASERVICEFACTORY_H
+#define __WASERVICEFACTORY_H
+
+#include <bfc/dispatch.h>
+#include <bfc/nsguid.h>
+#include "api_service.h"
+// ----------------------------------------------------------------------------
+
+class NOVTABLE waServiceFactory : public Dispatchable
+{
+protected:
+ waServiceFactory() throw( ) {}
+ ~waServiceFactory() {}
+
+public:
+ FOURCC getServiceType();
+ const char *getServiceName();
+ GUID getGuid();
+ const wchar_t *getTestString();
+
+ void *getInterface( int global_lock = TRUE );
+ int releaseInterface( void *ifc );
+
+ int supportNonLockingGetInterface();
+ int serviceNotify( int msg, intptr_t param1 = 0, intptr_t param2 = 0 );
+
+protected:
+ enum
+ {
+ WASERVICEFACTORY_GETSERVICETYPE = 100,
+ WASERVICEFACTORY_GETSERVICENAME = 200,
+ WASERVICEFACTORY_GETGUID = 210,
+ WASERVICEFACTORY_GETINTERFACE = 300,
+ WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE = 301,
+ WASERVICEFACTORY_RELEASEINTERFACE = 310,
+ WASERVICEFACTORY_GETTESTSTRING = 500,
+ WASERVICEFACTORY_SERVICENOTIFY = 600,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline FOURCC waServiceFactory::getServiceType()
+{
+ FOURCC __retval = _call( WASERVICEFACTORY_GETSERVICETYPE, (FOURCC)NULL );
+ return __retval;
+}
+
+inline const char *waServiceFactory::getServiceName()
+{
+ const char *__retval = _call( WASERVICEFACTORY_GETSERVICENAME, (const char *)0 );
+ return __retval;
+}
+
+inline GUID waServiceFactory::getGuid()
+{
+ GUID __retval = _call( WASERVICEFACTORY_GETGUID, INVALID_GUID );
+ return __retval;
+}
+
+inline const wchar_t *waServiceFactory::getTestString()
+{
+ return _call( WASERVICEFACTORY_GETTESTSTRING, (const wchar_t *)0 );
+}
+
+
+inline void *waServiceFactory::getInterface( int global_lock )
+{
+ void *__retval = _call( WASERVICEFACTORY_GETINTERFACE, (void *)NULL, global_lock );
+
+#if 0 // unused in Winamp 5
+ // -- generated code - edit in waservicefactoryi.h
+ // support old code that always locks even when global_lock==FALSE
+ if ( !global_lock && __retval != NULL && !supportNonLockingGetInterface() )
+ WASABI_API_SVC->service_unlock( __retval );
+#endif
+ return __retval;
+}
+
+inline int waServiceFactory::releaseInterface( void *ifc )
+{
+ int __retval = _call( WASERVICEFACTORY_RELEASEINTERFACE, (int)0, ifc );
+ return __retval;
+}
+
+
+inline int waServiceFactory::supportNonLockingGetInterface()
+{
+ int __retval = _call( WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, (int)0 );
+ return __retval;
+}
+
+inline int waServiceFactory::serviceNotify( int msg, intptr_t param1, intptr_t param2 )
+{
+ int __retval = _call( WASERVICEFACTORY_SERVICENOTIFY, (int)0, msg, param1, param2 );
+ return __retval;
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __WASERVICEFACTORY_H
diff --git a/Src/Wasabi/api/service/waservicefactorybase.cpp b/Src/Wasabi/api/service/waservicefactorybase.cpp
new file mode 100644
index 00000000..793842b3
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactorybase.cpp
@@ -0,0 +1,5 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "waservicefactorybase.h"
+//?>
+
diff --git a/Src/Wasabi/api/service/waservicefactorybase.h b/Src/Wasabi/api/service/waservicefactorybase.h
new file mode 100644
index 00000000..19c9c56d
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactorybase.h
@@ -0,0 +1,76 @@
+#ifndef __WASERVICEFACTORYBASE_IMPL_H
+#define __WASERVICEFACTORYBASE_IMPL_H
+
+/*<?<autoheader/>*/
+class CfgItem;
+/*?>*/
+
+#include "waservicefactoryi.h"
+
+template <class SERVICETYPE, class SERVICE>
+class NOVTABLE waServiceFactoryBaseX : public waServiceFactoryI {
+public:
+ waServiceFactoryBaseX(GUID myGuid = INVALID_GUID) : guid(myGuid) {}
+ virtual FOURCC svc_serviceType()=0;
+ virtual const char *svc_getServiceName() { return SERVICE::getServiceName(); }
+ virtual GUID svc_getGuid() { return guid; }
+ virtual void *svc_getInterfaceAndLock() {// this is only for back compat
+ return getInterface(TRUE);
+ }
+
+ virtual void *svc_getInterface(int global_lock)=0;
+ virtual int svc_releaseInterface(void *ptr)=0;
+
+ virtual CfgItem *svc_getCfgInterface() { return NULL; }
+ virtual const wchar_t *svc_getTestString() { return NULL; }
+
+ virtual int svc_notify(int msg, int param1 = 0, int param2 = 0) { return 0; }
+
+private:
+ GUID guid;
+};
+
+// if you derive from this, all you have to do is override the newService()
+// and delService() methods... if all you need to do is instantiate a class
+// and destroy it use the helper below (waServiceFactoryT)
+template <class SERVICETYPE, class SERVICE>
+class NOVTABLE waServiceFactoryBase : public waServiceFactoryBaseX<SERVICETYPE, SERVICE> {
+public:
+ waServiceFactoryBase(GUID myGuid = INVALID_GUID) : waServiceFactoryBaseX<SERVICETYPE, SERVICE>(myGuid) {}
+ virtual FOURCC svc_serviceType() { return SERVICETYPE::getServiceType(); }
+ virtual void *svc_getInterface(int global_lock) { // new style, client optionally does the locking
+ SERVICETYPE *ret = newService();
+ if (global_lock) WASABI_API_SVC->service_lock(this, ret);
+ return ret;
+ }
+ virtual int svc_releaseInterface(void *ptr) {
+ return delService(static_cast<SERVICE*>(static_cast<SERVICETYPE*>(ptr)));
+ }
+protected:
+ virtual SERVICETYPE *newService()=0;
+ virtual int delService(SERVICETYPE *service)=0;
+};
+
+// and this one just exposes a service pointer, without factory. note that
+// SERVICETYPE and SERVICE do not have to be related (unlike waServiceFactoryBase
+// who needs a relationship between the classes in releaseInterface)
+template <class SERVICETYPE, class SERVICE>
+class NOVTABLE waServiceBase : public waServiceFactoryBaseX<SERVICETYPE, SERVICE> {
+public:
+ waServiceBase(GUID myGuid = INVALID_GUID) : waServiceFactoryBaseX<SERVICETYPE, SERVICE>(myGuid) {}
+ virtual FOURCC svc_serviceType() { return SERVICE::getServiceType(); }
+ virtual void *svc_getInterface(int global_lock) { // new style, client optionally does the locking
+ SERVICETYPE *ret = getService();
+ if (global_lock) WASABI_API_SVC->service_lock(this, ret);
+ return ret;
+ }
+ virtual int svc_releaseInterface(void *ptr) {
+ return TRUE;
+ }
+protected:
+ virtual SERVICETYPE *getService()=0;
+};
+
+
+
+#endif // __WASERVICEFACTORYBASE_IMPL_H
diff --git a/Src/Wasabi/api/service/waservicefactoryi.cpp b/Src/Wasabi/api/service/waservicefactoryi.cpp
new file mode 100644
index 00000000..18ad97dd
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactoryi.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include <api/service/servicei.h>
diff --git a/Src/Wasabi/api/service/waservicefactoryi.h b/Src/Wasabi/api/service/waservicefactoryi.h
new file mode 100644
index 00000000..28d0b846
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactoryi.h
@@ -0,0 +1,73 @@
+#ifndef __WASERVICEFACTORY_IMPL_H
+#define __WASERVICEFACTORY_IMPL_H
+
+/*<?<autoheader/>*/
+#include "waservicefactory.h"
+#include "waservicefactoryx.h"
+
+class CfgItem;
+/*?>*/
+/*[interface.header.h]
+#include "common/nsguid.h"
+#include "studio/api.h"
+*/
+
+// this is a wasabi service factory. it's a static object you can query to
+// fetch the * to your real service interface
+class NOVTABLE waServiceFactoryI : public waServiceFactoryX {
+public:
+ virtual ~waServiceFactoryI() {}
+protected:
+/*[interface.x_getServiceType.h]
+ public:
+*/
+ DISPATCH(100) virtual FOURCC x_getServiceType() { return svc_serviceType(); } // see services.h
+ DISPATCH(200) virtual const char *x_getServiceName() { return svc_getServiceName(); }
+ DISPATCH(210) virtual GUID getGuid() { return svc_getGuid(); } // GUID per service factory, can be INVALID_GUID
+/**
+ Fetches a pointer to an instance of the service. Optionally locks it into the
+ global table, so that it can be safely released via service_release()
+ @see ComponentAPI::service_release()
+ @param global_lock If TRUE, calls service_lock() with the service *
+ @see releaseInterface()
+*/
+/*[dispatchable.getInterface.postcall]
+ // -- generated code - edit in waservicefactoryi.h
+ // support old code that always locks even when global_lock==FALSE
+ if (!global_lock && __retval != NULL && !supportNonLockingGetInterface())
+ WASABI_API_SVC->service_unlock(__retval);
+*/
+ DISPATCH(300) virtual void *getInterface(int global_lock = TRUE) { return svc_getInterface(global_lock); }
+ DISPATCH(300) virtual void *_RETIRED_getInterface() { return getInterface(); } // for back compat
+ DISPATCH(301) virtual int supportNonLockingGetInterface() { return svc_supportNonLockingGetInterface(); }
+
+/**
+ Releases a pointer to an instance of the service. Call this when you're done
+ with a service interface. Do NOT just call delete on it! Only the original
+ service factory can safely delete it. Also, do not pass in any pointers
+ that were not allocated from this factory.
+ @see getInterface()
+ @ret TRUE if no error, FALSE if error.
+*/
+ DISPATCH(310) virtual int releaseInterface(void *ifc) { return svc_releaseInterface(ifc); } // when they're done w/ it
+
+/**
+ Fetches a string for optional quick lookup of a service factory. This string
+ is defined on a service family type basis. e.g. the xuitag for xuicreators.
+*/
+ DISPATCH(500) virtual const wchar_t *getTestString() { return svc_getTestString(); }
+ DISPATCH(600) virtual int serviceNotify(int msg, int param1 = 0, int param2 = 0) { return svc_notify(msg, param1, param2); }
+public:
+
+ NODISPATCH virtual FOURCC svc_serviceType()=0; // see services.h
+ NODISPATCH virtual const char *svc_getServiceName()=0;
+ NODISPATCH virtual GUID svc_getGuid()=0; // GUID per service factory, can be INVALID_GUID
+ NODISPATCH virtual void *svc_getInterface(int global_lock = TRUE)=0;
+ NODISPATCH virtual int svc_supportNonLockingGetInterface() { return TRUE; }
+ NODISPATCH virtual int svc_releaseInterface(void *ifc)=0; // when they're done w/ it
+ NODISPATCH virtual CfgItem *svc_getCfgInterface()=0;
+ NODISPATCH virtual const wchar_t *svc_getTestString()=0;
+ NODISPATCH virtual int svc_notify(int msg, int param1 = 0, int param2 = 0)=0;
+};
+
+#endif // __WASERVICEFACTORY_IMPL_H
diff --git a/Src/Wasabi/api/service/waservicefactoryt.cpp b/Src/Wasabi/api/service/waservicefactoryt.cpp
new file mode 100644
index 00000000..fdab05e0
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactoryt.cpp
@@ -0,0 +1,5 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "waservicefactoryt.h"
+//?>
+
diff --git a/Src/Wasabi/api/service/waservicefactoryt.h b/Src/Wasabi/api/service/waservicefactoryt.h
new file mode 100644
index 00000000..f2cc6e67
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactoryt.h
@@ -0,0 +1,28 @@
+#ifndef __WASERVICEFACTORYT_IMPL_H
+#define __WASERVICEFACTORYT_IMPL_H
+
+/*<?<autoheader/>*/
+/*?>*/
+
+#include "waservicefactorybase.h"
+
+// this is a service factory template that will manufacture any number
+// of a given class SERVICE, which is derived from service class SERVICETYPE
+template <class SERVICETYPE, class SERVICE>
+class waServiceFactoryT : public waServiceFactoryBase<SERVICETYPE, SERVICE> {
+public:
+ waServiceFactoryT(GUID myGuid = INVALID_GUID) :
+ waServiceFactoryBase<SERVICETYPE, SERVICE>(myGuid) {}
+ virtual SERVICETYPE *newService() {
+ SERVICE *ret = new SERVICE;
+ ASSERT(ret != NULL);
+ return ret;
+ }
+ virtual int delService(SERVICETYPE *service) {
+ ASSERT(service != NULL);
+ delete static_cast<SERVICE*>(service);
+ return 1;
+ }
+};
+
+#endif // __WASERVICEFACTORYT_IMPL_H
diff --git a/Src/Wasabi/api/service/waservicefactorytsingle.cpp b/Src/Wasabi/api/service/waservicefactorytsingle.cpp
new file mode 100644
index 00000000..358de389
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactorytsingle.cpp
@@ -0,0 +1,5 @@
+#include <precomp.h>
+//<?#include "<class data="implementationheader"/>"
+#include "waservicefactorytsingle.h"
+//?>
+
diff --git a/Src/Wasabi/api/service/waservicefactorytsingle.h b/Src/Wasabi/api/service/waservicefactorytsingle.h
new file mode 100644
index 00000000..3a3a8d2f
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactorytsingle.h
@@ -0,0 +1,47 @@
+#ifndef __WASERVICEFACTORYTSINGLE_IMPL_H
+#define __WASERVICEFACTORYTSINGLE_IMPL_H
+
+/*<?<autoheader/>*/
+/*?>*/
+
+#include "waservicefactorybase.h"
+
+#include <bfc/bfc_assert.h>
+
+// this is a service factory template that holds one copy of a class
+// and reissues the pointer as needed, with reference counting
+template <class SERVICETYPE, class SERVICE>
+class waServiceFactoryTSingle : public waServiceFactoryBase<SERVICETYPE, SERVICE> {
+public:
+ waServiceFactoryTSingle(GUID myGuid = INVALID_GUID) :
+ refcount(0), waServiceFactoryBase<SERVICETYPE, SERVICE>(myGuid) {
+ singleService = new SERVICE;
+ }
+ waServiceFactoryTSingle(SERVICE *svc, GUID myGuid = INVALID_GUID) :
+ singleService(svc), refcount(0),
+ waServiceFactoryBase<SERVICETYPE, SERVICE>(myGuid) { }
+ ~waServiceFactoryTSingle() {
+ delete singleService;
+ }
+ virtual SERVICETYPE *newService() {
+ ASSERT(singleService != NULL);
+ refcount++;
+ return singleService;
+ }
+ virtual int delService(SERVICETYPE *service) {
+ ASSERT(static_cast<SERVICE*>(service) == singleService);
+ refcount--;
+ ASSERT(refcount >= 0);
+ return 1;
+ }
+
+ SERVICE *getSingleService() { return singleService; }
+
+private:
+ SERVICE * singleService;
+ int refcount;
+};
+
+
+
+#endif // __WASERVICEFACTORYTSINGLE_IMPL_H
diff --git a/Src/Wasabi/api/service/waservicefactoryx.cpp b/Src/Wasabi/api/service/waservicefactoryx.cpp
new file mode 100644
index 00000000..5853b833
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactoryx.cpp
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:57:16 2003]
+//
+// File : waservicefactoryx.cpp
+// Class : waServiceFactory
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "waservicefactoryx.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS waServiceFactoryX
+START_DISPATCH;
+ CB(WASERVICEFACTORY_GETSERVICETYPE, x_getServiceType);
+ CB(WASERVICEFACTORY_GETSERVICENAME, x_getServiceName);
+ CB(WASERVICEFACTORY_GETGUID, getGuid);
+ case WASERVICEFACTORY_GETINTERFACE:
+ switch (nparam) {
+ default: cb<CBCLASS>(&CBCLASS::getInterface, retval, params); break;
+ case 0: cb<CBCLASS>(&CBCLASS::_RETIRED_getInterface, retval, params); break;
+ }
+ break;
+ CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, supportNonLockingGetInterface);
+ CB(WASERVICEFACTORY_RELEASEINTERFACE, releaseInterface);
+ CB(WASERVICEFACTORY_GETTESTSTRING, getTestString);
+ CB(WASERVICEFACTORY_SERVICENOTIFY, serviceNotify);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/service/waservicefactoryx.h b/Src/Wasabi/api/service/waservicefactoryx.h
new file mode 100644
index 00000000..dd00a241
--- /dev/null
+++ b/Src/Wasabi/api/service/waservicefactoryx.h
@@ -0,0 +1,37 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:57:16 2003]
+//
+// File : waservicefactoryx.h
+// Class : waServiceFactory
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __WASERVICEFACTORYX_H
+#define __WASERVICEFACTORYX_H
+
+#include "waservicefactory.h"
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE waServiceFactoryX : public waServiceFactory {
+ protected:
+ waServiceFactoryX() {}
+ protected:
+
+ public:
+
+ virtual FOURCC x_getServiceType()=0;
+ virtual const char *x_getServiceName()=0;
+ virtual GUID getGuid()=0;
+ virtual void *getInterface(int global_lock = TRUE)=0;
+ virtual void *_RETIRED_getInterface()=0;
+ virtual int supportNonLockingGetInterface()=0;
+ virtual int releaseInterface(void *ifc)=0;
+ virtual const wchar_t *getTestString()=0;
+ virtual int serviceNotify(int msg, int param1 = 0, int param2 = 0)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __WASERVICEFACTORYX_H
diff --git a/Src/Wasabi/api/skin/SkinElementAlias.cpp b/Src/Wasabi/api/skin/SkinElementAlias.cpp
new file mode 100644
index 00000000..6c66d842
--- /dev/null
+++ b/Src/Wasabi/api/skin/SkinElementAlias.cpp
@@ -0,0 +1,8 @@
+#include <precomp.h>
+#include "SkinElementAlias.h"
+#include <api/skin/PaletteManager.h>
+
+SkinItem *SkinElementAlias::getAncestor()
+{
+ return paletteManager.getAliasAncestor(this);
+}
diff --git a/Src/Wasabi/api/skin/SkinElementAlias.h b/Src/Wasabi/api/skin/SkinElementAlias.h
new file mode 100644
index 00000000..1957825c
--- /dev/null
+++ b/Src/Wasabi/api/skin/SkinElementAlias.h
@@ -0,0 +1,65 @@
+#pragma once
+#include <api/skin/skinitem.h>
+#include <api/xml/xmlparamsi.h>
+struct SkinElementAlias : public SkinItemI
+{
+public:
+
+ SkinElementAlias(const wchar_t *_aliasname, const wchar_t *_idtarget, int _scriptid = -1, int _secondarycounter = 0)
+ : aliasname(_aliasname), idtarget(_idtarget), scriptid(_scriptid), seccount(_secondarycounter) //, rootpath(path)
+ {
+ params = NULL;
+ /*
+ if (p != NULL) {
+ params = new XmlReaderParamsI();
+ for (int i=0;i<p->getNbItems();i++) {
+ params->addItem(p->getItemName(i), p->getItemValue(i));
+ }
+ }
+ */
+ }
+ virtual ~SkinElementAlias()
+ {
+ delete params;
+ }
+
+ const wchar_t *getAliasName() { return aliasname; }
+ const wchar_t *getTargetId() { return idtarget; }
+ int getSecCount() { return seccount; }
+
+ virtual const wchar_t *getXmlRootPath() { return rootpath; }
+ virtual const wchar_t *getName() { return L"elementalias"; }
+ virtual ifc_xmlreaderparams *getParams() { return params; }
+ virtual int getSkinPartId() { return scriptid; }
+ virtual SkinItem *getAncestor();
+
+private:
+ StringW aliasname;
+ StringW idtarget;
+ int scriptid;
+ int seccount;
+ XmlReaderParamsI *params;
+ StringW rootpath;
+};
+
+class SortSkinElementAlias
+{
+public:
+ static int compareItem(SkinElementAlias *p1, SkinElementAlias *p2)
+ {
+ int r = WCSICMP(p1->getAliasName(), p2->getAliasName());
+ if (!r)
+ {
+ if (p1->getSkinPartId() < p2->getSkinPartId()) return -1;
+ if (p1->getSkinPartId() > p2->getSkinPartId()) return 1;
+ if (p1->getSecCount() < p2->getSecCount()) return -1;
+ if (p1->getSecCount() > p2->getSecCount()) return 1;
+ return 0;
+ }
+ return r;
+ }
+ static int compareAttrib(const wchar_t *attrib, SkinElementAlias *item)
+ {
+ return WCSICMP(attrib, item->getAliasName());
+ }
+}; \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/SkinVersion.cpp b/Src/Wasabi/api/skin/SkinVersion.cpp
new file mode 100644
index 00000000..ae112c49
--- /dev/null
+++ b/Src/Wasabi/api/skin/SkinVersion.cpp
@@ -0,0 +1,42 @@
+#include <precomp.h>
+#include "SkinVersion.h"
+#include "../xml/obj_xml.h"
+#include <api/service/waservicefactory.h>
+#include <bfc/string/StringW.h>
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+SkinVersionXmlReader::SkinVersionXmlReader(const wchar_t *skinname)
+{
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ parser->xmlreader_registerCallback(L"WinampAbstractionLayer", this);
+ parser->xmlreader_registerCallback(L"WasabiXML", this);
+ parser->xmlreader_open();
+
+ StringPathCombine fn(WASABI_API_SKIN->getSkinPath(), L"skin.xml");
+ LoadXmlFile(parser, fn);
+ parser->xmlreader_unregisterCallback(this);
+
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ }
+ }
+}
+
+void SkinVersionXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *version = params->getItemValue(L"version");
+ if (version)
+ walversion = version;
+}
+const wchar_t *SkinVersionXmlReader::getWalVersion()
+{
+ return walversion;
+}
diff --git a/Src/Wasabi/api/skin/SkinVersion.h b/Src/Wasabi/api/skin/SkinVersion.h
new file mode 100644
index 00000000..baaf46a1
--- /dev/null
+++ b/Src/Wasabi/api/skin/SkinVersion.h
@@ -0,0 +1,18 @@
+#ifndef NULLSOFT_WASABI_SKINVERSION_H
+#define NULLSOFT_WASABI_SKINVERSION_H
+
+#include "../xml/ifc_xmlreadercallbacki.h"
+#include <bfc/string/StringW.h>
+
+class ifc_xmlreaderparams;
+class SkinVersionXmlReader : public ifc_xmlreadercallbackI
+{
+public:
+ SkinVersionXmlReader(const wchar_t *skinname);
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ const wchar_t *getWalVersion();
+private:
+ StringW walversion;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/api_colorthemes.cpp b/Src/Wasabi/api/skin/api_colorthemes.cpp
new file mode 100644
index 00000000..f346774b
--- /dev/null
+++ b/Src/Wasabi/api/skin/api_colorthemes.cpp
@@ -0,0 +1,3 @@
+#include "api_colorthemes.h"
+
+/* benski> this file left intentionally blank */ \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/api_colorthemes.h b/Src/Wasabi/api/skin/api_colorthemes.h
new file mode 100644
index 00000000..b61c2eb2
--- /dev/null
+++ b/Src/Wasabi/api/skin/api_colorthemes.h
@@ -0,0 +1,161 @@
+#pragma once
+#include <bfc/dispatch.h>
+#include <api/skin/colorthemes.h>
+
+class api_colorthemes : public Dispatchable
+{
+protected:
+ api_colorthemes(){}
+ ~api_colorthemes(){}
+public:
+ /* Gamma Sets */
+ size_t getNumGammaSets();
+ const wchar_t *enumGammaSet(size_t n);
+ void deleteGammaSet(const wchar_t *set);
+ void deleteAllGammaSets();
+ void resetGammaSet(const wchar_t *set);
+ void renameGammaSet(const wchar_t *set, const wchar_t *newname);
+ size_t newGammaSet(const wchar_t *set); // returns index of your new gamma group
+ void updateGammaSet(const wchar_t *set);
+
+ /* Gamma Groups */
+ int getNumGammaGroups(const wchar_t *gammaset);
+ const wchar_t *enumGammaGroup(const wchar_t *gammaset, int n);
+ ColorThemeGroup *enumColorThemeGroup(int colorset, int colorgroup);
+ ColorThemeGroup *getColorThemeGroup(const wchar_t *colorset, const wchar_t *colorgroup);
+ int getGammaForGroup(const wchar_t *group, int *r, int *g, int *b, int *gray, int *boost);
+ void addGammaGroup(const wchar_t *set, ColorThemeGroup *group);
+ void addGammaGroup(size_t gammaSetIndex, ColorThemeGroup *group);
+
+ /* Active Gamma Set */
+ const wchar_t *getGammaSet();
+ void setGammaSet(const wchar_t *set);
+
+ /* Call these if you are loading a whole bunch of color themes at once */
+ void StartTransaction();
+ void EndTransaction();
+
+ enum
+ {
+ API_COLORTHEMES_GETNUMGAMMASETS = 0,
+ API_COLORTHEMES_ENUMGAMMASET = 1,
+ API_COLORTHEMES_DELETEGAMMASET = 2,
+ API_COLORTHEMES_DELETEALLGAMMASETS = 3,
+ API_COLORTHEMES_RESETGAMMASET = 4,
+ API_COLORTHEMES_RENAMEGAMMASET = 5,
+ API_COLORTHEMES_NEWGAMMASET = 6,
+ API_COLORTHEMES_UPDATEGAMMASET = 7,
+ API_COLORTHEMES_GETNUMGAMMAGROUPS = 8,
+ API_COLORTHEMES_ENUMGAMMAGROUP = 9,
+ API_COLORTHEMES_ENUMCOLORTHEMEGROUP = 10,
+ API_COLORTHEMES_GETCOLORTHEMEGROUP = 11,
+ API_COLORTHEMES_GETGAMMAFORGROUP = 12,
+ API_COLORTHEMES_ADDGAMMAGROUP = 13,
+ API_COLORTHEMES_ADDGAMMAGROUP2 = 14,
+ API_COLORTHEMES_GETGAMMASET = 15,
+ API_COLORTHEMES_SETGAMMASET = 16,
+ API_COLORTHEMES_STARTTRANSACTION = 17,
+ API_COLORTHEMES_ENDTRANSACTION = 18,
+ };
+};
+
+inline size_t api_colorthemes::getNumGammaSets()
+{
+ return _call(API_COLORTHEMES_GETNUMGAMMASETS, (size_t)0);
+}
+
+inline const wchar_t *api_colorthemes::enumGammaSet(size_t n)
+{
+ return _call(API_COLORTHEMES_ENUMGAMMASET, (const wchar_t *)0, n);
+}
+
+inline void api_colorthemes::deleteGammaSet(const wchar_t *set)
+{
+ _voidcall(API_COLORTHEMES_DELETEGAMMASET, set);
+}
+
+inline void api_colorthemes::deleteAllGammaSets()
+{
+ _voidcall(API_COLORTHEMES_DELETEALLGAMMASETS);
+}
+
+inline void api_colorthemes::resetGammaSet(const wchar_t *set)
+{
+ _voidcall(API_COLORTHEMES_RESETGAMMASET, set);
+}
+
+inline void api_colorthemes::renameGammaSet(const wchar_t *set, const wchar_t *newname)
+{
+ _voidcall(API_COLORTHEMES_RENAMEGAMMASET, set, newname);
+}
+
+inline size_t api_colorthemes::newGammaSet(const wchar_t *set)
+{
+ return _call(API_COLORTHEMES_NEWGAMMASET, (size_t)-1, set);
+}
+
+inline void api_colorthemes::updateGammaSet(const wchar_t *set)
+{
+ _voidcall(API_COLORTHEMES_UPDATEGAMMASET, set);
+}
+
+inline int api_colorthemes::getNumGammaGroups(const wchar_t *gammaset)
+{
+ return _call(API_COLORTHEMES_GETNUMGAMMAGROUPS, (int)0, gammaset);
+}
+
+inline const wchar_t *api_colorthemes::enumGammaGroup(const wchar_t *gammaset, int n)
+{
+ return _call(API_COLORTHEMES_ENUMGAMMAGROUP, (const wchar_t *)0, gammaset, n);
+}
+
+inline ColorThemeGroup *api_colorthemes::enumColorThemeGroup(int colorset, int colorgroup)
+{
+ return _call(API_COLORTHEMES_ENUMCOLORTHEMEGROUP, (ColorThemeGroup *)0, colorset, colorgroup);
+}
+
+inline ColorThemeGroup *api_colorthemes::getColorThemeGroup(const wchar_t *colorset, const wchar_t *colorgroup)
+{
+ return _call(API_COLORTHEMES_GETCOLORTHEMEGROUP, (ColorThemeGroup *)0, colorset, colorgroup);
+}
+
+inline int api_colorthemes::getGammaForGroup(const wchar_t *group, int *r, int *g, int *b, int *gray, int *boost)
+{
+ return _call(API_COLORTHEMES_GETGAMMAFORGROUP, (int)0, group, r, g, b, gray, boost);
+}
+
+inline void api_colorthemes::addGammaGroup(const wchar_t *set, ColorThemeGroup *group)
+{
+ _voidcall(API_COLORTHEMES_ADDGAMMAGROUP, set, group);
+}
+
+inline void api_colorthemes::addGammaGroup(size_t gammaSetIndex, ColorThemeGroup *group)
+{
+ _voidcall(API_COLORTHEMES_ADDGAMMAGROUP2, gammaSetIndex, group);
+}
+
+inline const wchar_t *api_colorthemes::getGammaSet()
+{
+ return _call(API_COLORTHEMES_GETGAMMASET, (const wchar_t *)0);
+}
+
+inline void api_colorthemes::setGammaSet(const wchar_t *set)
+{
+ _voidcall(API_COLORTHEMES_SETGAMMASET, set);
+}
+
+inline void api_colorthemes::StartTransaction()
+{
+ _voidcall(API_COLORTHEMES_STARTTRANSACTION);
+}
+
+inline void api_colorthemes::EndTransaction()
+{
+ _voidcall(API_COLORTHEMES_ENDTRANSACTION);
+}
+
+// {A3AAB98E-1634-4763-81A7-8D397F9E3154}
+static const GUID ColorThemesAPIGUID=
+{ 0xa3aab98e, 0x1634, 0x4763, { 0x81, 0xa7, 0x8d, 0x39, 0x7f, 0x9e, 0x31, 0x54 } };
+
+extern api_colorthemes *colorThemesApi;
diff --git a/Src/Wasabi/api/skin/api_palette.cpp b/Src/Wasabi/api/skin/api_palette.cpp
new file mode 100644
index 00000000..e02f8d42
--- /dev/null
+++ b/Src/Wasabi/api/skin/api_palette.cpp
@@ -0,0 +1 @@
+#include "api_palette.h"
diff --git a/Src/Wasabi/api/skin/api_palette.h b/Src/Wasabi/api/skin/api_palette.h
new file mode 100644
index 00000000..6f5361cc
--- /dev/null
+++ b/Src/Wasabi/api/skin/api_palette.h
@@ -0,0 +1,273 @@
+#pragma once
+#include <bfc/dispatch.h>
+#include <api/skin/skinitem.h>
+#include <api/skin/skin.h>
+#include <tataki/region/region.h>
+
+class api_palette : public Dispatchable
+{
+protected:
+ api_palette() {}
+ ~api_palette() {}
+public:
+ void StartTransaction(); // if you add a bunch of stuff at once, it's faster to call this at the beginning
+ void EndTransaction(); // and this at the end.
+
+ void Reset(); // clear everything
+
+ const int *getSkinPartIteratorPtr(); // call this to get a pointer that's faster to check than calling getSkinPartIterator via Dispatchable
+ int newSkinPart(); // call this before adding your elements, let's you easily remove just your stuff via UnloadElements
+ int getSkinPartIterator(); // if this value changes, then something in the skin palette has changed
+
+ void UnloadElements(int skinpart); // unload just your skin elements (get a skinpart value via newSkinPart)
+
+ /* Aliases */
+ void AddAlias(const wchar_t *id, const wchar_t *target);
+ const wchar_t *getElementAlias(const wchar_t *alias);
+ SkinItem *getAliasAncestor(SkinItem *item);
+
+ /* Colors */
+ void AddColor(const wchar_t *id, ARGB32 value, const wchar_t *colorgrp = NULL, const wchar_t *path = NULL, ifc_xmlreaderparams *p = NULL);
+ int getNumColorElements();
+ const wchar_t *enumColorElement(int n);
+ ARGB32 *getColorElementRef(const wchar_t *type, const wchar_t **grp = NULL);
+ SkinItem *getColorAncestor(SkinItem *item);
+ ARGB32 getColorElement(const wchar_t *type, const wchar_t **grp = NULL);
+
+ /* Cursors */
+ void AddCursor(const wchar_t *id, const wchar_t *bitmapid, int x, int y, const wchar_t *path = NULL, ifc_xmlreaderparams *params = NULL);
+ int getCursorElement(const wchar_t *id);
+ OSCURSOR getCursor(const wchar_t *id);
+ SkinItem *getCursorAncestor(SkinItem *item);
+ const wchar_t *getSkinCursorBitmapId(const wchar_t *cursor);
+
+ /* Bitmaps */
+ void AddBitmap(const wchar_t *id, const wchar_t *filename, const wchar_t *path, int x, int y, int w, int h, ifc_xmlreaderparams *params = NULL, const wchar_t *colorgroup = NULL);
+ int getBitmapElement(const wchar_t *type);
+ SkinItem *getBitmapAncestor(SkinItem *item);
+ int getNumBitmapElement();
+ const wchar_t *getSkinBitmapFilename(const wchar_t *id, int *x, int *y, int *w, int *h, const wchar_t **rootpath, ifc_xmlreaderparams **params);
+ const wchar_t *getGammaGroupFromId(const wchar_t *id);
+ int getLayerFromId(const wchar_t *id);
+
+ /* Region Server (part of Bitmaps) */
+ RegionServer *requestSkinRegion(const wchar_t *id);
+ void cacheSkinRegion(const wchar_t *id, api_region *r);
+
+ enum
+ {
+ API_PALETTE_STARTTRANSACTION=0,
+ API_PALETTE_ENDTRANSACTION=1,
+ API_PALETTE_RESET=2,
+ API_PALETTE_GETSKINPARTITERATORPTR=3,
+ API_PALETTE_NEWSKINPART=4,
+ API_PALETTE_GETSKINPARTITERATOR=5,
+ API_PALETTE_UNLOADELEMENTS=6,
+ API_PALETTE_ADDALIAS=7,
+ API_PALETTE_GETELEMENTALIAS=8,
+ API_PALETTE_GETALIASANCESTOR=9,
+ API_PALETTE_ADDCOLOR=10,
+ API_PALETTE_GETNUMCOLORELEMENTS=11,
+ API_PALETTE_ENUMCOLORELEMENT=12,
+ API_PALETTE_GETCOLORELEMENTREF=13,
+ API_PALETTE_GETCOLORANCESTOR=14,
+ API_PALETTE_GETCOLORELEMENT=15,
+ API_PALETTE_ADDCURSOR=16,
+ API_PALETTE_GETCURSORELEMENT=17,
+ API_PALETTE_GETCURSOR=18,
+ API_PALETTE_GETCURSORANCESTOR=19,
+ API_PALETTE_GETSKINCURSORBITMAPID=20,
+ API_PALETTE_ADDBITMAP=21,
+ API_PALETTE_GETBITMAPELEMENT=22,
+ API_PALETTE_GETBITMAPANCESTOR=23,
+ API_PALETTE_GETNUMBITMAPELEMENT=24,
+ API_PALETTE_GETSKINBITMAPFILENAME=25,
+ API_PALETTE_GETGAMMAGROUPFROMID=26,
+ API_PALETTE_GETLAYERFROMID=27,
+ API_PALETTE_REQUESTSKINREGION=28,
+ API_PALETTE_CACHESKINREGION=29,
+ };
+};
+
+inline void api_palette::StartTransaction()
+{
+ _voidcall(API_PALETTE_STARTTRANSACTION);
+}
+
+
+inline void api_palette::EndTransaction()
+{
+ _voidcall(API_PALETTE_ENDTRANSACTION);
+}
+
+
+inline void api_palette::Reset()
+{
+ _voidcall(API_PALETTE_RESET);
+}
+
+
+inline const int *api_palette::getSkinPartIteratorPtr()
+{
+ return _call(API_PALETTE_GETSKINPARTITERATORPTR, (const int *)0);
+}
+
+
+inline int api_palette::newSkinPart()
+{
+ return _call(API_PALETTE_NEWSKINPART, (int)0);
+}
+
+
+inline int api_palette::getSkinPartIterator()
+{
+ return _call(API_PALETTE_GETSKINPARTITERATOR, (int)0);
+}
+
+
+inline void api_palette::UnloadElements(int skinpart)
+{
+ _voidcall(API_PALETTE_UNLOADELEMENTS, skinpart);
+}
+
+
+inline void api_palette::AddAlias(const wchar_t *id, const wchar_t *target)
+{
+ _voidcall(API_PALETTE_ADDALIAS, id, target);
+}
+
+
+inline const wchar_t *api_palette::getElementAlias(const wchar_t *alias)
+{
+ return _call(API_PALETTE_GETELEMENTALIAS, (const wchar_t *)0, alias);
+}
+
+
+inline SkinItem *api_palette::getAliasAncestor(SkinItem *item)
+{
+ return _call(API_PALETTE_GETALIASANCESTOR, (SkinItem *)0, item);
+}
+
+
+inline void api_palette::AddColor(const wchar_t *id, ARGB32 value, const wchar_t *colorgrp, const wchar_t *path, ifc_xmlreaderparams *p)
+{
+ _voidcall(API_PALETTE_ADDCOLOR, id, value, colorgrp, path, p);
+}
+
+
+inline int api_palette::getNumColorElements()
+{
+ return _call(API_PALETTE_GETNUMCOLORELEMENTS, (int)0);
+}
+
+
+inline const wchar_t *api_palette::enumColorElement(int n)
+{
+ return _call(API_PALETTE_ENUMCOLORELEMENT, (const wchar_t *)0, n);
+}
+
+
+inline ARGB32 *api_palette::getColorElementRef(const wchar_t *type, const wchar_t **grp)
+{
+ return _call(API_PALETTE_GETCOLORELEMENTREF, (ARGB32 *)0, type, grp);
+}
+
+
+inline SkinItem *api_palette::getColorAncestor(SkinItem *item)
+{
+ return _call(API_PALETTE_GETCOLORANCESTOR, (SkinItem *)0, item);
+}
+
+
+inline ARGB32 api_palette::getColorElement(const wchar_t *type, const wchar_t **grp)
+{
+ return _call(API_PALETTE_GETCOLORELEMENT, (ARGB32)RGB(255, 0, 255), type, grp);
+}
+
+
+inline void api_palette::AddCursor(const wchar_t *id, const wchar_t *bitmapid, int x, int y, const wchar_t *path, ifc_xmlreaderparams *params)
+{
+ _voidcall(API_PALETTE_ADDCURSOR, id, bitmapid, x, y, path, params);
+}
+
+
+inline int api_palette::getCursorElement(const wchar_t *id)
+{
+ return _call(API_PALETTE_GETCURSORELEMENT, (int)-1, id);
+}
+
+
+inline OSCURSOR api_palette::getCursor(const wchar_t *id)
+{
+ return _call(API_PALETTE_GETCURSOR, INVALIDOSCURSORHANDLE, id);
+}
+
+
+inline SkinItem *api_palette::getCursorAncestor(SkinItem *item)
+{
+ return _call(API_PALETTE_GETCURSORANCESTOR, (SkinItem *)0, item);
+}
+
+
+inline const wchar_t *api_palette::getSkinCursorBitmapId(const wchar_t *cursor)
+{
+ return _call(API_PALETTE_GETSKINCURSORBITMAPID, (const wchar_t *)0, cursor);
+}
+
+
+inline void api_palette::AddBitmap(const wchar_t *id, const wchar_t *filename, const wchar_t *path, int x, int y, int w, int h, ifc_xmlreaderparams *params, const wchar_t *colorgroup)
+{
+ _voidcall(API_PALETTE_ADDBITMAP, id, filename, path, x, y, w, h, params, colorgroup);
+}
+
+
+inline int api_palette::getBitmapElement(const wchar_t *type)
+{
+ return _call(API_PALETTE_GETBITMAPELEMENT, (int)-1, type);
+}
+
+
+inline SkinItem *api_palette::getBitmapAncestor(SkinItem *item)
+{
+ return _call(API_PALETTE_GETBITMAPANCESTOR, (SkinItem *)0, item);
+}
+
+
+inline int api_palette::getNumBitmapElement()
+{
+ return _call(API_PALETTE_GETNUMBITMAPELEMENT, (int)0);
+}
+
+
+inline const wchar_t *api_palette::getSkinBitmapFilename(const wchar_t *id, int *x, int *y, int *w, int *h, const wchar_t **rootpath, ifc_xmlreaderparams **params)
+{
+ return _call(API_PALETTE_GETSKINBITMAPFILENAME, (const wchar_t *)0,id,x,y,w,h,rootpath, params);
+}
+
+
+inline const wchar_t *api_palette::getGammaGroupFromId(const wchar_t *id)
+{
+ return _call(API_PALETTE_GETGAMMAGROUPFROMID, (const wchar_t *)0, id);
+}
+
+
+inline int api_palette::getLayerFromId(const wchar_t *id)
+{
+ return _call(API_PALETTE_GETLAYERFROMID, (int)-1, id);
+}
+
+
+inline RegionServer *api_palette::requestSkinRegion(const wchar_t *id)
+{
+ return _call(API_PALETTE_REQUESTSKINREGION, (RegionServer *)0, id);
+}
+
+
+inline void api_palette::cacheSkinRegion(const wchar_t *id, api_region *r)
+{
+ _voidcall(API_PALETTE_CACHESKINREGION, id, r);
+}
+
+// {DCA2E3C2-4C3E-4dd9-AB1A-1940F2CA31F7}
+static const GUID PaletteManagerGUID =
+{ 0xdca2e3c2, 0x4c3e, 0x4dd9, { 0xab, 0x1a, 0x19, 0x40, 0xf2, 0xca, 0x31, 0xf7 } };
diff --git a/Src/Wasabi/api/skin/api_skin.cpp b/Src/Wasabi/api/skin/api_skin.cpp
new file mode 100644
index 00000000..ca441ede
--- /dev/null
+++ b/Src/Wasabi/api/skin/api_skin.cpp
@@ -0,0 +1,63 @@
+#include <precomp.h>
+#include "api_skin.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS api_skinI
+START_DISPATCH;
+ CB(API_SKIN_SKIN_GETCOLORELEMENT, skin_getColorElement);
+ CB(API_SKIN_SKIN_GETCOLORELEMENTREF, skin_getColorElementRef);
+ CB(API_SKIN_SKIN_GETITERATOR, skin_getIterator);
+ VCB(API_SKIN_SKIN_SWITCHSKIN, skin_switchSkin);
+ VCB(API_SKIN_SKIN_UNLOADSKIN, skin_unloadSkin);
+ CB(API_SKIN_GETSKINNAME, getSkinName);
+ CB(API_SKIN_GETSKINPATH, getSkinPath);
+ CB(API_SKIN_GETSKINSPATH, getSkinsPath);
+ CB(API_SKIN_GETDEFAULTSKINPATH, getDefaultSkinPath);
+ CB(API_SKIN_IMGLDR_REQUESTSKINBITMAP, imgldr_requestSkinBitmap);
+ VCB(API_SKIN_IMGLDR_RELEASESKINBITMAP, imgldr_releaseSkinBitmap);
+ CB(API_SKIN_FILTERSKINCOLOR, filterSkinColor);
+ VCB(API_SKIN_REAPPLYSKINFILTERS, reapplySkinFilters);
+ CB(API_SKIN_COLORTHEME_GETNUMCOLORSETS, colortheme_getNumColorSets);
+ CB(API_SKIN_COLORTHEME_ENUMCOLORSET, colortheme_enumColorSet);
+ CB(API_SKIN_COLORTHEME_GETNUMCOLORGROUPS, colortheme_getNumColorGroups);
+ CB(API_SKIN_COLORTHEME_ENUMCOLORGROUPNAME, colortheme_enumColorGroupName);
+ CB(API_SKIN_COLORTHEME_ENUMCOLORGROUP, colortheme_enumColorGroup);
+ CB(API_SKIN_COLORTHEME_GETCOLORGROUP, colortheme_getColorGroup);
+ VCB(API_SKIN_COLORTHEME_SETCOLORSET, colortheme_setColorSet);
+ CB(API_SKIN_COLORTHEME_GETCOLORSET, colortheme_getColorSet);
+ VCB(API_SKIN_COLORTHEME_NEWCOLORSET, colortheme_newColorSet);
+ VCB(API_SKIN_COLORTHEME_UPDATECOLORSET, colortheme_updateColorSet);
+ VCB(API_SKIN_COLORTHEME_RENAMESET, colortheme_renameColorSet);
+ VCB(API_SKIN_COLORTHEME_DELETE, colortheme_deleteColorSet);
+ CB(API_SKIN_LOADSKINFILE, loadSkinFile);
+ CB(API_SKIN_LOADGROUPDEFDATA, loadGroupDefData);
+ VCB(API_SKIN_UNLOADSKINPART, unloadSkinPart);
+ CB(API_SKIN_GROUP_CREATE, group_create);
+#ifdef WASABI_COMPILE_CONFIG
+ CB(API_SKIN_GROUP_CREATE_CFG, group_create_cfg);
+#endif // WASABI_COMPILE_CONFIG
+#ifdef WASABI_COMPILE_WNDMGR
+ CB(API_SKIN_GROUP_CREATE_LAYOUT, group_create_layout);
+#endif //WASABI_COMPILE_WNDMGR
+ CB(API_SKIN_GROUP_DESTROY, group_destroy);
+ CB(API_SKIN_GROUP_EXISTS, group_exists);
+ CB(API_SKIN_PARSE, parse);
+ CB(API_SKIN_XUI_NEW, xui_new);
+ VCB(API_SKIN_XUI_DELETE, xui_delete);
+ CB(API_SKIN_CURSOR_REQUEST, cursor_request);
+ CB(API_SKIN_GETNUMGROUPS, getNumGroupDefs);
+ CB(API_SKIN_ENUMGROUP, enumGroupDef);
+ CB(API_SKIN_GROUP_CREATEBYITEM, group_createBySkinItem);
+ CB(API_SKIN_GETGROUPANCESTOR, getGroupDefAncestor);
+ CB(API_SKIN_GROUPDEF_GETNUMOBJECTS, groupdef_getNumObjects);
+ CB(API_SKIN_GROUPDEF_ENUMOBJECT, groupdef_enumObject);
+ VCB(API_SKIN_SETLOCKUI, skin_setLockUI);
+ CB(API_SKIN_GETLOCKUI, skin_getLockUI);
+ CB(API_SKIN_GETVERSION, skin_getVersion);
+#ifdef WASABI_COMPILE_IMGLDR
+ CB(API_SKIN_GETBITMAPCOLOR, skin_getBitmapColor);
+#endif
+ CB(API_SKIN_ISLOADED, skin_isLoaded);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/skin/api_skin.h b/Src/Wasabi/api/skin/api_skin.h
new file mode 100644
index 00000000..136712e9
--- /dev/null
+++ b/Src/Wasabi/api/skin/api_skin.h
@@ -0,0 +1,429 @@
+#ifndef __API_SKIN_H
+#define __API_SKIN_H
+
+#include <wasabicfg.h>
+#include <bfc/dispatch.h>
+
+class ifc_window;
+class GuiObject;
+class ColorThemeGroup;
+class ifc_xmlreaderparams;
+class SkinItem;
+
+#ifdef WASABI_COMPILE_CONFIG
+class CfgItem;
+#endif //WASABI_COMPILE_CONFIG
+
+#ifdef WASABI_COMPILE_WNDMGR
+class CfgItem;
+#endif //WASABI_COMPILE_WNDMGR
+
+#ifdef _WIN32
+#ifndef OSCURSOR
+#define OSCURSOR HICON
+#endif
+#elif defined(__APPLE__)
+#define OSCURSOR CGImageRef
+#endif
+
+class NOVTABLE api_skin : public Dispatchable
+{
+ public:
+ // skin colors
+ ARGB32 skin_getColorElement(const wchar_t *type, const wchar_t **color_group = NULL);
+ const ARGB32 *skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group = NULL);
+ const int *skin_getIterator();
+
+ // possibly make a svc_skinloader
+ void skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path=NULL);
+ void skin_unloadSkin();
+ int loadSkinFile(const wchar_t *xmlfile);
+ int loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem);
+ void unloadSkinPart(int skinpartid);
+ const wchar_t *getSkinName();
+ const wchar_t *getSkinPath();
+ const wchar_t *getSkinsPath();
+ const wchar_t *getDefaultSkinPath();
+
+ // skin bitmaps
+ ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached);
+ void imgldr_releaseSkinBitmap(ARGB32 *bmpbits);
+#ifdef WASABI_COMPILE_IMGLDR
+ ARGB32 skin_getBitmapColor(const wchar_t *bitmapid);
+#endif
+
+ // skin filters
+ ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname);
+ void reapplySkinFilters();
+ int colortheme_getNumColorSets();
+ const wchar_t *colortheme_enumColorSet(int n);
+ int colortheme_getNumColorGroups(const wchar_t *colorset);
+ const wchar_t *colortheme_enumColorGroupName(const wchar_t *colorset, int n);
+ ColorThemeGroup *colortheme_enumColorGroup(int colorset, int n);
+ ColorThemeGroup *colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *colorgroup);
+ void colortheme_setColorSet(const wchar_t *colorset);
+ const wchar_t *colortheme_getColorSet();
+ void colortheme_newColorSet(const wchar_t *set);
+ void colortheme_updateColorSet(const wchar_t *set);
+ void colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname);
+ void colortheme_deleteColorSet(const wchar_t *set);
+
+ // groups
+ ifc_window *group_create(const wchar_t *groupid, int scripts_enabled=1);
+ int group_exists(const wchar_t *groupid);
+#ifdef WASABI_COMPILE_CONFIG
+ ifc_window *group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled=1);
+#endif // WASABI_COMPILE_CONFIG
+#ifdef WASABI_COMPILE_WNDMGR
+ ifc_window *group_create_layout(const wchar_t *groupid, int scripts_enabled=1);
+#endif //WASABI_COMPILE_WNDMGR
+ int group_destroy(ifc_window *group);
+
+ int parse(const wchar_t *str, const wchar_t *how);
+ GuiObject *xui_new(const wchar_t *classname);
+ void xui_delete(GuiObject *o);
+ OSCURSOR cursor_request(const wchar_t *id);
+ int getNumGroupDefs();
+ SkinItem *enumGroupDef(int n);
+ ifc_window *group_createBySkinItem(SkinItem *groupitem, int scripts_enabled=1);
+ SkinItem *getGroupDefAncestor(SkinItem *groupitem);
+ int groupdef_getNumObjects(SkinItem *groupitem);
+ SkinItem *groupdef_enumObject(SkinItem *item, int n);
+ void skin_setLockUI(int l);
+ int skin_getLockUI();
+ double skin_getVersion();
+ bool skin_isLoaded();
+
+
+ enum {
+ API_SKIN_SKIN_GETCOLORELEMENT = 0,
+ API_SKIN_SKIN_GETCOLORELEMENTREF = 10,
+ API_SKIN_SKIN_GETITERATOR = 20,
+ API_SKIN_SKIN_SWITCHSKIN = 30,
+ API_SKIN_SKIN_UNLOADSKIN = 35,
+ API_SKIN_GETSKINNAME = 40,
+ API_SKIN_GETSKINPATH = 50,
+ API_SKIN_GETSKINSPATH = 60,
+ API_SKIN_GETDEFAULTSKINPATH = 70,
+ API_SKIN_IMGLDR_REQUESTSKINBITMAP = 80,
+ API_SKIN_IMGLDR_RELEASESKINBITMAP = 90,
+ API_SKIN_FILTERSKINCOLOR = 100,
+ API_SKIN_REAPPLYSKINFILTERS = 110,
+ API_SKIN_COLORTHEME_GETNUMCOLORSETS = 120,
+ API_SKIN_COLORTHEME_ENUMCOLORSET = 130,
+ API_SKIN_COLORTHEME_GETNUMCOLORGROUPS = 140,
+ API_SKIN_COLORTHEME_ENUMCOLORGROUPNAME = 150,
+ API_SKIN_COLORTHEME_ENUMCOLORGROUP = 160,
+ API_SKIN_COLORTHEME_GETCOLORGROUP = 165,
+ API_SKIN_COLORTHEME_SETCOLORSET = 170,
+ API_SKIN_COLORTHEME_GETCOLORSET = 180,
+ API_SKIN_COLORTHEME_NEWCOLORSET = 190,
+ API_SKIN_COLORTHEME_RENAMESET = 191,
+ API_SKIN_COLORTHEME_DELETE = 192,
+ API_SKIN_COLORTHEME_UPDATECOLORSET = 193,
+ API_SKIN_LOADSKINFILE = 200,
+ API_SKIN_UNLOADSKINPART = 210,
+ API_SKIN_GROUP_CREATE = 220,
+ API_SKIN_GROUP_EXISTS = 225,
+#ifdef WASABI_COMPILE_CONFIG
+ API_SKIN_GROUP_CREATE_CFG = 230,
+#endif // WASABI_COMPILE_CONFIG
+#ifdef WASABI_COMPILE_WNDMGR
+ API_SKIN_GROUP_CREATE_LAYOUT = 240,
+#endif //WASABI_COMPILE_WNDMGR
+ API_SKIN_GROUP_DESTROY = 250,
+ API_SKIN_PARSE = 260,
+ API_SKIN_XUI_NEW = 270,
+ API_SKIN_XUI_DELETE = 280,
+ API_SKIN_CURSOR_REQUEST = 290,
+ API_SKIN_GETNUMGROUPS = 300,
+ API_SKIN_ENUMGROUP = 310,
+ API_SKIN_GROUP_CREATEBYITEM = 320,
+ API_SKIN_GETGROUPANCESTOR = 330,
+ API_SKIN_GROUPDEF_GETNUMOBJECTS = 340,
+ API_SKIN_GROUPDEF_ENUMOBJECT = 350,
+ API_SKIN_LOADGROUPDEFDATA = 360,
+ API_SKIN_SETLOCKUI = 370,
+ API_SKIN_GETLOCKUI = 380,
+ API_SKIN_GETVERSION = 390,
+ API_SKIN_GETBITMAPCOLOR = 400,
+ API_SKIN_ISLOADED = 410,
+ };
+};
+
+inline ARGB32 api_skin::skin_getColorElement(const wchar_t *type, const wchar_t **color_group) {
+ return _call(API_SKIN_SKIN_GETCOLORELEMENT, (ARGB32)NULL, type, color_group);
+}
+
+inline const ARGB32 *api_skin::skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group) {
+ return _call(API_SKIN_SKIN_GETCOLORELEMENTREF, (ARGB32 *)NULL, type, color_group);
+}
+
+inline const int *api_skin::skin_getIterator() {
+ return _call(API_SKIN_SKIN_GETITERATOR, (const int *)0);
+}
+
+inline void api_skin::skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path) {
+ _voidcall(API_SKIN_SKIN_SWITCHSKIN, skin_name, skin_path);
+}
+
+inline void api_skin::skin_unloadSkin() {
+ _voidcall(API_SKIN_SKIN_UNLOADSKIN);
+}
+
+inline const wchar_t *api_skin::getSkinName() {
+ return _call(API_SKIN_GETSKINNAME, (const wchar_t *)0);
+}
+
+inline const wchar_t *api_skin::getSkinPath() {
+ return _call(API_SKIN_GETSKINPATH, (const wchar_t *)0);
+}
+
+inline const wchar_t *api_skin::getSkinsPath() {
+ return _call(API_SKIN_GETSKINSPATH, (const wchar_t *)0);
+}
+
+inline const wchar_t *api_skin::getDefaultSkinPath() {
+ return _call(API_SKIN_GETDEFAULTSKINPATH, (const wchar_t *)0);
+}
+
+inline ARGB32 *api_skin::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) {
+ return _call(API_SKIN_IMGLDR_REQUESTSKINBITMAP, (ARGB32 *)NULL, file, has_alpha, x, y, subw, subh, w, h, cached);
+}
+
+inline void api_skin::imgldr_releaseSkinBitmap(ARGB32 *bmpbits) {
+ _voidcall(API_SKIN_IMGLDR_RELEASESKINBITMAP, bmpbits);
+}
+
+inline ARGB32 api_skin::filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname) {
+ return _call(API_SKIN_FILTERSKINCOLOR, (ARGB32)NULL, color, elementid, groupname);
+}
+
+inline void api_skin::reapplySkinFilters() {
+ _voidcall(API_SKIN_REAPPLYSKINFILTERS);
+}
+
+inline int api_skin::colortheme_getNumColorSets() {
+ return _call(API_SKIN_COLORTHEME_GETNUMCOLORSETS, (int)0);
+}
+
+inline const wchar_t *api_skin::colortheme_enumColorSet(int n) {
+ return _call(API_SKIN_COLORTHEME_ENUMCOLORSET, (const wchar_t *)0, n);
+}
+
+inline int api_skin::colortheme_getNumColorGroups(const wchar_t *colorset) {
+ return _call(API_SKIN_COLORTHEME_GETNUMCOLORGROUPS, (int)0, colorset);
+}
+
+inline const wchar_t *api_skin::colortheme_enumColorGroupName(const wchar_t *colorset, int n) {
+ return _call(API_SKIN_COLORTHEME_ENUMCOLORGROUPNAME, (const wchar_t *)0, colorset, n);
+}
+
+inline ColorThemeGroup *api_skin::colortheme_enumColorGroup(int colorset, int n) {
+ return _call(API_SKIN_COLORTHEME_ENUMCOLORGROUP, (ColorThemeGroup *)NULL, colorset, n);
+}
+
+inline ColorThemeGroup *api_skin::colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *group) {
+ return _call(API_SKIN_COLORTHEME_GETCOLORGROUP, (ColorThemeGroup *)NULL, colorset, group);
+}
+
+inline void api_skin::colortheme_setColorSet(const wchar_t *colorset)
+{
+ _voidcall(API_SKIN_COLORTHEME_SETCOLORSET, colorset);
+}
+
+inline const wchar_t *api_skin::colortheme_getColorSet()
+{
+ return _call(API_SKIN_COLORTHEME_GETCOLORSET, (const wchar_t *)0);
+}
+
+inline void api_skin::colortheme_newColorSet(const wchar_t *set) {
+ _voidcall(API_SKIN_COLORTHEME_NEWCOLORSET, set);
+}
+
+inline void api_skin::colortheme_updateColorSet(const wchar_t *set) {
+ _voidcall(API_SKIN_COLORTHEME_UPDATECOLORSET, set);
+}
+
+inline void api_skin::colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname) {
+ _voidcall(API_SKIN_COLORTHEME_RENAMESET, set, newname);
+}
+
+inline void api_skin::colortheme_deleteColorSet(const wchar_t *set) {
+ _voidcall(API_SKIN_COLORTHEME_DELETE, set);
+}
+
+
+inline int api_skin::loadSkinFile(const wchar_t *xmlfile) {
+ return _call(API_SKIN_LOADSKINFILE, (int)0, xmlfile);
+}
+
+inline void api_skin::unloadSkinPart(int skinpartid) {
+ _voidcall(API_SKIN_UNLOADSKINPART, skinpartid);
+}
+
+inline ifc_window *api_skin::group_create(const wchar_t *groupid, int scripts_enabled) {
+ return _call(API_SKIN_GROUP_CREATE, (ifc_window *)NULL, groupid, scripts_enabled);
+}
+
+inline int api_skin::group_exists(const wchar_t *groupid) {
+ return _call(API_SKIN_GROUP_EXISTS, 1, groupid);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+inline ifc_window *api_skin::group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled) {
+ return _call(API_SKIN_GROUP_CREATE_CFG, (ifc_window *)NULL, groupid, cfgitem, attributename, scripts_enabled);
+}
+#endif // WASABI_COMPILE_CONFIG
+
+#ifdef WASABI_COMPILE_WNDMGR
+inline ifc_window *api_skin::group_create_layout(const wchar_t *groupid, int scripts_enabled) {
+ return _call(API_SKIN_GROUP_CREATE_LAYOUT, (ifc_window *)NULL, groupid, scripts_enabled);
+}
+#endif //WASABI_COMPILE_WNDMGR
+
+inline int api_skin::group_destroy(ifc_window *group) {
+ return _call(API_SKIN_GROUP_DESTROY, (int)0, group);
+}
+
+inline int api_skin::parse(const wchar_t *str, const wchar_t *how) {
+ return _call(API_SKIN_PARSE, (int)0, str, how);
+}
+
+inline GuiObject *api_skin::xui_new(const wchar_t *classname) {
+ return _call(API_SKIN_XUI_NEW, (GuiObject *)NULL, classname);
+}
+
+inline void api_skin::xui_delete(GuiObject *o) {
+ _voidcall(API_SKIN_XUI_DELETE, o);
+}
+
+inline OSCURSOR api_skin::cursor_request(const wchar_t *id)
+{
+ return _call(API_SKIN_CURSOR_REQUEST, (OSCURSOR)NULL, id);
+}
+
+inline int api_skin::getNumGroupDefs() {
+ return _call(API_SKIN_GETNUMGROUPS, (int)0);
+}
+
+inline SkinItem *api_skin::enumGroupDef(int n) {
+ return _call(API_SKIN_ENUMGROUP, (SkinItem *)NULL, n);
+}
+
+inline ifc_window *api_skin::group_createBySkinItem(SkinItem *item, int scripts_enabled) {
+ return _call(API_SKIN_GROUP_CREATEBYITEM, (ifc_window *)NULL, item, scripts_enabled);
+}
+
+inline SkinItem *api_skin::getGroupDefAncestor(SkinItem *item) {
+ return _call(API_SKIN_GETGROUPANCESTOR, (SkinItem *)NULL, item);
+}
+
+inline int api_skin::groupdef_getNumObjects(SkinItem *groupitem) {
+ return _call(API_SKIN_GROUPDEF_GETNUMOBJECTS, 0, groupitem);
+}
+
+inline SkinItem *api_skin::groupdef_enumObject(SkinItem *item, int n) {
+ return _call(API_SKIN_GROUPDEF_ENUMOBJECT, (SkinItem *)NULL, item, n);
+}
+
+inline int api_skin::loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem) {
+ return _call(API_SKIN_LOADGROUPDEFDATA, -1, groupdef, lastgroupitem);
+}
+
+inline void api_skin::skin_setLockUI(int l) {
+ _voidcall(API_SKIN_SETLOCKUI, l);
+}
+
+inline int api_skin::skin_getLockUI() {
+ return _call(API_SKIN_GETLOCKUI, 0);
+}
+
+inline double api_skin::skin_getVersion() {
+ return _call(API_SKIN_GETVERSION, 0.8);
+}
+
+#ifdef WASABI_COMPILE_IMGLDR
+inline ARGB32 api_skin::skin_getBitmapColor(const wchar_t *bitmapid) {
+ return _call(API_SKIN_GETBITMAPCOLOR, 0xFFFF00FF, bitmapid);
+}
+#endif
+
+inline bool api_skin::skin_isLoaded()
+{
+ return _call(API_SKIN_ISLOADED, false);
+}
+
+class api_skinI : public api_skin
+{
+ protected:
+ api_skinI() {}
+ virtual ~api_skinI() {}
+
+ public:
+ virtual ARGB32 skin_getColorElement(const wchar_t *type, const wchar_t **color_group = NULL)=0;
+ virtual const ARGB32 *skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group = NULL)=0;
+ virtual const int *skin_getIterator()=0;
+ virtual void skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path=NULL)=0;
+ virtual void skin_unloadSkin()=0;
+ virtual const wchar_t *getSkinName()=0;
+ virtual const wchar_t *getSkinPath()=0;
+ virtual const wchar_t *getSkinsPath()=0;
+ virtual const wchar_t *getDefaultSkinPath()=0;
+ virtual ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached)=0;
+ virtual void imgldr_releaseSkinBitmap(ARGB32 *bmpbits)=0;
+ virtual ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname)=0;
+ virtual void reapplySkinFilters()=0;
+ virtual int colortheme_getNumColorSets()=0;
+ virtual const wchar_t *colortheme_enumColorSet(int n)=0;
+ virtual int colortheme_getNumColorGroups(const wchar_t *colorset)=0;
+ virtual const wchar_t *colortheme_enumColorGroupName(const wchar_t *colorset, int n)=0;
+ virtual ColorThemeGroup *colortheme_enumColorGroup(int colorset, int n)=0;
+ virtual ColorThemeGroup *colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *group)=0;
+ virtual void colortheme_setColorSet(const wchar_t *colorset)=0;
+ virtual const wchar_t *colortheme_getColorSet()=0;
+ virtual void colortheme_newColorSet(const wchar_t *set)=0;
+ virtual void colortheme_updateColorSet(const wchar_t *set)=0;
+ virtual void colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname)=0;
+ virtual void colortheme_deleteColorSet(const wchar_t *set)=0;
+ virtual int loadSkinFile(const wchar_t *xmlfile)=0;
+ virtual int loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem)=0;
+ virtual void unloadSkinPart(int skinpartid)=0;
+ virtual ifc_window *group_create(const wchar_t *groupid, int scripts_enabled=1)=0;
+ virtual int group_exists(const wchar_t *groupid)=0;
+#ifdef WASABI_COMPILE_CONFIG
+ virtual ifc_window *group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled=1)=0;
+#endif // WASABI_COMPILE_CONFIG
+#ifdef WASABI_COMPILE_WNDMGR
+ virtual ifc_window *group_create_layout(const wchar_t *groupid, int scripts_enabled=1)=0;
+#endif //WASABI_COMPILE_WNDMGR
+ virtual int group_destroy(ifc_window *group)=0;
+ virtual int parse(const wchar_t *str, const wchar_t *how)=0;
+ virtual GuiObject *xui_new(const wchar_t *classname)=0;
+ virtual void xui_delete(GuiObject *o)=0;
+ virtual OSCURSOR cursor_request(const wchar_t *id)=0;
+ virtual int getNumGroupDefs()=0;
+ virtual SkinItem *enumGroupDef(int n)=0;
+ virtual ifc_window *group_createBySkinItem(SkinItem *item, int scripts_enabled=1)=0;
+ virtual SkinItem *getGroupDefAncestor(SkinItem *groupitem)=0;
+ virtual int groupdef_getNumObjects(SkinItem *groupitem)=0;
+ virtual SkinItem *groupdef_enumObject(SkinItem *groupitem, int n)=0;
+ virtual void skin_setLockUI(int l)=0;
+ virtual int skin_getLockUI()=0;
+ virtual double skin_getVersion()=0;
+#ifdef WASABI_COMPILE_IMGLDR
+ virtual ARGB32 skin_getBitmapColor(const wchar_t *id)=0;
+#endif
+ virtual bool skin_isLoaded()=0;
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {F2398F09-63B0-4442-86C9-F8BC473F6DA7}
+static const GUID skinApiServiceGuid =
+{ 0xf2398f09, 0x63b0, 0x4442, { 0x86, 0xc9, 0xf8, 0xbc, 0x47, 0x3f, 0x6d, 0xa7 } };
+
+extern api_skin *skinApi;
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/colorthemes.h b/Src/Wasabi/api/skin/colorthemes.h
new file mode 100644
index 00000000..fe11ec17
--- /dev/null
+++ b/Src/Wasabi/api/skin/colorthemes.h
@@ -0,0 +1,87 @@
+#ifndef __COLORTHEMEGROUP_H
+#define __COLORTHEMEGROUP_H
+
+#include <bfc/dispatch.h>
+
+class ColorThemeGroup : public Dispatchable
+{
+ public:
+ const wchar_t *getName();
+ int getRed();
+ int getGreen();
+ int getBlue();
+ int getGray();
+ int getBoost();
+
+ void setName(const wchar_t *name);
+ void setRed(int r);
+ void setGreen(int g);
+ void setBlue(int b);
+ void setGray(int g);
+ void setBoost(int b);
+
+ enum {
+ COLORTHEMEGROUPGETNAME=10,
+ COLORTHEMEGROUPGETRED=20,
+ COLORTHEMEGROUPGETGREEN=30,
+ COLORTHEMEGROUPGETBLUE=40,
+ COLORTHEMEGROUPGETGRAY=50,
+ COLORTHEMEGROUPGETBOOST=60,
+ COLORTHEMEGROUPSETNAME=70,
+ COLORTHEMEGROUPSETRED=80,
+ COLORTHEMEGROUPSETGREEN=90,
+ COLORTHEMEGROUPSETBLUE=100,
+ COLORTHEMEGROUPSETGRAY=110,
+ COLORTHEMEGROUPSETBOOST=120,
+ };
+};
+
+inline const wchar_t *ColorThemeGroup::getName() {
+ return _call(COLORTHEMEGROUPGETNAME, (const wchar_t *)NULL);
+}
+
+inline int ColorThemeGroup::getRed() {
+ return _call(COLORTHEMEGROUPGETRED, 0);
+}
+
+inline int ColorThemeGroup::getGreen() {
+ return _call(COLORTHEMEGROUPGETGREEN, 0);
+}
+
+inline int ColorThemeGroup::getBlue() {
+ return _call(COLORTHEMEGROUPGETBLUE, 0);
+}
+
+inline int ColorThemeGroup::getGray() {
+ return _call(COLORTHEMEGROUPGETGRAY, 0);
+}
+
+inline int ColorThemeGroup::getBoost() {
+ return _call(COLORTHEMEGROUPGETBOOST, 0);
+}
+
+inline void ColorThemeGroup::setName(const wchar_t *name) {
+ _voidcall(COLORTHEMEGROUPSETNAME, name);
+}
+
+inline void ColorThemeGroup::setRed(int r) {
+ _voidcall(COLORTHEMEGROUPSETRED, r);
+}
+
+inline void ColorThemeGroup::setGreen(int g) {
+ _voidcall(COLORTHEMEGROUPSETGREEN, g);
+}
+
+inline void ColorThemeGroup::setBlue(int b) {
+ _voidcall(COLORTHEMEGROUPSETBLUE, b);
+}
+
+inline void ColorThemeGroup::setGray(int g) {
+ _voidcall(COLORTHEMEGROUPSETGRAY, g);
+}
+
+inline void ColorThemeGroup::setBoost(int b) {
+ _voidcall(COLORTHEMEGROUPSETBOOST, b);
+}
+
+#endif
diff --git a/Src/Wasabi/api/skin/cursormgr.cpp b/Src/Wasabi/api/skin/cursormgr.cpp
new file mode 100644
index 00000000..bf5ab3e8
--- /dev/null
+++ b/Src/Wasabi/api/skin/cursormgr.cpp
@@ -0,0 +1,29 @@
+#include "precomp.h"
+#include <api.h>
+#include "cursormgr.h"
+#include <api/skin/skinelem.h>
+
+
+
+OSCURSOR CursorMgr::requestCursor(const wchar_t *id)
+{
+ // Martin> Register os cursors, perhaps find a better way to do this in basewnd.cpp
+ if (_wcsicmp(id, L"IDC_ARROW") == 0) return LoadCursor(NULL, IDC_ARROW);
+ if (_wcsicmp(id, L"IDC_SIZENS") == 0) return LoadCursor(NULL, IDC_SIZENS);
+ if (_wcsicmp(id, L"IDC_SIZEWE") == 0) return LoadCursor(NULL, IDC_SIZEWE);
+ if (_wcsicmp(id, L"IDC_SIZENWSE") == 0) return LoadCursor(NULL, IDC_SIZENWSE);
+ if (_wcsicmp(id, L"IDC_SIZENESW") == 0) return LoadCursor(NULL, IDC_SIZENESW);
+ if (_wcsicmp(id, L"IDC_SIZEALL") == 0) return LoadCursor(NULL, IDC_SIZEALL);
+ if (_wcsicmp(id, L"IDC_IBEAM") == 0) return LoadCursor(NULL, IDC_IBEAM);
+ if (_wcsicmp(id, L"IDC_WAIT") == 0) return LoadCursor(NULL, IDC_WAIT);
+ if (_wcsicmp(id, L"IDC_CROSS") == 0) return LoadCursor(NULL, IDC_CROSS);
+ if (_wcsicmp(id, L"IDC_UPARROW") == 0) return LoadCursor(NULL, IDC_UPARROW);
+ if (_wcsicmp(id, L"IDC_NO") == 0) return LoadCursor(NULL, IDC_NO);
+ if (_wcsicmp(id, L"IDC_HAND") == 0) return LoadCursor(NULL, IDC_HAND);
+ if (_wcsicmp(id, L"IDC_APPSTARTING") == 0) return LoadCursor(NULL, IDC_APPSTARTING);
+ if (_wcsicmp(id, L"IDC_HELP") == 0) return LoadCursor(NULL, IDC_HELP);
+
+ OSCURSOR cursor = WASABI_API_PALETTE->getCursor(id);
+ return cursor;
+}
+
diff --git a/Src/Wasabi/api/skin/cursormgr.h b/Src/Wasabi/api/skin/cursormgr.h
new file mode 100644
index 00000000..a70d6eaf
--- /dev/null
+++ b/Src/Wasabi/api/skin/cursormgr.h
@@ -0,0 +1,18 @@
+#ifndef __CURSORMGR_H
+#define __CURSORMGR_H
+
+#include <bfc/platform/platform.h>
+#include <api/wnd/cursor.h>
+
+class ifc_window;
+
+class CursorMgr
+{
+ public:
+ CursorMgr() {}
+ virtual ~CursorMgr() {}
+
+ static OSCURSOR requestCursor(const wchar_t *id);
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/feeds/TextFeedEnum.h b/Src/Wasabi/api/skin/feeds/TextFeedEnum.h
new file mode 100644
index 00000000..62405cfe
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/TextFeedEnum.h
@@ -0,0 +1,35 @@
+#ifndef NULLSOFT_WASABI_TEXTFEEDENUM_H
+#define NULLSOFT_WASABI_TEXTFEEDENUM_H
+
+
+#include <bfc/string/StringW.h>
+#include <api/skin/feeds/api_textfeed.h>
+// see helper class TextFeed
+
+#include <api/service/servicei.h>
+template <class T>
+class TextFeedCreatorSingle : public waServiceFactoryTSingle<svc_textFeed, T>
+{
+public:
+ svc_textFeed *getFeed()
+ {
+ return getSingleService();
+ }
+};
+
+#include <api/service/svc_enum.h>
+
+class TextFeedEnum : public SvcEnumT<svc_textFeed>
+{
+public:
+ TextFeedEnum(const wchar_t *_feedid) : feedid(_feedid) {}
+protected:
+ virtual int testService(svc_textFeed *svc)
+ {
+ return (svc->hasFeed(feedid));
+ }
+private:
+ StringW feedid;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/feeds/api_textfeed.cpp b/Src/Wasabi/api/skin/feeds/api_textfeed.cpp
new file mode 100644
index 00000000..d7b3d2f1
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/api_textfeed.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "api_textfeed.h" \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/feeds/api_textfeed.h b/Src/Wasabi/api/skin/feeds/api_textfeed.h
new file mode 100644
index 00000000..fecde4d4
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/api_textfeed.h
@@ -0,0 +1,66 @@
+#ifndef __WASABI_API_TEXTFEED_H
+#define __WASABI_API_TEXTFEED_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include <api/service/services.h>
+
+class ifc_dependent;
+
+// {A04E3420-CBA1-4ae1-B3C0-8DE127D2B861}
+static const GUID textfeed_dependent_GUID = { 0xa04e3420, 0xcba1, 0x4ae1, { 0xb3, 0xc0, 0x8d, 0xe1, 0x27, 0xd2, 0xb8, 0x61 } };
+
+class NOVTABLE svc_textFeed : public Dispatchable
+{
+public:
+ static FOURCC getServiceType() { return WaSvc::TEXTFEED; }
+ static const GUID *depend_getClassGuid()
+ {
+ return &textfeed_dependent_GUID;
+ }
+ static const char *getServiceName() { return "Untitled Textfeed"; }
+
+public:
+ int hasFeed(const wchar_t *name);
+ const wchar_t *getFeedText(const wchar_t *name);
+ const wchar_t *getFeedDescription(const wchar_t *name);
+ ifc_dependent *getDependencyPtr();
+
+public:
+ enum
+ {
+ Event_TEXTCHANGE = 100, // param is const char* to id, ptr points to new text
+ };
+
+ DISPATCH_CODES
+ {
+ SVCTEXTFEED_HASFEED = 10,
+ //20,30 retired
+ SVCTEXTFEED_GETFEEDTEXT = 40,
+ SVCTEXTFEED_GETFEEDDESC = 45,
+ SVCTEXTFEED_GETDEPENDENCYPTR = 100,
+ };
+};
+
+inline int svc_textFeed::hasFeed(const wchar_t *name)
+{
+ return _call(SVCTEXTFEED_HASFEED, 0, name);
+}
+
+inline const wchar_t *svc_textFeed::getFeedText(const wchar_t *name)
+{
+ return _call(SVCTEXTFEED_GETFEEDTEXT, (const wchar_t *)NULL, name);
+}
+
+inline const wchar_t *svc_textFeed::getFeedDescription(const wchar_t *name)
+{
+ return _call(SVCTEXTFEED_GETFEEDDESC, (const wchar_t *)NULL, name);
+}
+
+inline ifc_dependent *svc_textFeed::getDependencyPtr()
+{
+ return _call(SVCTEXTFEED_GETDEPENDENCYPTR, (ifc_dependent*)NULL);
+}
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/feeds/ezfeed.h b/Src/Wasabi/api/skin/feeds/ezfeed.h
new file mode 100644
index 00000000..cc607d10
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/ezfeed.h
@@ -0,0 +1,27 @@
+#ifndef _EZFEED_H
+#define _EZFEED_H
+
+//#include <bfc/wasabi_std.h>
+#include <api/service/waservicefactorybase.h>
+#include <api/skin/feeds/textfeed.h>
+
+class EzFeed : public waServiceFactoryBase<svc_textFeed, EzFeed>, public TextFeed
+{
+public:
+ EzFeed() : registered(0) { }
+ static const char *getServiceName() { return "EzTextFeed"; }
+ virtual svc_textFeed *newService() { return this; }
+ virtual int delService(svc_textFeed *service) { return TRUE; }
+
+ virtual int svc_notify(int msg, int param1 = 0, int param2 = 0)
+ {
+ if (msg == SvcNotify::ONREGISTERED) registered = 1;
+ else if (msg == SvcNotify::ONDEREGISTERED) registered = 0;
+ return 1;
+ }
+
+private:
+ int registered;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/feeds/feedwatch.cpp b/Src/Wasabi/api/skin/feeds/feedwatch.cpp
new file mode 100644
index 00000000..e200c20e
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/feedwatch.cpp
@@ -0,0 +1,90 @@
+#include <precomp.h>
+#pragma warning(disable:4355)
+
+//<?#include "<class data="implementationheader"/>"
+#include "feedwatch.h"
+//?>
+
+#include <api/skin/feeds/TextFeedEnum.h>
+
+
+FeedWatcher::FWDV::FWDV(FeedWatcher *_parent) : parent(_parent) { }
+
+int FeedWatcher::FWDV::viewer_onItemDeleted(ifc_dependent *item) {
+ return parent->fwdv_onItemDeleted(item);
+}
+
+int FeedWatcher::FWDV::viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) {
+ return parent->fwdv_onEvent(item, event, param, ptr, ptrlen);
+}
+
+FeedWatcher::FeedWatcher() :
+ registered_syscb(0), textfeed(NULL), fwdv(this)
+{
+}
+
+
+FeedWatcher::~FeedWatcher() {
+ releaseFeed();
+ if (registered_syscb) {
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SvcCallbackI*>(this));
+ DebugStringW(L"unreg syscb");
+ }
+}
+
+int FeedWatcher::setFeed(const wchar_t *feedid)
+{
+ if (!registered_syscb++) WASABI_API_SYSCB->syscb_registerCallback(static_cast<SvcCallbackI*>(this));
+
+ releaseFeed();
+
+ feed_id = feedid;
+ if (!feed_id.isempty()) textfeed = TextFeedEnum(feed_id).getFirst();
+
+ if (textfeed != NULL) {
+ fwdv.viewer_addViewItem(textfeed->getDependencyPtr());
+ feedwatcher_onSetFeed(textfeed);
+//CUT if (first_cb) feedwatcher_onFeedChange(textfeed->getFeedText(feed_id));
+ }
+
+ return 1;
+}
+
+void FeedWatcher::releaseFeed() {
+ if (textfeed) {
+ fwdv.viewer_delViewItem(textfeed->getDependencyPtr());
+ feed_id = L"";
+ SvcEnum::release(textfeed);
+ textfeed = NULL;
+ }
+}
+
+const wchar_t *FeedWatcher::getFeedId() {
+ return feed_id;
+}
+
+int FeedWatcher::fwdv_onItemDeleted(ifc_dependent *item) {
+ textfeed = NULL;
+ // send text change msg? dunno for sure
+ return 1;
+}
+
+int FeedWatcher::fwdv_onEvent(ifc_dependent *item, int event, intptr_t param2, void *ptr, size_t ptrlen) {
+ if (textfeed && item == textfeed->getDependencyPtr()
+ && event == svc_textFeed::Event_TEXTCHANGE
+ && WCSCASEEQLSAFE((const wchar_t *)param2, feed_id)) {
+ feedwatcher_onFeedChange((const wchar_t *)ptr);
+ return 1;
+ }
+ return 0;
+}
+
+void FeedWatcher::svccb_onSvcRegister(FOURCC type, waServiceFactory *svc) {
+ // brand new feed and we don't have one, try to register it
+//CUT __asm int 3;
+ if (type == WaSvc::TEXTFEED && textfeed == NULL) {
+ if (!feed_id.isempty()) {
+ setFeed(feed_id);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/feeds/feedwatch.h b/Src/Wasabi/api/skin/feeds/feedwatch.h
new file mode 100644
index 00000000..3e3bd7a2
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/feedwatch.h
@@ -0,0 +1,54 @@
+#ifndef __FEEDWATCH_H
+#define __FEEDWATCH_H
+
+#include <bfc/wasabi_std.h>
+#include <api/syscb/callbacks/svccbi.h>
+#include "feedwatcherso.h"
+
+class svc_textFeed;
+class ifc_dependent;
+
+
+
+class FeedWatcher : private SvcCallbackI, public FeedWatcherScriptObject {
+public:
+ FeedWatcher();
+ virtual ~FeedWatcher();
+
+ int setFeed(const wchar_t *feedid);
+ void releaseFeed();
+
+ const wchar_t *getFeedId();
+
+ virtual void feedwatcher_onSetFeed(svc_textFeed *svc) { }
+ virtual void feedwatcher_onFeedChange(const wchar_t *data) { }
+
+protected:
+ class FWDV : public DependentViewerI
+{
+public:
+ friend class FeedWatcher;
+
+ FWDV(FeedWatcher *parent);
+
+ virtual int viewer_onItemDeleted(ifc_dependent *item);
+ virtual int viewer_onEvent(ifc_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen);
+
+ FeedWatcher *parent;
+};
+
+ // catches text feed change events
+ virtual int fwdv_onItemDeleted(ifc_dependent *item);
+ virtual int fwdv_onEvent(ifc_dependent *item, int event, intptr_t param2, void *ptr, size_t ptrlen);
+
+private:
+ // catches new feeds being registered
+ virtual void svccb_onSvcRegister(FOURCC type, waServiceFactory *svc);
+
+ int registered_syscb;
+ StringW feed_id;
+ svc_textFeed *textfeed;
+ FWDV fwdv;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/feeds/feedwatcherso.cpp b/Src/Wasabi/api/skin/feeds/feedwatcherso.cpp
new file mode 100644
index 00000000..af8d5ff0
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/feedwatcherso.cpp
@@ -0,0 +1,136 @@
+// ----------------------------------------------------------------------------
+// Generated by ScriptObjectFactory [Sat Sep 27 01:24:57 2003]
+//
+// File :
+// Class : FeedWatcherScriptObject
+// class layer : Automatic Object Scripting
+// ----------------------------------------------------------------------------
+#include "precomp.h"
+
+#include "feedwatch.h"
+#include "FeedWatcherSO.h"
+// ScriptController Instance
+static FeedWatcherScriptController _feedWatcherScriptController;FeedWatcherScriptController *feedWatcherScriptController = &_feedWatcherScriptController;
+
+// Function Descriptor Table
+function_descriptor_struct FeedWatcherScriptController::exportedFunctions[] = {
+ { L"setFeed", 1, script_setFeed },
+ { L"releaseFeed", 0, script_releaseFeed },
+ { L"onFeedChange", 1, script_feedwatcher_onFeedChange },
+};
+
+// Script Object Methods
+FeedWatcherScriptObject::FeedWatcherScriptObject() {
+ if (!getScriptObject()) return;
+ feedWatcherScriptObject_init();
+}
+
+FeedWatcherScriptObject::~FeedWatcherScriptObject() {
+}
+
+void FeedWatcherScriptObject::feedWatcherScriptObject_init() {
+ // Assign the script interface to this instance.
+ getScriptObject()->vcpu_setInterface(FeedWatcherGuid, (void *)static_cast<FeedWatcher*>(this));
+ // Assign the class name to this instance.
+ getScriptObject()->vcpu_setClassName(L"FeedWatcher");
+ // Assign the controller instance to this script object instance.
+ getScriptObject()->vcpu_setController(feedWatcherScriptController);
+}
+
+// Script Object Methods
+
+void FeedWatcherScriptObject::feedwatcher_onFeedChange(const wchar_t *data) {
+ FeedWatcherScriptController::script_feedwatcher_onFeedChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(data));
+}
+
+scriptVar /*int */ FeedWatcherScriptController::script_setFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ feedid) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ FeedWatcher*_pObj = static_cast<FeedWatcher*>(_pSO->vcpu_getInterface(FeedWatcherGuid));
+ if (_pObj) {
+ return MAKE_SCRIPT_INT(_pObj->setFeed(GET_SCRIPT_STRING(feedid)));
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar /*void */ FeedWatcherScriptController::script_releaseFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ FeedWatcher*_pObj = static_cast<FeedWatcher*>(_pSO->vcpu_getInterface(FeedWatcherGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->releaseFeed();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ FeedWatcherScriptController::script_feedwatcher_onFeedChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ data) {
+ // Begin all script methods with the init block
+ SCRIPT_FUNCTION_INIT;
+ // Honnor C++ hooks
+ PROCESS_HOOKS1(_pSO, feedWatcherScriptController, data);
+ // If there are no script hooks to execute, we abort here.
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ // Otherwise we execute the script methods by calling this.
+ SCRIPT_EXEC_EVENT1(_pSO, data);
+}
+
+// Script Controller
+
+// This method returns the human readable name of the class in script files.
+const wchar_t *FeedWatcherScriptController::getClassName() {
+ return L"FeedWatcher";
+}
+
+// This method returns the human readable name of the parent of this class.
+const wchar_t *FeedWatcherScriptController::getAncestorClassName() {
+ return FEEDWATCHER_SCRIPTPARENTCLASS;
+}
+
+// This method returns the controller object for the parent class.
+ScriptObjectController *FeedWatcherScriptController::getAncestorController() {
+ /* XML-Template-TODO : Support inheritance */
+ return NULL;
+}
+
+// This method returns the number of methods this class publishes.
+int FeedWatcherScriptController::getNumFunctions() {
+ return sizeof(exportedFunctions) / sizeof(function_descriptor_struct);
+}
+
+// This method returns the block of published function descriptors.
+const function_descriptor_struct *FeedWatcherScriptController::getExportedFunctions() {
+ return exportedFunctions;
+}
+
+// This method returns the GUID assigned to this script class.
+GUID FeedWatcherScriptController::getClassGuid() {
+ return FeedWatcherGuid;
+}
+
+// This method creates and returns a new script class instance.
+ScriptObject *FeedWatcherScriptController::instantiate() {
+ FeedWatcher*_pObj = new FeedWatcher();
+ ASSERT(_pObj != NULL);
+ return _pObj->getScriptObject();
+}
+
+// This method deletes a given script class instance.
+void FeedWatcherScriptController::destroy(ScriptObject *o) {
+ FeedWatcher*_pObj = static_cast<FeedWatcher*>(o->vcpu_getInterface(FeedWatcherGuid));
+ ASSERT(_pObj != NULL);
+ delete _pObj;
+}
+
+// This method returns an encapsulated interface for the given instance.
+void *FeedWatcherScriptController::encapsulate(ScriptObject *o) {
+ // No automatic encapsulation
+ return NULL;
+}
+
+// This method frees a previously encapsulated interface.
+void FeedWatcherScriptController::deencapsulate(void *o) {
+}
+
diff --git a/Src/Wasabi/api/skin/feeds/feedwatcherso.h b/Src/Wasabi/api/skin/feeds/feedwatcherso.h
new file mode 100644
index 00000000..852964fa
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/feedwatcherso.h
@@ -0,0 +1,64 @@
+// ----------------------------------------------------------------------------
+// Generated by ScriptObjectFactory [Sat Sep 27 01:24:57 2003]
+//
+// File :
+// Class : FeedWatcherScriptObject
+// class layer : Automatic Object Scripting
+// ----------------------------------------------------------------------------
+
+#ifndef __FEEDWATCHERSCRIPTOBJECT_H
+#define __FEEDWATCHERSCRIPTOBJECT_H
+
+
+#include <api/script/objects/rootobj.h>
+#include <api/script/objcontroller.h>
+
+#define FEEDWATCHER_SCRIPTPARENT RootObjectInstance
+#define FEEDWATCHER_SCRIPTPARENTCLASS L"Object"
+
+class svc_textFeed;
+
+// ----------------------------------------------------------------------------
+// {A5376FA1-4E94-411a-83F6-05EC5EEA5F0A}
+static const GUID FeedWatcherGuid =
+{ 0xa5376fa1, 0x4e94, 0x411a, { 0x83, 0xf6, 0x5, 0xec, 0x5e, 0xea, 0x5f, 0xa } };
+
+// -----------------------------------------------------------------------------
+
+class FeedWatcherScriptObject : public FEEDWATCHER_SCRIPTPARENT {
+public:
+ FeedWatcherScriptObject();
+ virtual ~FeedWatcherScriptObject();
+
+ void feedWatcherScriptObject_init();
+
+public:
+ virtual void feedwatcher_onFeedChange(const wchar_t *data);
+};
+
+// -----------------------------------------------------------------------------
+class FeedWatcherScriptController : public ScriptObjectControllerI {
+public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ static scriptVar script_setFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar feedid);
+ static scriptVar script_releaseFeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_feedwatcher_onFeedChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar data);
+
+private:static function_descriptor_struct exportedFunctions[];
+};
+
+extern FeedWatcherScriptController *feedWatcherScriptController;
+// ----------------------------------------------------------------------------
+
+#endif // __FEEDWATCHERSCRIPTOBJECT_H
diff --git a/Src/Wasabi/api/skin/feeds/textfeed.cpp b/Src/Wasabi/api/skin/feeds/textfeed.cpp
new file mode 100644
index 00000000..feebe097
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/textfeed.cpp
@@ -0,0 +1,116 @@
+#include <precomp.h>
+#include "textfeed.h"
+#include <bfc/pair.h>
+
+int TextFeed::registerFeed(const wchar_t *feedid, const wchar_t *initial_text, const wchar_t *description)
+{
+ //if (feeds.getItem(StringW(feedid)))
+ // return FALSE;
+ auto it = feeds.find(feedid);
+ if (feeds.end() != it)
+ {
+ return FALSE;
+ }
+
+ //std::pair<std::wstring, std::wstring> pair(initial_text, description);
+
+ feeds.insert({ feedid, {initial_text, description} });
+
+ dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)feedid, (void*)initial_text, wcslen(initial_text) + 1);
+ return TRUE;
+}
+
+int TextFeed::sendFeed(const wchar_t *feedid, const wchar_t *text)
+{
+ //Pair <StringW, StringW> ft(L"", L"");
+ //if (!feeds.getItem(StringW(feedid), &ft))
+ //{
+ // //CUT ASSERTALWAYS("hey, you're trying to send a feed you didn't register. stop it.");
+ // DebugString("TextFeed::sendFeed(), feedid '%s' not registered", feedid);
+ // return FALSE;
+ //}
+ auto it = feeds.find(feedid);
+ if (feeds.end() == it)
+ {
+ return FALSE;
+ }
+
+ //StringW id(feedid);
+ //feeds.getItem(id, &ft);
+ //ft.a = StringW(text);
+ //feeds.setItem(StringW(feedid), ft);
+
+ auto &ft = feeds[feedid];
+ ft.first = text;
+
+ dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)feedid, (void*)text, wcslen(text) + 1);
+ return TRUE;
+}
+
+const wchar_t *TextFeed::getFeedText(const wchar_t *name)
+{
+ //const Pair<StringW, StringW> *ft = feeds.getItemRef(StringW(name));
+ //if (ft == NULL)
+ // return NULL;
+ //ft->a.getValue();
+
+ auto it = feeds.find(name);
+ if (it == feeds.end())
+ {
+ return NULL;
+ }
+ auto& ft = it->second;
+ return ft.first.c_str();
+}
+
+const wchar_t *TextFeed::getFeedDescription(const wchar_t *name)
+{
+ //const Pair<StringW, StringW> *ft = feeds.getItemRef(StringW(name));
+ //if (ft == NULL) return NULL;
+ //return ft->b.getValue();
+
+ auto it = feeds.find(name);
+ if (it == feeds.end())
+ {
+ return NULL;
+ }
+
+ auto& ft = it->second;
+ return ft.second.c_str();
+}
+
+int TextFeed::hasFeed(const wchar_t *name)
+{
+ return feeds.count(name);
+}
+
+void TextFeed::dependent_onRegViewer(api_dependentviewer *viewer, int add)
+{
+ if (add)
+ {
+ //for (int i = 0; i < feeds.getNumItems(); i++)
+ //{
+ // StringW a = feeds.enumIndexByPos(i, StringW(L""));
+ // Pair<StringW, StringW> sp(L"", L"");
+ // StringW b = feeds.enumItemByPos(i, sp).a;
+ // dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)a.getValue(), (void*)b.getValue(), b.len() + 1, viewer); //send to this viewer only
+ //}
+
+ for (auto it = feeds.begin(); it != feeds.end(); it++)
+ {
+ std::wstring key = it->first;
+ auto val = it->second;
+ std::wstring val_first = val.first;
+ dependent_sendEvent(svc_textFeed::depend_getClassGuid(), Event_TEXTCHANGE, (intptr_t)key.c_str(), (void*)val_first.c_str(), wcslen(val_first.c_str()) + 1, viewer); //send to this viewer only
+ }
+ }
+
+ if (add) onRegClient();
+ else onDeregClient();
+}
+
+void *TextFeed::dependent_getInterface(const GUID *classguid)
+{
+ HANDLEGETINTERFACE(svc_textFeed);
+ return NULL;
+}
diff --git a/Src/Wasabi/api/skin/feeds/textfeed.h b/Src/Wasabi/api/skin/feeds/textfeed.h
new file mode 100644
index 00000000..1c2d9bc1
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/textfeed.h
@@ -0,0 +1,57 @@
+#ifndef _TEXTFEED_H
+#define _TEXTFEED_H
+
+#include <bfc/common.h>
+#include <map>
+#include <string>
+#include <utility>
+#include <bfc/depend.h>
+#include <api/service/svcs/svc_textfeed.h>
+#include <api/syscb/callbacks/corecbi.h>
+
+/**
+ This is the standard helper class for implementing a textfeed.
+ Be sure to check out class EzFeed in ezfeed.h, which combines this
+ class with a service factory.
+*/
+class TextFeed : public svc_textFeedI, public DependentI
+{
+public:
+/**
+ Call this to register your feeds by id. Make the ids unique!
+ @see sendFeed()
+ @ret TRUE if succeeded, FALSE on error (i.e. nonunique id)
+*/
+ int registerFeed(const wchar_t *feedid, const wchar_t *initial_text=L"", const wchar_t *description=L"");
+
+/**
+ Call this to send text into a feed.
+ @see registerFeed()
+ @ret TRUE if succeeded, FALSE on error (i.e. feedid not registered)
+*/
+ int sendFeed(const wchar_t *feedid, const wchar_t *text);
+
+// Gives the most recently sent text on a feed.
+ virtual const wchar_t *getFeedText(const wchar_t *feedid);
+
+// Gives a description for the feed (used by accessibility).
+ virtual const wchar_t *getFeedDescription(const wchar_t *feedid);
+
+protected:
+ virtual api_dependent *getDependencyPtr() { return this; }
+ virtual void dependent_onRegViewer(api_dependentviewer *viewer, int add);
+ virtual void *dependent_getInterface(const GUID *classguid);
+
+/**
+ Called when someone subscribes to this feed.
+*/
+ virtual void onRegClient() { }
+ virtual void onDeregClient() { }
+
+ virtual int hasFeed(const wchar_t *name);
+
+private:
+ std::map<std::wstring, std::pair<std::wstring, std::wstring> > feeds;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/feeds/textfeedcb.cpp b/Src/Wasabi/api/skin/feeds/textfeedcb.cpp
new file mode 100644
index 00000000..61542fb3
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/textfeedcb.cpp
@@ -0,0 +1,9 @@
+#include "precomp.h"
+#if 0//CUT
+#include "textfeedcb.h"
+
+#define CBCLASS TextFeedCallbackI
+START_DISPATCH;
+ VCB(TEXTFEEDCB_ONRECEIVETEXT, textfeed_onReceiveText);
+END_DISPATCH;
+#endif
diff --git a/Src/Wasabi/api/skin/feeds/textfeedcb.h b/Src/Wasabi/api/skin/feeds/textfeedcb.h
new file mode 100644
index 00000000..da8d804a
--- /dev/null
+++ b/Src/Wasabi/api/skin/feeds/textfeedcb.h
@@ -0,0 +1,34 @@
+#error this file is going away
+#if 0
+#ifndef __TEXTFEEDCB_H
+#define __TEXTFEEDCB_H
+
+#include "dispatch.h"
+#include "../common/common.h"
+
+class TextFeedCallback : public Dispatchable {
+ public:
+
+ void textfeed_onReceiveText(const wchar_t *text);
+
+ enum {
+ TEXTFEEDCB_ONRECEIVETEXT = 10,
+ };
+};
+
+inline void TextFeedCallback::textfeed_onReceiveText(const wchar_t *text) {
+ _voidcall(TEXTFEEDCB_ONRECEIVETEXT, text);
+}
+
+class TextFeedCallbackI : public TextFeedCallback {
+ public:
+ TextFeedCallbackI() {}
+ virtual ~TextFeedCallbackI() {}
+
+ virtual void textfeed_onReceiveText(const wchar_t *text)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+#endif
+#endif
diff --git a/Src/Wasabi/api/skin/gammamgr.cpp b/Src/Wasabi/api/skin/gammamgr.cpp
new file mode 100644
index 00000000..9df1c88e
--- /dev/null
+++ b/Src/Wasabi/api/skin/gammamgr.cpp
@@ -0,0 +1,135 @@
+#include <precomp.h>
+#include <api.h>
+#include "gammamgr.h"
+#include <api/service/servicei.h>
+#include <api/skin/skinelem.h>
+#include <api/syscb/callbacks/skincb.h>
+
+
+
+void GammaMgr::init()
+{
+ skinXML.registerCallback(L"WinampAbstractionLayer\fgammaset", &xmlreader); //back compat
+ skinXML.registerCallback(L"WinampAbstractionLayer\fgammaset\fgammagroup", &xmlreader); //back compat
+ skinXML.registerCallback(L"WasabiXML\fgammaset", &xmlreader);
+ skinXML.registerCallback(L"WasabiXML\fgammaset\fgammagroup", &xmlreader);
+
+ curset = -1;
+}
+
+void GammaMgr::deinit()
+{
+ WASABI_API_COLORTHEMES->deleteAllGammaSets();
+ skinXML.unregisterCallback(&xmlreader);
+}
+
+void GammaMgr::onBeforeLoadingGammaGroups()
+{
+ WASABI_API_COLORTHEMES->deleteAllGammaSets();
+ curset = -1;
+}
+
+void GammaMgr::onAfterLoadingGammaGroups()
+{}
+
+void GammaMgr::loadDefault()
+{
+ WASABI_API_COLORTHEMES->StartTransaction();
+#ifdef ON_LOAD_EXTRA_COLORTHEMES
+ ON_LOAD_EXTRA_COLORTHEMES();
+#endif
+ WASABI_API_COLORTHEMES->EndTransaction();
+
+ if (WASABI_API_COLORTHEMES->getGammaSet() == NULL)
+ {
+ wchar_t txt[256] = {0};
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"Color Themes/%s", WASABI_API_SKIN->getSkinName()), txt, 256, L"Default");
+ WASABI_API_COLORTHEMES->setGammaSet(txt);
+ }
+}
+
+int GammaMgr::gammaEqual(const wchar_t *id1, const wchar_t *id2)
+{
+ const wchar_t *a = WASABI_API_PALETTE->getGammaGroupFromId(id1);
+ const wchar_t *b = WASABI_API_PALETTE->getGammaGroupFromId(id2);
+ if (!a || !b) return 1;
+ return !WCSICMP(a, b);
+}
+
+void GammaMgrXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params)
+{
+ GammaMgr::xmlReaderOnStartElementCallback(xmltag, params);
+}
+
+void GammaMgr::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params)
+{
+ if (!WCSICMP(xmltag, L"gammaset"))
+ {
+ const wchar_t *id = params->getItemValue(L"id");
+ WASABI_API_COLORTHEMES->resetGammaSet(id);
+ curset = WASABI_API_COLORTHEMES->newGammaSet(id);
+ }
+ else if (!WCSICMP(xmltag, L"gammagroup"))
+ {
+ const wchar_t *id = params->getItemValue(L"id");
+ if (!id) // TODO: should we pop up a skin error msgbox?
+ return;
+ StringW value = params->getItemValue(L"value");
+ int r = 0, g = 0, b = 0;
+ wchar_t *p = value.getNonConstVal();
+ if (!p) // TODO: should we pop up a skin error msgbox?
+ return;
+ wchar_t *q = p;
+ while (q && *q && *q != ',') q++;
+ if (q && *q == ',') *q++ = 0;
+ r = WTOI(p);
+ if (*q)
+ {
+ p = q;
+ while (*q && *q != ',') q++;
+ if (*q == ',') *q++ = 0;
+ g = WTOI(p);
+ if (*q) b = WTOI(q);
+ }
+
+ int makegray = params->getItemValueInt(L"gray");
+ int boost = params->getItemValueInt(L"boost");
+ if (!WCSICMP(id, L"General") && curset>=0)
+ {
+ ColorThemeGroup *generalgroup = WASABI_API_COLORTHEMES->enumColorThemeGroup(curset, -1);
+ if (generalgroup)
+ {
+ generalgroup->setRed(r);
+ generalgroup->setGreen(g);
+ generalgroup->setBlue(b);
+ generalgroup->setGray(makegray);
+ generalgroup->setBoost(boost);
+ }
+ }
+ else if (curset != -1)
+ {
+ ColorThemeGroupI new_group(id, r, g, b, makegray, boost);
+ WASABI_API_COLORTHEMES->addGammaGroup(curset, &new_group);
+ }
+ }
+
+}
+
+GammaMgrXmlReader GammaMgr::xmlreader;
+int GammaMgr::curset;
+
+#define CBCLASS ColorThemeGroupI
+START_DISPATCH;
+CB(COLORTHEMEGROUPGETNAME, getName);
+CB(COLORTHEMEGROUPGETRED, getRed);
+CB(COLORTHEMEGROUPGETGREEN, getGreen);
+CB(COLORTHEMEGROUPGETBLUE, getBlue);
+CB(COLORTHEMEGROUPGETGRAY, getGray);
+CB(COLORTHEMEGROUPGETBOOST, getBoost);
+VCB(COLORTHEMEGROUPSETNAME, setName);
+VCB(COLORTHEMEGROUPSETRED, setRed);
+VCB(COLORTHEMEGROUPSETGREEN, setGreen);
+VCB(COLORTHEMEGROUPSETBLUE, setBlue);
+VCB(COLORTHEMEGROUPSETGRAY, setGray);
+VCB(COLORTHEMEGROUPSETBOOST, setBoost);
+END_DISPATCH; \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/gammamgr.h b/Src/Wasabi/api/skin/gammamgr.h
new file mode 100644
index 00000000..1d09319e
--- /dev/null
+++ b/Src/Wasabi/api/skin/gammamgr.h
@@ -0,0 +1,91 @@
+#ifndef _GAMMAMGR_H
+#define _GAMMAMGR_H
+
+#include <api/xml/xmlreader.h>
+#include <api/service/svcs/svc_skinfilter.h>
+
+#include <bfc/string/StringW.h>
+#include <api/skin/colorthemes.h>
+
+
+class ColorThemeGroupI : public ColorThemeGroup
+{
+public:
+ ColorThemeGroupI(const wchar_t *pname, int pred, int pgreen, int pblue, int pgray, int pboost)
+ : name(pname), red(pred), green(pgreen), blue(pblue), make_grayscale(pgray), boost_levels(pboost) { }
+ ColorThemeGroupI(ColorThemeGroup &copy_group)
+ {
+ name = copy_group.getName();
+ red = copy_group.getRed();
+ green = copy_group.getGreen();
+ blue = copy_group.getBlue();
+ make_grayscale = copy_group.getGray();
+ boost_levels = copy_group.getBoost();
+ }
+ virtual const wchar_t *getName() { return name; }
+ virtual int getRed() { return red; }
+ virtual int getGreen() { return green; }
+ virtual int getBlue() { return blue; }
+ virtual int getGray() { return make_grayscale; }
+ virtual int getBoost() { return boost_levels; }
+ virtual void setName(const wchar_t *pname) { name = pname; }
+ virtual void setRed(int r) { red = r; }
+ virtual void setGreen(int g) { green = g; }
+ virtual void setBlue(int b) { blue = b; }
+ virtual void setGray(int g) { make_grayscale = g; }
+ virtual void setBoost(int b) { boost_levels = b; }
+
+ protected:
+ RECVS_DISPATCH;
+
+ StringW name;
+ int red;
+ int green;
+ int blue;
+ int make_grayscale;
+ int boost_levels;
+};
+
+
+
+
+class GammaMgrXmlReader : public XmlReaderCallbackI
+{
+public:
+ void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params);
+};
+
+class GammaMgr
+{
+public:
+ static void init();
+ static void deinit();
+
+ static void onBeforeLoadingGammaGroups();
+ static void onAfterLoadingGammaGroups();
+ static int gammaEqual(const wchar_t *id1, const wchar_t *id2);
+
+ static void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params);
+
+ static int filterBitmap(uint8_t *bits, int w, int h, int bpp, const wchar_t *element_id, const wchar_t *forcegroup=NULL);
+ static ARGB32 filterColor(ARGB32 color, const wchar_t *element_id, const wchar_t *forcegroup=NULL);
+/*
+ static void setGammaSet(const wchar_t *set);
+ static int getNumGammaSets();
+ static const wchar_t *enumGammaSet(int n);
+ static int getNumGammaGroups(const wchar_t *gammaset);
+ static const wchar_t *enumGammaGroup(const wchar_t *gammaset, int n);
+ static ColorThemeGroup *enumColorThemeGroup(int colorset, int colorgroup);
+ static ColorThemeGroup *getColorThemeGroup(const wchar_t *colorset, const wchar_t *colorgroup);
+ static void newGammaSet(const wchar_t *set);
+ static void updateGammaSet(const wchar_t *set);
+ static void renameGammaSet(const wchar_t *set, const wchar_t *newname);
+ static void deleteGammaSet(const wchar_t *set);*/
+ static void loadDefault();
+
+private:
+ static void onGammaSet();
+ static GammaMgrXmlReader xmlreader;
+ static int curset; // current while parsing xml
+};
+#endif
diff --git a/Src/Wasabi/api/skin/group.h b/Src/Wasabi/api/skin/group.h
new file mode 100644
index 00000000..e4a9ad5f
--- /dev/null
+++ b/Src/Wasabi/api/skin/group.h
@@ -0,0 +1,366 @@
+#include "widgets/group.h"
+#if 0 // not in use
+#ifndef __GROUP_H
+#define __GROUP_H
+
+#ifndef _NOSTUDIO
+
+class Group;
+class Container;
+class Layout;
+class CfgItem;
+class CfgGroup;
+class SRegion;
+
+#include <bfc/tlist.h>
+#include <bfc/depview.h>
+#include <api/wnd/wndclass/embeddedxui.h>
+#include <api/wnd/wndclass/clickwnd.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <tataki/bitmap/bitmap.h>
+#include <tataki/region/region.h>
+#ifdef WASABI_COMPILE_CONFIG
+#include <api/config/items/cfgitem.h>
+#endif // wasabi_compile_config
+
+#include <api/wndmgr/container.h>
+
+#endif // _nostudio
+
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+// {80F0F8BD-1BA5-42a6-A093-3236A00C8D4A}
+static const GUID cfgGroupGuid =
+{ 0x80f0f8bd, 0x1ba5, 0x42a6, { 0xa0, 0x93, 0x32, 0x36, 0xa0, 0xc, 0x8d, 0x4a } };
+
+#define RESIZE_MINW 96
+#define RESIZE_MINH 24
+
+class XmlObject;
+
+class GroupScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual int getInstantiable();
+ virtual ScriptObject *cast(ScriptObject *, GUID g);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern GroupScriptController *groupController;
+
+class XuiParam {
+ public:
+ XuiParam(const wchar_t *_param, const wchar_t *_value) : param(_param), value(_value) {}
+ virtual ~XuiParam() {}
+ StringW param;
+ StringW value;
+};
+
+#define GROUP_PARENT EmbeddedXuiObject
+
+class Group : public GROUP_PARENT {
+
+public:
+ Group();
+ virtual ~Group();
+
+ int onPaint(Canvas *canvas);
+
+ virtual int onResize();
+ virtual int onPostedMove();
+ virtual int onInit();
+ virtual Container *getParentContainer();
+ virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2);
+
+ virtual void setBaseTexture(const wchar_t *b, int regis=1);
+ virtual SkinBitmap *getBaseTexture();
+ virtual ifc_window *getBaseTextureWindow();
+
+ virtual int setXmlParam(const wchar_t *paramname, const wchar_t *strvalue);
+ virtual int setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue);
+ virtual api_region *getRegion();
+ virtual void setRegion(api_region *r);
+ void reloadDefaults();
+ virtual int onGroupChange(const wchar_t *id);
+ virtual void autoResize();
+ virtual void startScripts();
+
+ void onCreateObject(GuiObject *o);
+ GuiObject *getObject(const wchar_t *id);
+
+ void sendNotifyToAllChildren(int notifymsg, int param1, int param2);
+
+ int isDeleting() { return deleting; }
+
+ void updatePos(GuiObject *o, RECT *r=NULL);
+
+ AutoSkinBitmap *background;
+ int x, y;
+
+ LPARAM wndHolder_getParentParam(int i=0);
+
+ virtual void setDesignWidth(int w);
+ virtual void setDesignHeight(int h);
+ virtual int getDesignWidth();
+ virtual int getDesignHeight();
+
+ virtual void invalidateWindowRegion();
+ virtual void setRegionOp(int o);
+ virtual void setGroupContent(const wchar_t *id, SkinItem *specific_item, int scripts_enabled);
+ virtual const wchar_t *getGroupContentId();
+ virtual SkinItem *getGroupContentSkinItem();
+ virtual void setAutoWidthSource(const wchar_t *obj);
+ virtual void setAutoHeightSource(const wchar_t *obj);
+
+ virtual void cancelCapture() {};
+ virtual int getPreferences(int what);
+
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return groupController; }
+
+ int getNumObjects();
+ ifc_window *enumObjects(int i);
+
+ void addChild(GuiObject *g);
+ void removeChild(GuiObject *g);
+
+#ifdef WASABI_COMPILE_WNDMGR
+ virtual void mouseResize(int x, int y, int resizeway);// screen coords!
+ virtual void beginMove();
+ virtual void beginScale();
+ virtual void beginResize();
+ virtual void endMove();
+ virtual void endScale();
+ virtual void endResize();
+#endif
+
+ virtual int getAutoWidth(void);
+ virtual int getAutoHeight(void);
+
+ virtual int isLayout();
+
+ void setDrawBackground(int t);
+ int getDrawBackground(void);
+
+#ifdef WASABI_COMPILE_CONFIG
+ static int isCfgGroup(Group *ptr);
+#endif
+
+ void addScript(int scriptid);
+ void deleteScripts();
+ int enumScript(int n);
+ int getNumScripts();
+ virtual int isDesktopAlphaSafe();
+ virtual int isTransparencySafe(int excludeme=0);
+
+ static int isGroup(Group *o);
+ const wchar_t *getBackgroundStr();
+ int getWidthBasedOn(GuiObject *o=NULL);
+ int getHeightBasedOn(GuiObject *o=NULL);
+
+ void fixPosition();
+
+ const wchar_t *embeddedxui_getEmbeddedObjectId() { return xui_embedded_id; }
+ virtual void onFillGroup();
+ virtual int onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual ScriptObject *script_cast(GUID g);
+
+ virtual void onMinMaxEnforcerChanged();
+ virtual int isTransparencyForcedOff() { return 0; }
+
+protected:
+ static PtrList<CfgGroup> cfggrouplist;
+
+private:
+ StringW basetextureStr;
+ StringW xui_embedded_id;
+
+ void invalidateScaledReg();
+ void ensureScaledRegValid();
+
+ int resizing;
+ int size_w,size_h;
+ int cX,cY;
+ int captured;
+ POINT mousepos;
+ int propagatesize;
+
+ PtrList<XuiParam> xuiparams;
+
+ int moving;
+ int mover;
+ int drawbackground;
+ RECT oldRect;
+ int groupmaxheight;
+ int groupmaxwidth;
+ int groupminheight;
+ int groupminwidth;
+ int lockminmax;
+// int regionop;
+ TList<int> scripts;
+ RegionI *subtractedreg;
+ static PtrList<Group> groups;
+ StringW backgroundstr;
+ StringW instanceid;
+ RegionI *reg;
+ RegionI *scaledreg;
+ int scaledregionvalid;
+ int autoregionop;
+ StringW content_id;
+ SkinItem *content_item;
+ int no_init_on_addchild;
+ StringW autoheightsource;
+ StringW autowidthsource;
+ GuiObject *lastheightsource;
+ GuiObject *lastwidthsource;
+ int lastgetwidthbasedon, lastgetheightbasedon;
+
+ int default_w, default_h;
+ int design_w, design_h;
+ int scripts_enabled;
+ int xuihandle;
+ static XMLParamPair groupParams[];
+protected:
+ enum {
+ XUIGROUP_INSTANCEID=0,
+ XUIGROUP_BACKGROUND,
+ XUIGROUP_DRAWBACKGROUND,
+ XUIGROUP_DEFAULT_W,
+ XUIGROUP_DEFAULT_H,
+ XUIGROUP_MAXIMUM_H,
+ XUIGROUP_MAXIMUM_W,
+ XUIGROUP_MINIMUM_H,
+ XUIGROUP_MINIMUM_W,
+ XUIGROUP_PROPAGATESIZE,
+ XUIGROUP_LOCKMINMAX,
+ XUIGROUP_NAME,
+ XUIGROUP_AUTOWIDTHSOURCE,
+ XUIGROUP_AUTOHEIGHTSOURCE,
+ XUIGROUP_EMBED_XUI,
+ XUIGROUP_XUITAG,
+ XUIGROUP_INHERIT_GROUP,
+ XUIGROUP_INHERIT_CONTENT,
+ XUIGROUP_DESIGN_W,
+ XUIGROUP_DESIGN_H,
+ XUIGROUP_NUMPARAMS,
+ };
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+private:
+ PtrList<ScriptObject> script_objects;
+ PtrList<GuiObject> gui_objects;
+ int deleting;
+ int skinpart;
+ int alpha;
+ int disable_update_pos;
+
+public:
+ void addObject(GuiObject *o);
+ void removeObject(GuiObject *o);
+ void setSkinPartId(int i) { skinpart = i; }
+ int getSkinPartId() { return skinpart; }
+
+ static scriptVar script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i);
+ static scriptVar script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob);
+ static scriptVar script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_subtractRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg);
+ static scriptVar script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static void instantiate(Layout *l);
+
+};
+
+extern const wchar_t groupXuiObjectStr[];
+extern char groupXuiSvcName[];
+class GroupXuiSvc : public XuiObjectSvc<Group, groupXuiObjectStr, groupXuiSvcName> {};
+
+
+#ifdef WASABI_COMPILE_CONFIG
+
+class CfgGroupScriptController : public GroupScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return groupController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual int getInstantiable();
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern CfgGroupScriptController *cfgGroupController;
+
+class CfgGroup : public Group, public DependentViewerTPtr<CfgItem> {
+ public:
+
+ CfgGroup();
+ virtual ~CfgGroup();
+
+ void setAttr(CfgItem *item, const wchar_t *name);
+ const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return cfgGroupController; }
+
+ virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual void dataChanged();
+
+ CfgItem *getCfgItem();
+ const wchar_t *getAttributeName();
+ const wchar_t *getCfgGuid() { return cfgguid; }
+ virtual int onInit();
+
+ static scriptVar script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+
+ CfgItem *cfgitem;
+ StringW attrname;
+ StringW cfgguid;
+ static wchar_t txt[512];
+};
+
+extern const wchar_t cfgGroupXuiObjectStr[];
+extern char cfgGroupXuiSvcName[];
+class CfgGroupXuiSvc : public XuiObjectSvc<CfgGroup, cfgGroupXuiObjectStr, cfgGroupXuiSvcName> {};
+
+#endif // wasabi_compile_config
+
+
+#endif // group.h
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/groupmgr.cpp b/Src/Wasabi/api/skin/groupmgr.cpp
new file mode 100644
index 00000000..dea7672c
--- /dev/null
+++ b/Src/Wasabi/api/skin/groupmgr.cpp
@@ -0,0 +1,51 @@
+#include <precomp.h>
+#include <api/skin/groupmgr.h>
+#include <api/skin/skinparse.h>
+#include <api/skin/guitree.h>
+#include <api/config/items/attrint.h>
+#include <api/config/items/cfgitem.h>
+
+Group *GroupMgr::instantiate(const wchar_t *groupid, int grouptype, SkinItem *specific_item, int scripts_enabled)
+{
+ InCriticalSection in_cs(&cs_grp);
+ GuiObject *go = SkinParser::newDynamicGroup(groupid, grouptype, specific_item, 0, scripts_enabled);
+ Group *g = static_cast<Group *>(go->guiobject_getScriptObject()->vcpu_getInterface(groupGuid));
+ if (!g) return NULL;
+ grouplist.addItem(g);
+ return g;
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+
+Group *GroupMgr::instantiate(const wchar_t *groupid, CfgItem *i, const wchar_t *name, int scripts_enabled) {
+ InCriticalSection in_cs(&cs_grp);
+ CfgGroup *g = static_cast<CfgGroup *>(instantiate(groupid, GROUP_CFGGROUP, NULL, scripts_enabled));
+ ASSERTPR(g != NULL, StringPrintf("couldn't load groupid '%S'", groupid));
+ g->setAttr(i, name);
+ grouplist.addItem(g);
+ return g;
+}
+
+#endif
+
+int GroupMgr::destroy(Group *group) {
+ InCriticalSection in_cs(&cs_grp);
+ if (!grouplist.haveItem(group)) {
+ DebugStringW(L"you cannot destroy a group that you have not instatiated\n");
+ return 0;
+ }
+ delete group;
+ grouplist.removeItem(group);
+ return 1;
+}
+
+int GroupMgr::exists(const wchar_t *groupid)
+{
+ SkinItem *si = guiTree->getGroupDef(groupid);
+ if (si) return 1;
+ return 0;
+}
+
+
+PtrList<Group> GroupMgr::grouplist;
+CriticalSection GroupMgr::cs_grp;
diff --git a/Src/Wasabi/api/skin/groupmgr.h b/Src/Wasabi/api/skin/groupmgr.h
new file mode 100644
index 00000000..4e4457ca
--- /dev/null
+++ b/Src/Wasabi/api/skin/groupmgr.h
@@ -0,0 +1,42 @@
+#ifndef __GROUPMGR_H
+#define __GROUPMGR_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/bfcstring.h>
+#include <api/skin/skinparse.h>
+#include <bfc/critsec.h>
+
+class Group;
+class CfgItem;
+
+class ifc_window;
+class SkinItem;
+
+class CfgGroupEntry
+{
+ public:
+ CfgGroupEntry(const wchar_t *_id, int _type) : id(_id), type(_type) {}
+ ~CfgGroupEntry() {}
+
+ StringW id;
+ int type;
+};
+
+class GroupMgr
+{
+ public:
+ static Group *instantiate(const wchar_t *groupid, int grouptype=GROUP_GROUP, SkinItem *specific_item=NULL, int scripts_enabled=1);
+#ifdef WASABI_COMPILE_CONFIG
+ static Group *instantiate(const wchar_t *groupid, CfgItem *i, const wchar_t *name, int scripts_enabled);
+#endif
+ static int destroy(Group *group);
+ static int hasGroup(Group *g) { return grouplist.haveItem(g); }
+ static int getNumGroups() { return grouplist.getNumItems(); }
+ static int exists(const wchar_t *groupid);
+
+ private:
+ static PtrList<Group> grouplist;
+ static CriticalSection cs_grp;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/groupwndcreate.cpp b/Src/Wasabi/api/skin/groupwndcreate.cpp
new file mode 100644
index 00000000..adf5daa6
--- /dev/null
+++ b/Src/Wasabi/api/skin/groupwndcreate.cpp
@@ -0,0 +1,51 @@
+#include <precomp.h>
+
+#include "groupwndcreate.h"
+
+#include <api/skin/guitree.h>
+#include <api/skin/groupmgr.h>
+
+// 5/15/2002, removed serving of groups by guid xui param, guid is 'non-overriden window guaranteed', groupid is 'allow override implicitly'
+
+/*int GroupWndCreateSvc::testGuid(GUID g) {
+ return (GuiTree::getGroupDef(g) >= 0);
+}
+
+api_window *GroupWndCreateSvc::createWindowByGuid(GUID g, api_window *parent) {
+ int n = GuiTree::getGroupDef(g);
+ if (n < 0) return NULL;
+
+ return createGuiTreeItem(n, parent);
+}*/
+
+ifc_window *GroupWndCreateSvc::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int i)
+{
+ SkinItem *item = guiTree->enumGroupDefOfType(windowtype, i);
+ if (item == NULL) return NULL;
+
+ return createGuiTreeItem(item, parent);
+}
+
+ifc_window *GroupWndCreateSvc::createGuiTreeItem(SkinItem*item, ifc_window *parent)
+{
+ ifc_window *wnd = GroupMgr::instantiate(NULL, GROUP_GROUP, item);
+ if (!wnd) return NULL;
+ wnd->setParent(parent);
+ group_list.addItem(wnd);
+ num_group_list = group_list.getNumItems();
+ return wnd;
+}
+
+int GroupWndCreateSvc::destroyWindow(ifc_window *w)
+{
+ if (group_list.haveItem(w))
+ {
+ group_list.removeItem(w);
+ WASABI_API_SKIN->group_destroy(w);
+ num_group_list = group_list.getNumItems();
+ return 1;
+ }
+ return 0;
+}
+
+int GroupWndCreateSvc::num_group_list = 0;
diff --git a/Src/Wasabi/api/skin/groupwndcreate.h b/Src/Wasabi/api/skin/groupwndcreate.h
new file mode 100644
index 00000000..c142e2c4
--- /dev/null
+++ b/Src/Wasabi/api/skin/groupwndcreate.h
@@ -0,0 +1,25 @@
+#ifndef __WNDCREATE_H
+#define __WNDCREATE_H
+
+#include <api/service/svcs/svc_wndcreate.h>
+#include <bfc/ptrlist.h>
+
+class GroupWndCreateSvc : public svc_windowCreateI
+{
+public:
+ static const char *getServiceName() { return "WindowType to Group window creator"; }
+
+ virtual int testType(const wchar_t *windowtype) { return 1; }
+ // virtual int testGuid(GUID g) ;
+ // virtual ifc_window *createWindowByGuid(GUID g, ifc_window *parent);
+ virtual ifc_window *createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n);
+ virtual int destroyWindow(ifc_window *w);
+
+ static int num_group_list;
+
+private:
+ ifc_window *createGuiTreeItem(SkinItem *item, ifc_window *parent);
+ PtrList<ifc_window> group_list;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/guitree.cpp b/Src/Wasabi/api/skin/guitree.cpp
new file mode 100644
index 00000000..e5196f28
--- /dev/null
+++ b/Src/Wasabi/api/skin/guitree.cpp
@@ -0,0 +1,379 @@
+#include <precomp.h>
+#include "guitree.h"
+#include <api/skin/skinparse.h>
+#include <api/syscb/callbacks/wndcb.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/autopopup.h>
+#endif
+#include <api/skin/skin.h>
+#include <bfc/bfc_assert.h>
+
+GuiTree *guiTree=NULL;
+
+GuiTreeItem::GuiTreeItem(int type, const wchar_t *name, ifc_xmlreaderparams *p, int scriptid, const wchar_t *path, GUID g, const wchar_t *windowtype, const wchar_t *xuitag)
+{
+ if (p)
+ {
+ for (size_t i=0;i!=p->getNbItems();i++)
+ params.addItem(p->getItemName(i), p->getItemValue(i));
+ }
+ object_type = type;
+ object_name = name;
+ scriptId = scriptid;
+ rootpath = path;
+ guid = g;
+ idx=-1;
+ seccount = incrementor++;
+ wndtype = windowtype;
+ tag = xuitag;
+}
+
+int GuiTreeItem::incrementor=0;
+
+GuiTreeItem::~GuiTreeItem() {
+}
+
+int GuiTreeItem::getScriptId() {
+ return scriptId;
+}
+
+ifc_xmlreaderparams *GuiTreeItem::getParams()
+{
+ // TODO: benski> helps replicate old logic.. we really fix the parts of the code that are assuming getValue() always succeeds with this returned object
+ if (params.getNbItems())
+ return &params;
+ else
+ return 0;
+}
+
+const wchar_t *GuiTreeItem::getXmlRootPath() {
+ return rootpath;
+}
+
+
+int GuiTreeItem::getType() {
+ return object_type;
+}
+
+const wchar_t *GuiTreeItem::getName()
+{
+ return object_name;
+}
+
+SkinItem *GuiTreeItem::getAncestor() {
+ if (object_type == XML_TAG_GROUPDEF)
+ return guiTree->getGroupDefAncestor(this);
+ if (object_type == XML_TAG_CONTAINER)
+ return guiTree->getContainerAncestor(this);
+ return NULL;
+}
+
+GuiTree::GuiTree() {
+ cached=-1;
+ cachedtype=-1;
+ cached_guid_idx=-1;
+ cached_guid=INVALID_GUID;
+ lastdefinedgroupdef = NULL;
+}
+
+GuiTree::~GuiTree() {
+ list.deleteAll();
+ groupdefs.removeAll();
+ wndtypes.removeAll();
+ //groupdefsbyguid.removeAll();
+}
+
+void GuiTree::addItem(int object_type, const wchar_t *name, ifc_xmlreaderparams *params, int scriptid, const wchar_t *rootpath) {
+ cached = -1;
+ cached_guid_idx = -1;
+ GUID guid=INVALID_GUID;
+ const wchar_t *wtype=NULL;
+ int has_ancestor=0;
+ const wchar_t *xuitag=NULL;
+
+ const wchar_t *_id = NULL;
+ if (params)
+ {
+ _id = params->getItemValue(L"id");
+ xuitag = params->getItemValue(L"xuitag");
+#ifdef WASABI_COMPILE_WNDMGR
+ if (params->getItemValueInt(L"register_autopopup"))
+ AutoPopup::registerGroupId(scriptid, _id, params->getItemValue(L"name"));
+#endif
+ const wchar_t *strguid = params->getItemValue(L"guid");
+ if (strguid)
+ guid = nsGUID::fromCharW(strguid);
+ wtype = params->getItemValue(L"windowtype");
+ }
+ if (object_type == XML_TAG_GROUPDEF && params)
+ {
+ has_ancestor = (getGroupDef(_id) != NULL);
+ }
+
+ GuiTreeItem *item = new GuiTreeItem(object_type, name, params, scriptid, rootpath, guid, wtype, xuitag);
+ item->setIdx(list.getNumItems());
+ list.addItem(item);
+
+ if (object_type == XML_TAG_GROUPDEF && params) {
+ lastdefinedgroupdef = item;
+// groupdefsbyguid.setAutoSort(0);
+ groupdefs.addItem(item);
+// groupdefsbyguid.addItem(item);
+ if (wtype && *wtype) {
+ wndtypes.addItem(item);
+ deferredInvalidateType(wtype);
+ }
+ if (xuitag && *xuitag) {
+ xuigroupdefs.addItem(item);
+ }
+ if (has_ancestor)
+ deferredInvalidateGroup(_id);
+ } else if (object_type == XML_TAG_CONTAINER && params && (params->getItemValueInt(L"dynamic", 0) == 1)) {
+ containers_by_id.setAutoSort(0);
+ containers_by_id.addItem(item);
+ }
+}
+
+int GuiTree::getNumObject() {
+ return list.getNumItems();
+}
+
+int GuiTree::getNumObject(int object_type) {
+ if (cachedtype == object_type && cached != -1) return cached;
+ int n=0;
+ for (int i=0;i<list.getNumItems();i++) {
+ GuiTreeItem *it = list.enumItem(i);
+ if (it->getType() == object_type)
+ n++;
+ }
+ cachedtype = object_type;
+ cached = n;
+ return n;
+}
+
+SkinItem *GuiTree::getObject(int object_type, int nth) {
+ int n=0;
+ for (int i=0;i<list.getNumItems();i++) {
+ GuiTreeItem *it = list.enumItem(i);
+ if (it && it->getType() == object_type) {
+ if (n++ == nth) return it;
+ }
+ }
+ return NULL;
+}
+
+SkinItem *GuiTree::getGroupDef(const wchar_t *id)
+{
+ return groupdefs.findLastItem(id);
+}
+
+SkinItem *GuiTree::getXuiGroupDef(const wchar_t *xuitag)
+{
+ xuigroupdefs.sort(); // doesn't sort if not necessary
+ return xuigroupdefs.findLastItem(xuitag);
+}
+
+SkinItem *GuiTree::getGroupDefAncestor(SkinItem *_item)
+{
+ //groupdefs.sort(); // doesn't sort if not necessary
+ int pos = -1;
+ GuiTreeItem *item = static_cast<GuiTreeItem *>(_item);
+ if (!item) return NULL;
+ ASSERT(item->getParams() != NULL);
+ const wchar_t *iid = item->getParams()->getItemValue(L"id");
+
+ pos = groupdefs.searchItem(item);
+ if (pos <= 0) return NULL;
+ pos--;
+
+ GuiTreeItem *ritem = groupdefs.enumItem(pos);
+ if (!ritem) return NULL;
+ ASSERT(ritem->getParams() != NULL);
+ if (WCSICMP(iid, ritem->getParams()->getItemValue(L"id"))) return NULL;
+ return ritem;
+}
+
+SkinItem *GuiTree::getContainerAncestor(SkinItem *_item) {
+ int pos = -1;
+ GuiTreeItem *item = static_cast<GuiTreeItem *>(_item);
+ if (!item) return NULL;
+ ASSERT(item->getParams() != NULL);
+ const wchar_t *iid = item->getParams()->getItemValue(L"id");
+
+ pos = containers_by_id.searchItem(item);
+
+ if (pos <= 0) return NULL;
+ pos--;
+
+ GuiTreeItem *ritem = containers_by_id.enumItem(pos);
+ if (!ritem) return NULL;
+ ASSERT(ritem->getParams() != NULL);
+ if (WCSICMP(iid, ritem->getParams()->getItemValue(L"id"))) return NULL;
+ return ritem;
+}
+
+
+/*int GuiTree::getGroupDef(GUID guid) {
+ groupdefsbyguid.sort(); // doesn't sort if not necessary
+ GuiTreeItem *item = groupdefsbyguid.findItem(reinterpret_cast<const char *>(&guid));
+ if (item)
+ return item->getIdx();
+ return -1;
+}*/
+
+SkinItem *GuiTree::enumGroupDefOfType(const wchar_t *type, int n) {
+ int c = 0;
+ foreach(wndtypes)
+ GuiTreeItem *item = wndtypes.getfor();
+ if (WCSCASEEQLSAFE(type, item->getWindowType())) {
+ if (c == n) {
+/* if (item->getGuid() != INVALID_GUID) { // see if it has a GUID, in which case we need to instantiate the last overriden version
+ int n = getGroupDef(item->getGuid());
+ if (n != -1) return n;
+ }*/
+ // take its groupid and find its latest overriden version
+ ifc_xmlreaderparams *p = item->getParams();
+ if (p)
+ {
+ const wchar_t *id = p->getItemValue(L"id");
+ if (id)
+ {
+ SkinItem *m = getGroupDef(id);
+ if (m != NULL) return m;
+ }
+ }
+ return item;
+ }
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+
+int GuiTree::getObjectType(SkinItem *item) {
+ GuiTreeItem *i = static_cast<GuiTreeItem *>(item);
+ return i->getType();
+}
+
+PtrList<GuiTreeItem> *GuiTree::getList() {
+ return &list;
+}
+
+PtrList<GuiTreeItem> *GuiTree::getGroupList() {
+ return &groupdefs;
+}
+
+SkinItem *GuiTree::getContainerById(const wchar_t *id)
+{
+ containers_by_id.sort(); // doesn't sort if not necessary
+ return containers_by_id.findLastItem(id);
+}
+
+void GuiTree::removeSkinPart(int scriptid) {
+ for (int i=0;i<list.getNumItems();i++) {
+ GuiTreeItem *item = list.enumItem(i);
+ if (item->getScriptId() == scriptid) {
+ ifc_xmlreaderparams *par = item->getParams();
+ if (item->getType() == XML_TAG_CONTAINER && par != NULL) {
+ int p = containers_by_id.searchItem(item);
+ if (p != -1)
+ containers_by_id.removeByPos(p);
+ }
+ if (item->getType() == XML_TAG_GROUPDEF && par != NULL)
+ {
+ const wchar_t *grpid = par->getItemValue(L"id");
+ if (grpid)
+ {
+ int p = groupdefs.searchItem(item);
+ if (p != -1)
+ groupdefs.removeByPos(p);
+ p = xuigroupdefs.searchItem(item);
+ if (p != -1)
+ xuigroupdefs.removeByPos(p);
+ p = wndtypes.searchItem(item);
+ if (p != -1) {
+ deferredInvalidateType(item->getWindowType());
+ wndtypes.removeByPos(p);
+ }
+ deferredInvalidateGroup(grpid);
+ }
+ }
+ delete item;
+ list.removeByPos(i);
+ i--;
+ }
+ }
+ foreach(list)
+ list.getfor()->setIdx(foreach_index);
+ endfor;
+}
+
+void GuiTree::reset() {
+ list.deleteAll();
+ groupdefs.removeAll();
+ wndtypes.removeAll();
+ xuigroupdefs.removeAll();
+ containers_by_id.removeAll();
+}
+
+void GuiTree::deferredInvalidateGroup(const wchar_t *id) {
+ if (!Skin::isDynamicGroupReloadEnabled()) return;
+ if (!id || !*id) return;
+ StringW *s = new StringW;
+ s->setValue(id);
+
+ GuiTreeCB *cb = new GuiTreeCB;
+ cb->cmd = INVALIDATEGRP;
+ cb->ptr = s;
+
+ timerclient_postDeferredCallback(CB_GUITREE, reinterpret_cast<intptr_t>(cb));
+}
+
+void GuiTree::deferredInvalidateType(const wchar_t *type) {
+ if (!Skin::isDynamicGroupReloadEnabled()) return;
+ StringW *s = new StringW;
+ s->setValue(type);
+
+ GuiTreeCB *cb = new GuiTreeCB;
+ cb->cmd = INVALIDATETYPE;
+ cb->ptr = s;
+
+ timerclient_postDeferredCallback(CB_GUITREE, reinterpret_cast<intptr_t>(cb));
+}
+
+int GuiTree::timerclient_onDeferredCallback(intptr_t param1, intptr_t param2)
+{
+ if (param1 == CB_GUITREE) {
+ GuiTreeCB *c = reinterpret_cast<GuiTreeCB *>(param2);
+ switch (c->cmd) {
+ case INVALIDATEGRP: {
+ StringW *s = reinterpret_cast<StringW *>(c->ptr);
+ WndInfo wi;
+ wi.groupid = s->getValue();
+ wi.wndtype = NULL;
+ wi.guid = INVALID_GUID;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::GROUPCHANGE, reinterpret_cast<intptr_t>(&wi));
+ delete s;
+ break;
+ }
+ case INVALIDATETYPE: {
+ StringW *s = reinterpret_cast<StringW *>(c->ptr);
+ WndInfo wi;
+ ZERO(wi);
+ wi.wndtype = s->getValue();
+ wi.guid = INVALID_GUID;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::TYPECHANGE, reinterpret_cast<intptr_t>(&wi));
+ delete s;
+ break;
+ }
+ }
+ return 1;
+ }
+ return GUITREE_PARENT::timerclient_onDeferredCallback(param1, param2);
+}
+
+int GuiTree::getObjectIdx(SkinItem *item) {
+ if (item == NULL) return -1;
+ return (static_cast<GuiTreeItem*>(item))->getIdx();
+}
diff --git a/Src/Wasabi/api/skin/guitree.h b/Src/Wasabi/api/skin/guitree.h
new file mode 100644
index 00000000..cdf74cf0
--- /dev/null
+++ b/Src/Wasabi/api/skin/guitree.h
@@ -0,0 +1,171 @@
+#ifndef __GUITREE_H
+#define __GUITREE_H
+
+#include <bfc/string/bfcstring.h>
+#include <bfc/ptrlist.h>
+#include <bfc/nsguid.h>
+#include <api/timer/timerclient.h>
+#include <api/xml/xmlreader.h>
+#include <api/xml/xmlparamsi.h>
+#include <api/skin/skinitem.h>
+#include <bfc/string/StringW.h>
+
+#define CB_GUITREE 0x987
+
+#define INVALIDATEGRP 1
+#define INVALIDATETYPE 2
+
+class GuiTreeCB {
+ public:
+ int cmd;
+ StringW *ptr;
+};
+
+class GuiTreeItem : public SkinItemI
+{
+ public:
+ GuiTreeItem(int type, const wchar_t *name, ifc_xmlreaderparams *p, int scriptid, const wchar_t *rootpath, GUID g, const wchar_t *windowtype, const wchar_t *xuitag);
+ virtual ~GuiTreeItem();
+ virtual int getType();
+ virtual const wchar_t *getName();
+ virtual int getSkinPartId() { return getScriptId(); }
+ virtual int getScriptId();
+ virtual ifc_xmlreaderparams *getParams();
+ virtual const wchar_t *getXmlRootPath();
+ virtual void setIdx(int i) { idx = i; }
+ virtual int getIdx() { return idx; }
+ virtual int getSecCount() { return seccount; }
+ virtual void setGuid(GUID g) { guid = g; }
+ virtual GUID getGuid() { return guid; }
+ virtual const wchar_t *getWindowType() { return wndtype; }
+ virtual const wchar_t *getXuiTag() { return tag; }
+ virtual void setXuiTag(const wchar_t *xuitag) { tag = xuitag; }
+ virtual SkinItem *getAncestor();
+
+ private:
+ XmlReaderParamsI params;
+ int object_type;
+ StringW object_name;
+ int scriptId;
+ StringW rootpath;
+ int idx;
+ int seccount;
+ GUID guid;
+ StringW wndtype;
+ StringW tag;
+
+ static int incrementor;
+};
+
+class SortGuiTreeItem
+{
+public:
+ static int compareItem(GuiTreeItem *p1, GuiTreeItem *p2) {
+ int r = WCSICMP(p1->getParams()->getItemValue(L"id"), p2->getParams()->getItemValue(L"id"));
+ if (!r) {
+ if (p1->getScriptId() < p2->getScriptId()) return -1;
+ if (p1->getScriptId() > p2->getScriptId()) return 1;
+ if (p1->getSecCount() < p2->getSecCount()) return -1;
+ if (p1->getSecCount() > p2->getSecCount()) return 1;
+ return 0;
+ }
+ return r;
+ }
+ static int compareAttrib(const wchar_t *attrib, GuiTreeItem *item) {
+ return WCSICMP(attrib, item->getParams()->getItemValue(L"id"));
+ }
+};
+
+class SortGuiTreeItemByXuiTag {
+public:
+ static int compareItem(GuiTreeItem *p1, GuiTreeItem *p2) {
+ int r = WCSICMP(p1->getParams()->getItemValue(L"xuitag"), p2->getParams()->getItemValue(L"xuitag"));
+ if (!r) {
+ if (p1->getScriptId() < p2->getScriptId()) return -1;
+ if (p1->getScriptId() > p2->getScriptId()) return 1;
+ if (p1->getSecCount() < p2->getSecCount()) return -1;
+ if (p1->getSecCount() > p2->getSecCount()) return 1;
+ return 0;
+ }
+ return r;
+ }
+ static int compareAttrib(const wchar_t *attrib, GuiTreeItem *item) {
+ return WCSICMP(attrib, item->getParams()->getItemValue(L"xuitag"));
+ }
+};
+
+class SortGuiTreeItemByGuid
+{
+public:
+ static int compareItem(GuiTreeItem *p1, GuiTreeItem *p2) {
+ GUID g1 = p1->getGuid();
+ GUID g2 = p2->getGuid();
+ if (g1 == g2) {
+ if (p1->getScriptId() < p2->getScriptId()) return -1;
+ if (p1->getScriptId() > p2->getScriptId()) return 1;
+ if (p1->getSecCount() < p2->getSecCount()) return -1;
+ if (p1->getSecCount() > p2->getSecCount()) return 1;
+ return 0;
+ }
+ return nsGUID::compare(g1, g2) < 0 ? -1 : 1;
+ }
+ static int compareAttrib(const wchar_t *attrib, GuiTreeItem *item) {
+ const GUID *g = reinterpret_cast<const GUID *>(attrib);
+ ASSERT(g);
+ GUID g1 = *g;
+ GUID g2 = item->getGuid();
+ if (g1 == g2) return 0;
+ return nsGUID::compare(g1, g2) < 0 ? -1 : 1;
+ }
+};
+
+#define GUITREE_PARENT TimerClientDI
+class GuiTree : public GUITREE_PARENT {
+ public:
+
+ GuiTree();
+ virtual ~GuiTree();
+
+ void addItem(int object_type, const wchar_t *object_name, ifc_xmlreaderparams *params, int scriptId, const wchar_t *rootpath);
+ SkinItem *getGroupDef(const wchar_t *id);
+ SkinItem *enumGroupDefOfType(const wchar_t *type, int n);
+ SkinItem *getGroupDefAncestor(SkinItem *item);
+ SkinItem *getContainerAncestor(SkinItem *item);
+ //int getGroupDef(GUID g);
+ SkinItem *getXuiGroupDef(const wchar_t *xuitag);
+ int getObjectType(SkinItem *item);
+ int getNumObject(); // total number of objects
+ int getNumObject(int object_type); // return the number of objects of this type
+ SkinItem *getObject(int object_type, int nth); // get nth object_type, return its index
+ SkinItem *getContainerById(const wchar_t *id);
+ int getObjectIdx(SkinItem *item);
+ void reset(void);
+ PtrList<GuiTreeItem> *getList();;
+ PtrList<GuiTreeItem> *getGroupList();;
+ void removeSkinPart(int scriptid);
+ void deferredInvalidateGroup(const wchar_t *id);
+ void deferredInvalidateType(const wchar_t *type);
+ int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2);
+ SkinItem *getLastDefinedGroup() { return lastdefinedgroupdef; }
+ SkinItem *enumGroupDef(int n) { return groupdefs.enumItem(n); }
+ int getNumGroupDefs() { return groupdefs.getNumItems(); }
+
+
+ private:
+ int cached;
+ int cachedtype;
+ PtrList<GuiTreeItem> list;
+ PtrListInsertMultiSorted<GuiTreeItem, SortGuiTreeItem> groupdefs;
+// PtrListQuickMultiSorted<GuiTreeItem, SortGuiTreeItemByGuid> groupdefsbyguid;
+ PtrListQuickMultiSorted<GuiTreeItem, SortGuiTreeItemByXuiTag> xuigroupdefs;
+ PtrListQuickMultiSorted<GuiTreeItem, SortGuiTreeItem> containers_by_id;
+ PtrList<GuiTreeItem> wndtypes;
+ int cached_guid_idx;
+ GUID cached_guid;
+ SkinItem *lastdefinedgroupdef;
+};
+
+extern GuiTree *guiTree;
+
+#endif
+
diff --git a/Src/Wasabi/api/skin/nakedobject.cpp b/Src/Wasabi/api/skin/nakedobject.cpp
new file mode 100644
index 00000000..9e0a3a78
--- /dev/null
+++ b/Src/Wasabi/api/skin/nakedobject.cpp
@@ -0,0 +1,34 @@
+#include <precomp.h>
+#include "nakedobject.h"
+
+NakedObject::NakedObject() {
+ reentry_onresize = 0;
+ reentry_onsetvisible = 0;
+}
+
+int NakedObject::getPreferences(int what) {
+ return 0;
+}
+
+int NakedObject::onResize() {
+ int rt = NAKEDOBJECT_PARENT::onResize();
+ RECT r;
+ getClientRect(&r);
+ if (!reentry_onresize && r.left != r.right || r.top != r.bottom) {
+ reentry_onresize = 1;
+ resize(r.left, r.top, 0, 0);
+ reentry_onresize = 0;
+ }
+ return rt;
+}
+
+void NakedObject::onSetVisible(int i) {
+ NAKEDOBJECT_PARENT::onSetVisible(i);
+ if (!i) return;
+ if (!reentry_onsetvisible) {
+ reentry_onsetvisible = 1;
+ setVisible(0);
+ reentry_onsetvisible = 0;
+ }
+}
+
diff --git a/Src/Wasabi/api/skin/nakedobject.h b/Src/Wasabi/api/skin/nakedobject.h
new file mode 100644
index 00000000..ad689533
--- /dev/null
+++ b/Src/Wasabi/api/skin/nakedobject.h
@@ -0,0 +1,24 @@
+#ifndef __NAKEDOBJECT_H
+#define __NAKEDOBJECT_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+// NakedObject, an invisible GuiObject
+
+#define NAKEDOBJECT_PARENT GuiObjectWnd
+
+class NakedObject : public GuiObjectWnd {
+ public:
+ NakedObject();
+ virtual ~NakedObject() {}
+
+ virtual int getPreferences(int what);
+ virtual int onResize();
+ virtual void onSetVisible(int i);
+
+ protected:
+ int reentry_onresize;
+ int reentry_onsetvisible;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/objectactuator.cpp b/Src/Wasabi/api/skin/objectactuator.cpp
new file mode 100644
index 00000000..f9eb1ee1
--- /dev/null
+++ b/Src/Wasabi/api/skin/objectactuator.cpp
@@ -0,0 +1,106 @@
+#include <precomp.h>
+#include "objectactuator.h"
+#include <api/console/console.h>
+#include <bfc/parse/paramparser.h>
+#include <api/script/scriptguid.h>
+
+XMLParamPair ObjectActuator::params[]=
+{
+ {OBJECTACTUATOR_GROUP, L"GROUP"},
+ {OBJECTACTUATOR_TARGET, L"TARGET"}
+};
+
+// -----------------------------------------------------------------------
+ObjectActuator::ObjectActuator()
+{
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+void ObjectActuator::CreateXMLParameters(int master_handle)
+{
+ //OBJECTACTUATOR_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ObjectActuator::~ObjectActuator() {
+}
+
+// -----------------------------------------------------------------------
+int ObjectActuator::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return OBJECTACTUATOR_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case OBJECTACTUATOR_TARGET:
+ if (actuator_wantTargetParam())
+ actuator_setTarget(value);
+ break;
+ case OBJECTACTUATOR_GROUP:
+ if (actuator_wantGroupParam())
+ actuator_setGroup(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ObjectActuator::actuator_setTarget(const wchar_t *value) {
+ objectsid = value;
+ if (isInited() && actuator_wantAutoPerform())
+ performActions();
+}
+
+// -----------------------------------------------------------------------
+void ObjectActuator::actuator_setGroup(const wchar_t *value) {
+ groupid = value;
+}
+
+// -----------------------------------------------------------------------
+int ObjectActuator::onInit() {
+ int rt = OBJECTACTUATOR_PARENT::onInit();
+
+ if (actuator_wantAutoPerform()) performActions();
+
+ return rt;
+}
+
+
+// -----------------------------------------------------------------------
+void ObjectActuator::performActions()
+{
+ ifc_window *group = getParent();
+
+ if (!groupid.isempty())
+ {
+ GuiObject *o = getGuiObject()->guiobject_findObject(groupid);
+ if (o != NULL) {
+ group = o->guiobject_getRootWnd();
+ }
+ }
+
+ GuiObject *go = static_cast<GuiObject *>(group->getInterface(guiObjectGuid));
+ if (go == NULL) {
+ DebugStringW(L"%s:group:%s\n", getActuatorTag(), groupid.getValue());
+ return;
+ }
+
+ ParamParser pp(objectsid);
+ for (int i=0;i<pp.getNumItems();i++) {
+ GuiObject *target = go->guiobject_findObject(pp.enumItem(i));
+ if (target != NULL)
+ actuator_onPerform(target);
+ else
+ DebugStringW(L"%s:%s/%s\n", getActuatorTag(), groupid.getValue(), objectsid.getValue());
+ }
+}
+
+const wchar_t *ObjectActuator::getActuatorTag() {
+ return L"ObjectActuator";
+}
diff --git a/Src/Wasabi/api/skin/objectactuator.h b/Src/Wasabi/api/skin/objectactuator.h
new file mode 100644
index 00000000..c5437a1c
--- /dev/null
+++ b/Src/Wasabi/api/skin/objectactuator.h
@@ -0,0 +1,49 @@
+#ifndef __OBJECTACTUATOR_H
+#define __OBJECTACTUATOR_H
+
+#include <api/skin/nakedobject.h>
+
+#define OBJECTACTUATOR_PARENT NakedObject
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+class ObjectActuator : public OBJECTACTUATOR_PARENT {
+
+ public:
+
+ ObjectActuator();
+ virtual ~ObjectActuator();
+
+ virtual int onInit();
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void actuator_setTarget(const wchar_t *value);
+ virtual void actuator_setGroup(const wchar_t *value);
+
+ virtual int actuator_wantTargetParam() { return 1; }
+ virtual int actuator_wantGroupParam() { return 1; }
+ virtual int actuator_wantAutoPerform() { return 1; }
+ virtual void actuator_onPerform(GuiObject *target) { } // called back n times for n targets found (separated by ';'), guaranteed non NULL
+
+ virtual const wchar_t *getActuatorTag(); // for error msgs purposes
+
+
+protected:
+ void performActions();
+/*static */void CreateXMLParameters(int master_handle);
+ private:
+ static XMLParamPair params[];
+ int myxuihandle;
+
+
+ enum {
+ OBJECTACTUATOR_TARGET= 0,
+ OBJECTACTUATOR_GROUP,
+ };
+
+ StringW groupid;
+ StringW objectsid;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/regioncache.cpp b/Src/Wasabi/api/skin/regioncache.cpp
new file mode 100644
index 00000000..68dc58aa
--- /dev/null
+++ b/Src/Wasabi/api/skin/regioncache.cpp
@@ -0,0 +1,32 @@
+#include "precomp.h"
+#include "regioncache.h"
+
+
+RegionServer *RegionCache::requestSkinRegion(const wchar_t *filename)
+{
+ int n = -1;
+ cache.findItem(filename, &n);
+ if (n == -1) return NULL;
+
+ RegionCacheItem *el = cache.enumItem(n);
+// if (el->region != NULL) el->region->getRegion()->debug();
+ return el->region;
+}
+
+void RegionCache::cacheSkinRegion(const wchar_t *filename, api_region *r)
+{
+ int n = -1;
+ cache.findItem(filename, &n);
+ if (n == -1) return;
+ RegionCacheItem *el = cache.enumItem(n);
+ ASSERT(el != NULL);
+ if (el->region != NULL) {
+ DebugString("Trying to cache a region but cache is already set!\n");
+ return;
+ }
+ el->region = new CacheRegionServer(r);
+ //el->region->getRegion()->debug();
+}
+
+
+PtrListQuickSorted<RegionCacheItem, SortRegionCacheItem> RegionCache::cache;
diff --git a/Src/Wasabi/api/skin/regioncache.h b/Src/Wasabi/api/skin/regioncache.h
new file mode 100644
index 00000000..ea2df961
--- /dev/null
+++ b/Src/Wasabi/api/skin/regioncache.h
@@ -0,0 +1,53 @@
+#ifndef __REGIONCACHE_H
+#define __REGIONCACHE_H
+
+#include <bfc/string/StringW.h>
+#include <tataki/region/region.h>
+#include <bfc/ptrlist.h>
+
+class CacheRegionServer : public RegionServerI {
+ public:
+ CacheRegionServer(api_region *r) {
+ reg = new RegionI(r->getOSHandle());
+ }
+ ~CacheRegionServer() {
+ delete reg;
+ }
+
+ virtual api_region *getRegion() {
+ return reg;
+ }
+
+ private:
+ RegionI *reg;
+};
+
+struct RegionCacheItem {
+ RegionCacheItem(const wchar_t *filename) : region(NULL) { }
+ virtual ~RegionCacheItem() { }
+ StringW filename;
+ CacheRegionServer *region;
+};
+
+class SortRegionCacheItem {
+public:
+ static int compareItem(RegionCacheItem *p1, RegionCacheItem *p2) {
+ return WCSICMP(p1->filename, p2->filename);
+ }
+ static int compareAttrib(const wchar_t *attrib, RegionCacheItem *item) {
+ return WCSICMP(attrib, item->filename);
+ }
+};
+
+
+class RegionCache {
+ public:
+
+ static RegionServer *requestSkinRegion(const wchar_t *id);
+ static void cacheSkinRegion(const wchar_t *id, api_region *r);
+
+ static PtrListQuickSorted<RegionCacheItem, SortRegionCacheItem> cache;
+ static int getNumCaches() { return cache.getNumItems(); }
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/skin.cpp b/Src/Wasabi/api/skin/skin.cpp
new file mode 100644
index 00000000..9348d4c9
--- /dev/null
+++ b/Src/Wasabi/api/skin/skin.cpp
@@ -0,0 +1,812 @@
+#include <precomp.h>
+#include <api.h>
+#include "skin.h"
+#include <api/skin/skinbmps.h>
+#include <tataki/canvas/bltcanvas.h>
+#include <api/wnd/basewnd.h>
+#include <tataki/bitmap/bitmap.h>
+#include <bfc/parse/pathparse.h>
+#include <bfc/file/readdir.h>
+//#include <api/wac/main.h> // CUT!!
+#include <api/skin/skinparse.h>
+#include <api/wac/compon.h>
+
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/skinembed.h>
+#endif
+
+#include <api/script/vcpu.h>
+#include <api/skin/skinelem.h>
+#include <api/application/wkc.h>
+#include <api/skin/gammamgr.h>
+#include <api/wnd/wndtrack.h>
+
+#ifdef WASABI_COMPILE_PAINTSETS
+#include <api/wnd/paintset.h>
+#endif
+
+#include <bfc/string/StringW.h>
+
+#ifdef WIN32
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+#endif
+
+// Version number has now a style of x.yz (same as gen_ff version)
+#define SKIN_LEGACY_VERSION 80.f // oldest supported is 0.8
+#define SKIN_VERSION 136.f // current version is 1.36
+
+Skin *tha = NULL;
+
+
+static wchar_t *loadSkinList = NULL, skName[64];
+
+Skin::Skin()
+{
+ if (deferedskinset == NULL)
+ {
+ deferedskinset = new SkinTimer();
+ }
+ base = NULL;
+ scaled = NULL;
+ scale_x = 0;
+ scale_y = 0;
+ validRgn = NULL;
+ resizing = FALSE;
+}
+
+Skin::~Skin()
+{
+ if (this == tha)
+ {
+ delete deferedskinset;
+ deferedskinset = NULL;
+ }
+ delete validRgn;
+ validRgn = NULL;
+ delete base;
+ delete scaled;
+ if (this == tha)
+ {
+ if (loadSkinList)
+ {
+ FREE(loadSkinList);
+ loadSkinList = NULL;
+ }
+ }
+}
+
+Skin *Skin::getCurSkin()
+{
+ return tha;
+}
+
+void Skin::setSkinName(const wchar_t *newskinname, const wchar_t *skinpath)
+{
+ if (newskinname)
+ skinName = newskinname;
+ else
+ skinName = WASABI_API_LNGSTRINGW_BUF(IDS_NO_SKIN_LOADED_,skName,64);
+
+ if (skinpath == NULL)
+ {
+ skinPath = WASABI_API_SKIN->getSkinsPath();
+ skinPath.AppendFolder(newskinname);
+ }
+ else
+ {
+ skinPath = skinpath;
+ skinPath.AddBackslash();
+ }
+}
+
+const wchar_t *Skin::getSkinName()
+{
+ return skinName.getValue();
+}
+
+const wchar_t *Skin::getSkinPath()
+{
+ return skinPath.getValue();
+}
+
+const wchar_t *Skin::getDefaultSkinPath()
+{
+ defSkinPath = WASABI_API_SKIN->getSkinsPath();
+ defSkinPath.AppendFolder(L"Default");
+ return defSkinPath;
+}
+
+void Skin::setBaseTexture(const wchar_t *b)
+{
+ if (b == NULL)
+ {
+ delete base;
+ base = NULL;
+ return ;
+ }
+ base = new AutoSkinBitmap();
+ base->setBitmap(b);
+}
+
+void Skin::rescaleBaseTexture(int w, int h)
+{
+ /* if (scaled != NULL && scale_x == w && scale_y == h)
+ return;
+ if ((resizing && (w > m_x || h > m_y)) || (!resizing && (w != m_x || h != m_y)))
+ {
+ delete scaled;
+ int lw = resizing ? maxw : w;
+ int lh = resizing ? maxh : h;
+ scaled = new BltCanvas(lw , lh);
+ m_x = lw; m_y = lh;
+ api_region *reg = new api_region(0,0,lw,lh);
+ scaled->selectClipRgn(reg);
+ delete reg;
+ lastw = w;
+ lasth = h;
+ }
+ // Empty valid region
+ if (validRgn)
+ validRgn->empty();
+ else
+ validRgn = new api_region();
+ scale_x = w;
+ scale_y = h;*/
+}
+
+void Skin::invalidateBaseTexture(Skin *s)
+{ //FG
+ if (!s) s = tha;
+ if (s) s->_invalidateBaseTexture();
+}
+
+void Skin::invalidateAllBaseTextures()
+{ //FG
+ tha->_invalidateBaseTexture();
+ for (int i = 0;i < skinList.getNumItems();i++)
+ {
+ Skin *s = skinList.enumItem(i);
+ s->_invalidateBaseTexture();
+ }
+}
+
+void Skin::unloadAllBaseTextures()
+{
+ if (tha) tha->_unloadBaseTexture();
+ for (int i = 0;i < skinList.getNumItems();i++)
+ {
+ Skin *s = skinList.enumItem(i);
+ s->_unloadBaseTexture();
+ }
+}
+
+void Skin::reloadAllBaseTextures()
+{
+ if (tha) tha->_reloadBaseTexture();
+ for (int i = 0;i < skinList.getNumItems();i++)
+ {
+ Skin *s = skinList.enumItem(i);
+ s->_reloadBaseTexture();
+ }
+ invalidateAllBaseTextures();
+}
+
+void Skin::_unloadBaseTexture()
+{
+ if (base)
+ base->reset();
+}
+
+void Skin::_reloadBaseTexture()
+{
+ if (!tha) return ;
+
+ if (base)
+ base->reload();
+}
+
+void Skin::_invalidateBaseTexture(void)
+{ //FG
+ if (validRgn)
+ validRgn->empty();
+}
+
+void Skin::registerBaseSkin(Skin *s, ifc_window *b)
+{
+ skinList.addItem(s);
+ baseList.addItem(b);
+}
+
+Skin *Skin::unregisterBaseSkin(ifc_window *b)
+{
+ for (int i = 0;i < baseList.getNumItems();i++)
+ {
+ if (baseList.enumItem(i) == b)
+ {
+ Skin *s = skinList.enumItem(i);
+ baseList.delByPos(i);
+ skinList.delByPos(i);
+ if (baseList.getNumItems() == 0)
+ baseList.removeAll();
+ if (skinList.getNumItems() == 0)
+ skinList.removeAll();
+ return s;
+ }
+ }
+ return NULL;
+}
+
+Skin *Skin::baseToSkin(ifc_window *b)
+{
+ if (b == NULL) return NULL;
+ for (int i = 0;i < baseList.getNumItems();i++)
+ if (baseList.enumItem(i) == b)
+ return skinList.enumItem(i);
+ return NULL;
+}
+
+void Skin::renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha)
+{
+ renderBaseTexture(base, baseToSkin(base), c, r, dest, alpha);
+}
+
+void Skin::renderBaseTexture(ifc_window *base, Skin *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha)
+{
+ ASSERT(tha != NULL);
+ if (!s)
+ {
+ DebugStringW(L"Warning, base texture from main wnd?!\n");
+ s = tha;
+ }
+
+ s->_renderBaseTexture(base, c, r, dest, alpha);
+}
+
+void Skin::validateBaseTextureRect(RECT *r)
+{
+ /* if (!base) {
+ ASSERT(!(tha && this == tha));
+ if (origbase)
+ base = new SkinBitmap(origbase, origbase->getWidth(), origbase->getHeight());
+ else
+ base = new SkinBitmap(tha->base, tha->base->getWidth(), tha->base->getHeight());
+ if (!base) return;
+ }
+
+ // make a region with the rect we have to draw
+ api_region *newregion = new api_region(r);
+
+ // check if newregion is enclosed in validRgn, put whatever is outside back into newregion
+ if (newregion->enclosed(validRgn, newregion)) {
+ delete newregion;
+ return;
+ }
+ // compute projected coordinates
+ RECT destRect, srcRect;
+ newregion->getRgnBox(&destRect);
+ srcRect.left = (int)(((float)destRect.left / scale_x) * base->getWidth());
+ srcRect.right = (int)(((float)destRect.right / scale_x) * base->getWidth());
+ srcRect.top = (int)(((float)destRect.top / scale_y) * base->getHeight());
+ srcRect.bottom = (int)(((float)destRect.bottom / scale_y) * base->getHeight());
+
+ // stretch the relevant portion of the image
+ base->stretchRectToRect(scaled, &srcRect, &destRect);
+
+ #if 0 //FG> debug purpose
+ HDC dc = GetDC(NULL);
+ BitBlt(dc, 0, 0, scale_x, scale_y, scaled->getHDC(), 0, 0, SRCCOPY);
+ ReleaseDC(NULL, dc);
+ #endif
+
+ // add this region to the valid region
+ validRgn->add(newregion);
+ delete newregion;*/
+}
+
+#define SAFEROUND(d) ((float)(int)d == d) ? (int)d : (d - (float)(int)d > 0) ? ((int)d)+1 : ((int)d)-1
+
+// FG> Please change this only if you REALLY know what you are doing. this needs to account for basewnd
+// coordinates (start from 0,0), as well as virtualwnd (relative to parent), at any depth (group holding
+// texture as 2nd group of the tree, and rendering the base texture in a basewnd in a virtual in the group),
+// and should handle resized textures and scaled windows. ooch
+
+void Skin::_renderBaseTexture(ifc_window *wndbase, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha)
+{
+ // pick our basetexture
+ AutoSkinBitmap *b = base ? base : tha->base;
+
+ if (!b) return ;
+
+ // srcRect is the source rectangle in the basetexture
+ RECT srcRect;
+ // destProjectedRect is the basetexture rectangle projected to dest coordinates
+ RECT destProjectedRect;
+
+ ifc_window *p = dest;
+ POINT pt;
+ int sx = 0, sy = 0;
+ while (p && p != wndbase)
+ {
+ if (!p->isVirtual())
+ {
+ p->getPosition(&pt);
+ sx += pt.x;
+ sy += pt.y;
+ }
+ p = p->getParent();
+ }
+ ASSERT(p);
+
+ wndbase->getNonClientRect(&destProjectedRect);
+ destProjectedRect.left -= sx;
+ destProjectedRect.top -= sy;
+ destProjectedRect.right -= sx;
+ destProjectedRect.bottom -= sy;
+
+ srcRect.left = 0;
+ srcRect.top = 0;
+ srcRect.right = b->getBitmap()->getWidth();
+ srcRect.bottom = b->getBitmap()->getHeight();
+
+#if 0//CUT
+ // NONPORTABLE
+ HDC hdc = c->getHDC();
+ HRGN oldRgn = CreateRectRgn(0, 0, 0, 0);
+ HRGN newRgn = CreateRectRgnIndirect(&r);
+
+ int cs = GetClipRgn(hdc, oldRgn);
+
+ ExtSelectClipRgn(hdc, newRgn, (cs != 1) ? RGN_COPY : RGN_AND);
+
+ b->getBitmap()->stretchToRectAlpha(c, &srcRect, &destProjectedRect, alpha);
+
+ SelectClipRgn(hdc, cs ? oldRgn : NULL);
+
+ DeleteObject(oldRgn);
+ DeleteObject(newRgn);
+#endif
+ BaseCloneCanvas clone(c);
+ RegionI oldRgn, newRgn(&r);
+#ifdef _WIN32
+ int cs = clone.getClipRgn(&oldRgn);
+ if (cs) newRgn.andRegion(&oldRgn);
+ clone.selectClipRgn(&newRgn);
+ b->getBitmap()->stretchToRectAlpha(&clone, &srcRect, &destProjectedRect, alpha);
+ clone.selectClipRgn(cs ? &oldRgn : NULL);
+#else
+#warning port me
+ b->getBitmap()->stretchToRectAlpha(&clone, &srcRect, &destProjectedRect, alpha);
+#endif
+}
+
+wchar_t *Skin::enumLoadableSkins(int refresh)
+{
+ static size_t loadSkinListSize = 1024;
+
+ if (loadSkinList)
+ {
+ if (!refresh)
+ return loadSkinList;
+ FREE(loadSkinList);
+ }
+
+ loadSkinList = WMALLOC(loadSkinListSize);
+ loadSkinList[0] = 0;
+
+ int first = 1;
+ ReadDir skins(L"skins");
+
+ while (skins.next())
+ {
+ const wchar_t *filename = skins.getFilename();
+
+ wchar_t *ext = const_cast<wchar_t *>(Wasabi::Std::extension(filename));
+
+ if (skins.isDir() || !WCSICMP(ext, L"wal") ||
+ !WCSICMP(ext, L"wsz") || !WCSICMP(ext, L"zip"))
+ {
+ if (!skins.isDotDir() && !skins.isDotDotDir())
+ {
+ if (!skins.isDir() )
+ {
+ if (ext && *ext) *(ext - 1) = 0;
+ }
+
+ // check loadSkinList size
+ if ((wcslen(loadSkinList) + wcslen(filename) + 2) > loadSkinListSize)
+ {
+ loadSkinListSize *= 2;
+ loadSkinList = (wchar_t *)REALLOC(loadSkinList, sizeof(wchar_t) * loadSkinListSize);
+ }
+
+ if (!first)
+ wcscat(loadSkinList, L"/");
+ wcscat(loadSkinList, filename);
+ first = 0;
+ }
+ }
+ }
+
+ return loadSkinList;
+}
+
+int Skin::loadSkinPart(const wchar_t *xmlfile)
+{
+#ifdef WASABI_COMPILE_COMPONENTS
+ WasabiKernelController *wkc = Main::getKernelController();
+ if (wkc && !wkc->testSkinFile(xmlfile)) return -1;
+#endif
+
+ int id = WASABI_API_PALETTE->newSkinPart();
+ SkinElementsMgr::onBeforeLoadingScriptElements(xmlfile, id);
+ SkinParser::loadScriptXml(xmlfile, id);
+ SkinElementsMgr::onAfterLoadingScriptElements();
+#ifdef WASABI_COMPILE_WNDMGR
+ SkinParser::startupContainers(id);
+#endif
+ return id;
+}
+
+void Skin::unloadSkinPart(int skinpartid)
+{
+ SkinElementsMgr::unloadScriptElements(skinpartid);
+ SkinParser::cleanupScript(skinpartid);
+}
+
+int Skin::checkSkin(const wchar_t *skinname)
+{
+ OSFILETYPE fh = WFOPEN(StringPathCombine(WASABI_API_SKIN->getSkinPath(), L"skin.xml"), WF_READONLY_BINARY);
+ if (fh != OPEN_FAILED)
+ {
+ FCLOSE(fh);
+ // ok it's a wa3 skin, now check the skin version number in the xml file
+ SkinVersionXmlReader r(skinname);
+ if (!r.getWalVersion()) return CHKSKIN_ISWA3OLD;
+ #ifndef LC_NUMERIC
+ #define LC_NUMERIC 4
+ #endif
+ float v = (float)(WTOF(r.getWalVersion()) * 100); // Since wa5.51 we will do a check for x.yz style
+ if (v < (SKIN_LEGACY_VERSION-0.5f)) return CHKSKIN_ISWA3OLD;
+ if (v > (SKIN_VERSION+0.5f)) return CHKSKIN_ISWA3FUTURE;
+ return CHKSKIN_ISWA3;
+ }
+ fh = WFOPEN(StringPathCombine(WASABI_API_SKIN->getSkinPath(), L"Main.bmp"), WF_READONLY_BINARY);
+ if (fh != OPEN_FAILED)
+ {
+ FCLOSE(fh);
+ return CHKSKIN_ISWA2;
+ }
+ return CHKSKIN_UNKNOWN;
+}
+
+void Skin::toggleSkin(const wchar_t *skin_name, const wchar_t *skin_path, int deferred)
+{
+ StringW skinName = skin_name;
+
+ if (sendAbortCallback(skinName)) return ;
+
+ enable_group_reload = 0;
+
+ StringW oldSkinPath = skinPath;
+ char title[32] = {0};
+ setSkinName(skinName, skin_path);
+ int skinType = checkSkin(skinName);
+ skinPath = oldSkinPath;
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ WasabiKernelController *wkc = Main::getKernelController();
+ if (wkc && !wkc->testSkin(skinName)) skinType = CHKSKIN_DISALLOWED;
+#endif
+
+ switch (skinType)
+ {
+ case CHKSKIN_ISWA3OLD:
+ {
+#ifdef WIN32
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ int ret = MessageBoxA(GetActiveWindow(), WASABI_API_LNGSTRING(IDS_SKIN_LOAD_FORMAT_OLD),
+ WASABI_API_LNGSTRING_BUF(IDS_SKIN_LOAD_WARNING,title,32),
+ MB_ICONWARNING | MB_YESNO);
+ WASABI_API_WND->appdeactivation_setbypass(0);
+ if (ret == IDNO) return ;
+#else
+ DebugString( "The skin you are trying to load is meant for an older Winamp3 version.\n" );
+#endif
+ break;
+ }
+ case CHKSKIN_ISWA3FUTURE:
+ {
+#ifdef WIN32
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ int ret = MessageBoxA(GetActiveWindow(), WASABI_API_LNGSTRING(IDS_SKIN_LOAD_FORMAT_TOO_RECENT),
+ WASABI_API_LNGSTRING_BUF(IDS_SKIN_LOAD_WARNING,title,32),
+ MB_ICONWARNING | MB_YESNO);
+ WASABI_API_WND->appdeactivation_setbypass(0);
+ if (ret == IDNO) return ;
+#else
+ DebugString( "The skin you are trying to load is meant for an older Winamp3 version.\n" );
+#endif
+ break;
+ }
+ case CHKSKIN_UNKNOWN:
+#ifdef WIN32
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ MessageBoxA(GetActiveWindow(), WASABI_API_LNGSTRING(IDS_SKIN_LOAD_NOT_SUPPORTED),
+ WASABI_API_LNGSTRING_BUF(IDS_ERROR,title,32), MB_ICONERROR);
+ WASABI_API_WND->appdeactivation_setbypass(0);
+#else
+ DebugString( "The skin you are trying to load is meant for an older Winamp3 version.\n" );
+#endif
+ return ;
+
+ case CHKSKIN_DISALLOWED:
+
+ // kernel controller should output its own error message
+
+ return ;
+
+ case CHKSKIN_ISWA2: break;
+ }
+
+ WASABI_API_COLORTHEMES->StartTransaction();
+ if (skin_loaded)
+ {
+ sendUnloadingCallback();
+ }
+
+ loading = 1;
+
+ if (skin_loaded)
+ {
+ //ComponentManager::detachAllTemporary();
+ //ComponentManager::destroyAllCompContainer();
+
+#ifdef WASABI_COMPILE_WNDMGR
+ #ifdef WASABI_COMPILE_CONFIG
+ #ifndef WASABI_WNDMGR_NORESPAWN
+ skinEmbedder->saveState();
+#endif
+ #endif
+ #endif
+
+ // unload current skin
+ SkinParser::cleanUp();
+
+ delete(tha);
+ tha = NULL;
+ //delete(VCPU::scriptManager);
+
+ unloadResources();
+
+ // TODO: benski> unload WAC files inside skin.
+ // we should have saved a list of WacComponent * when loading
+ // add a new method ComponentManager::unload(WacComponent *);
+
+ Skin::sendResetCallback();
+
+ // VCPU::scriptManager = new ScriptObjectManager();
+ Skin *n = new Skin;
+ tha = n;
+ }
+
+ setSkinName(skinName, skin_path);
+
+ if (skin_loaded)
+ {
+ SkinElementsMgr::resetSkinElements();
+ //SkinElementsMgr::loadSkinElements(skinName); // only loads element definitions, not actual bitmaps
+
+ sendReloadCallback();
+
+ reloadResources();
+ }
+
+ // TODO: benski> load WAC files inside skin. save list of WacComponent * to a list to unload later
+ // make ComponentManager::load() return the WacComponent to allow this
+
+#ifdef WASABI_COMPILE_WNDMGR
+ int ncont = SkinParser::loadContainers(skinName); //sends guiloaded cb
+#endif
+
+ GammaMgr::loadDefault();
+
+#ifdef WASABI_COMPILE_WNDMGR
+ SkinParser::startupContainers();
+#ifdef WASABI_COMPILE_CONFIG
+#ifndef WASABI_WNDMGR_NORESPAWN
+ skinEmbedder->restoreSavedState();
+#endif
+#endif
+#endif
+
+ enable_group_reload = 1;
+
+ sendLoadedCallback();
+
+#ifdef WASABI_COMPILE_WNDMGR
+ SkinParser::centerSkin();
+#endif
+
+ loading = 0;
+
+#ifdef WASABI_COMPILE_WNDMGR
+#ifdef WA3COMPATIBILITY
+ if (ncont == 0)
+ SkinParser::emmergencyReloadDefaultSkin();
+#endif
+#endif
+ skin_loaded = 1;
+ WASABI_API_COLORTHEMES->EndTransaction();
+}
+
+void Skin::unloadSkin()
+{
+ if (!skin_loaded) return ;
+
+ sendUnloadingCallback();
+
+ loading = -1;
+
+#ifdef WASABI_COMPILE_WNDMGR
+ #ifdef WASABI_COMPILE_CONFIG
+ #ifndef WASABI_WNDMGR_NORESPAWN
+ skinEmbedder->saveState();
+#endif
+ #endif
+ #endif
+
+ // unload current skin
+ SkinParser::cleanUp();
+
+ delete(tha);
+ tha = NULL;
+ //delete(VCPU::scriptManager);
+
+ unloadResources();
+
+ Skin::sendResetCallback();
+
+ // VCPU::scriptManager = new ScriptObjectManager();
+ Skin *n = new Skin;
+ tha = n;
+
+ setSkinName(WASABI_API_LNGSTRINGW_BUF(IDS_NO_SKIN_LOADED_,skName,64));
+
+ SkinElementsMgr::resetSkinElements();
+ //SkinElementsMgr::loadSkinElements(skinName); // only loads element definitions, not actual bitmaps
+
+ sendReloadCallback();
+
+ reloadResources();
+ loading = 0;
+ skin_loaded = 0;
+}
+
+void Skin::sendUnloadingCallback()
+{
+#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!!
+ ComponentManager::broadcastNotify(WAC_NOTIFY_SKINUNLOADING, WASABI_API_PALETTE->getSkinPartIterator());
+#endif
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::UNLOADING);
+}
+
+int Skin::sendAbortCallback(const wchar_t *skinname)
+{
+ int a = 0;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::CHECKPREVENTSWITCH, (intptr_t)skinname, (intptr_t)&a);
+ return a;
+}
+
+void Skin::sendResetCallback()
+{
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::RESET);
+}
+
+void Skin::sendReloadCallback()
+{
+#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!!
+ ComponentManager::broadcastNotify(WAC_NOTIFY_SWITCHINGSKIN, WASABI_API_PALETTE->getSkinPartIterator()); // this msg primilarily here to insert stuff between unloading of the old skin and reloading of the new one
+#endif
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::RELOAD);
+}
+
+void Skin::sendBeforeLoadingElementsCallback()
+{
+#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!!
+ ComponentManager::broadcastNotify(WAC_NOTIFY_BEFORELOADINGSKINELEMENTS, WASABI_API_PALETTE->getSkinPartIterator()); // this msg primilarily here to insert stuff between unloading of the old skin and reloading of the new one
+#endif
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::BEFORELOADINGELEMENTS);
+}
+
+void Skin::sendGuiLoadedCallback()
+{
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::GUILOADED);
+}
+
+void Skin::sendLoadedCallback()
+{
+#if defined(WASABI_COMPILE_COMPONENTS) | defined(GEN_FF) // MULTIAPI-FIXME!!
+ ComponentManager::broadcastNotify(WAC_NOTIFY_SKINLOADED, WASABI_API_PALETTE->getSkinPartIterator());
+#endif
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::SKINCB, SkinCallback::LOADED);
+}
+
+void Skin::setSkinReady(int i)
+{
+ loading = !i;
+}
+
+void Skin::main_notifySkinLoaded()
+{
+ skin_loaded = 1;
+}
+
+int Skin::isSkinReady()
+{
+ return !loading;
+}
+
+int Skin::unloadResources()
+{
+ if (windowTracker)
+ {
+ for (int i = 0;i < windowTracker->getNumAllWindows();i++)
+ {
+ ifc_window *w = windowTracker->enumAllWindows(i);
+#ifdef _WIN32
+ if (w) w->wndProc(w->gethWnd(), WM_WA_RELOAD, 0, 0);
+#else
+#warning port me
+#endif
+ }
+ Skin::unloadAllBaseTextures();
+#ifdef WASABI_COMPILE_PAINTSETS
+ paintset_reset();
+#endif
+
+ }
+
+ sendResetCallback();
+
+ return 1;
+}
+
+int Skin::reloadResources()
+{
+ if (windowTracker)
+ {
+ for (int i = 0;i < windowTracker->getNumAllWindows();i++)
+ {
+ ifc_window *w = windowTracker->enumAllWindows(i);
+#ifdef _WIN32
+ if (w) w->wndProc(w->gethWnd(), WM_WA_RELOAD, 1, 0);
+#else
+#warning port me
+#endif
+ }
+ Skin::reloadAllBaseTextures();
+ }
+
+ sendReloadCallback();
+
+ return 1;
+}
+
+bool Skin::isLoaded()
+{
+ return !!skin_loaded;
+}
+
+PtrList<Skin> Skin::skinList;
+PtrList<ifc_window> Skin::baseList;
+StringW Skin::skinName;
+StringW Skin::skinPath;
+int Skin::isDefaultSkin = 0;
+int Skin::loading = 0;
+int Skin::highest_id = 0;
+int Skin::reloadingskin = 0;
+int Skin::enable_group_reload = 0;
+StringW Skin::defSkinPath;
+SkinTimer *Skin::deferedskinset = NULL;
+int Skin::skin_loaded = 0; \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/skin.h b/Src/Wasabi/api/skin/skin.h
new file mode 100644
index 00000000..0f9da315
--- /dev/null
+++ b/Src/Wasabi/api/skin/skin.h
@@ -0,0 +1,150 @@
+#ifndef _SKIN_H
+#define _SKIN_H
+
+#include <api/skin/api_skin.h>
+
+#include <bfc/platform/platform.h>
+#include <api/wnd/basewnd.h>
+#include <bfc/ptrlist.h>
+#include <tataki/region/region.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <bfc/string/bfcstring.h>
+#include <api/wndmgr/container.h>
+#include <api/xml/xmlreader.h>
+#include <bfc/string/StringW.h>
+
+class SkinBitmap;
+#include "SkinVersion.h"
+
+#define CB_SETSKINDEFERRED 0x5492
+
+class SkinTimer;
+
+class Skin
+{
+public:
+ enum {
+ CHKSKIN_UNKNOWN = -1,
+ CHKSKIN_ISWA3 = 1,
+ CHKSKIN_ISWA3OLD = 2,
+ CHKSKIN_ISWA3FUTURE = 3,
+ CHKSKIN_ISWA2 = 4,
+ CHKSKIN_DISALLOWED = 5,
+ };
+
+ Skin();
+ virtual ~Skin();
+
+ static const wchar_t *getSkinName();
+ static void setSkinName(const wchar_t *newskinname, const wchar_t *skinpath = NULL);
+ static const wchar_t *getSkinPath();
+ static const wchar_t *getDefaultSkinPath();
+ static Skin *getCurSkin();
+
+ void setBaseTexture(const wchar_t *b);
+
+ //CUT static int registerCallback(SkinCallback *cb);
+ //CUT static int deregisterCallback(SkinCallback *cb);
+
+ static void renderBaseTexture(ifc_window *base, Skin *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha = 255);
+ static void renderBaseTexture(ifc_window *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha = 255);
+
+ static void invalidateBaseTexture(Skin *s);
+ static void invalidateAllBaseTextures();
+ static Skin *baseToSkin(ifc_window *b);
+ static void registerBaseSkin(Skin *s, ifc_window *b);
+ static Skin *unregisterBaseSkin(ifc_window *b);
+
+
+ static void unloadAllBaseTextures();
+ static void reloadAllBaseTextures();
+ void _unloadBaseTexture();
+ void _reloadBaseTexture();
+
+ static wchar_t *enumLoadableSkins(int refresh = FALSE);
+
+ static int checkSkin(const wchar_t *name);
+ static void toggleSkin(const wchar_t *name, const wchar_t *skin_path = NULL, int deferred = 0);
+ static void unloadSkin();
+ static void parseSkinFilename(const wchar_t *filename, const wchar_t *incpath);
+ static int isDefaultSkin;
+ static void sendUnloadingCallback();
+ static int sendAbortCallback(const wchar_t *skinname);
+ static void sendResetCallback();
+ static void sendReloadCallback();
+ static void sendBeforeLoadingElementsCallback();
+ static void sendGuiLoadedCallback();
+ static void sendLoadedCallback();
+ static int isSkinReady();
+ static void setSkinReady(int i);
+ static int isDynamicGroupReloadEnabled() { return enable_group_reload; }
+ static void unloadSkinPart(int id);
+ static int loadSkinPart(const wchar_t *xmlfile);
+ static void main_notifySkinLoaded();
+ static int isLoading() { return loading; }
+
+ static int unloadResources();
+ static int reloadResources();
+ static bool isLoaded();
+private:
+ void rescaleBaseTexture(int w, int h);
+ void _renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha);
+ void _invalidateBaseTexture(void);
+ void validateBaseTextureRect(RECT *r);
+
+ AutoSkinBitmap *base;
+ BltCanvas *scaled;
+ int scale_x, scale_y;
+ bool forceinvalid;
+ int m_x, m_y;
+ int lastw, lasth, maxw, maxh;
+ bool resizing;
+ RegionI *validRgn;
+ static int loading;
+ static int enable_group_reload;
+
+ static PtrList<Skin> skinList;
+ static PtrList<ifc_window> baseList;
+
+ static StringW skinName;
+ static StringW skinPath;
+ static StringW defSkinPath;
+ static int highest_id;
+ static int reloadingskin;
+ static int skin_loaded;
+
+ static SkinTimer *deferedskinset;
+};
+
+class SkinTimer : public TimerClientDI
+{
+public :
+ SkinTimer() {}
+ virtual ~SkinTimer() {}
+
+ void setSkinDeferred(const wchar_t *skinname)
+ {
+ skin = skinname;
+ timerclient_postDeferredCallback(CB_SETSKINDEFERRED, 0);
+ }
+
+ virtual int timerclient_onDeferredCallback(intptr_t p1, intptr_t p2)
+ {
+ if (p1 == CB_SETSKINDEFERRED)
+ {
+ Skin::toggleSkin(skin);
+ skin.trunc(0);
+ }
+ else
+ return TimerClientDI::timerclient_onDeferredCallback(p1, p2);
+ return 1;
+ }
+
+private:
+ StringW skin;
+};
+
+
+extern Skin *tha;
+
+#endif
diff --git a/Src/Wasabi/api/skin/skinapi.cpp b/Src/Wasabi/api/skin/skinapi.cpp
new file mode 100644
index 00000000..f68a0614
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinapi.cpp
@@ -0,0 +1,347 @@
+#include <precomp.h>
+#include <api.h>
+#include "skinapi.h"
+#include <api/skin/skin.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/skin/skinelem.h>
+#include <api/imgldr/imgldr.h>
+#include <api/skin/gammamgr.h>
+#include <api/skin/groupmgr.h>
+#include <api/skin/cursormgr.h>
+#include <api/skin/guitree.h>
+#include <api/skin/groupwndcreate.h>
+#include <api/wndmgr/autopopup.h>
+#include <tataki/canvas/bltcanvas.h>
+
+api_skin *skinApi;
+static waServiceTSingle<svc_windowCreate, GroupWndCreateSvc> groupWndCreate;
+
+SkinApi::SkinApi()
+{
+ lockui = 0;
+ tha = new Skin();
+ SkinParser::initialize();
+
+ WASABI_API_SVC->service_register(&groupWndCreate);
+
+ SkinElementsMgr::init();
+ GammaMgr::init();
+
+ // fixed this for 5.58+ so it'll use the correct skins directory
+ // and not the winamp.exe folder + "skins" - fixes @SKINSPATH@
+ // when the skins directory has been altered - from Bento notifier.xml
+ skinspath = WASABI_API_APP->path_getSkinSettingsPath();
+}
+
+SkinApi::~SkinApi()
+{
+ delete tha; tha = NULL;
+#ifdef WASABI_COMPILE_WNDMGR
+ AutoPopup::reset();
+#endif
+ SkinElementsMgr::deinit();
+ GammaMgr::deinit();
+ WASABI_API_SVC->service_deregister(&groupWndCreate);
+ SkinParser::shutdown();
+}
+
+void SkinApi::preShutdown()
+{
+ Skin::unloadSkin();
+ SkinElementsMgr::resetSkinElements();
+}
+
+ARGB32 SkinApi::skin_getColorElement(const wchar_t *type, const wchar_t **color_group)
+{
+ return WASABI_API_PALETTE->getColorElement(type, color_group);
+}
+
+const ARGB32 *SkinApi::skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group)
+{
+ return WASABI_API_PALETTE->getColorElementRef(type, color_group);
+}
+
+const int *SkinApi::skin_getIterator()
+{
+ return WASABI_API_PALETTE->getSkinPartIteratorPtr();
+}
+
+void SkinApi::skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path)
+{
+ if (skin_name && *skin_name) Skin::toggleSkin(skin_name, skin_path, 1);
+}
+
+void SkinApi::skin_unloadSkin()
+{
+ Skin::unloadSkin();
+}
+
+const wchar_t *SkinApi::getSkinName()
+{
+ return Skin::getSkinName();
+}
+
+const wchar_t *SkinApi::getSkinPath()
+{
+ return Skin::getSkinPath();
+}
+
+const wchar_t *SkinApi::getSkinsPath()
+{
+ return skinspath;
+}
+
+const wchar_t *SkinApi::getDefaultSkinPath()
+{
+ return Skin::getDefaultSkinPath();
+}
+
+ARGB32 *SkinApi::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached)
+{
+ if (file == NULL)
+ {
+ DebugStringW(L"illegal param : file == NULL\n");
+ return NULL;
+ }
+ return imageLoader::requestSkinBitmap(file, has_alpha, x, y, subw, subh, w, h, cached);
+}
+
+void SkinApi::imgldr_releaseSkinBitmap(ARGB32 *bmpbits)
+{
+ if (bmpbits == NULL)
+ {
+ DebugStringW(L"illegal param : bmpbits == NULL\n");
+ return ;
+ }
+ imageLoader::releaseSkinBitmap(bmpbits);
+}
+
+ARGB32 SkinApi::filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname)
+{
+ return imageLoader::filterSkinColor(color, elementid, groupname);
+}
+
+void SkinApi::reapplySkinFilters()
+{
+ imageLoader::applySkinFilters();
+}
+
+/* ---------------------------------------- */
+int SkinApi::colortheme_getNumColorSets()
+{
+ return WASABI_API_COLORTHEMES->getNumGammaSets();
+}
+
+const wchar_t *SkinApi::colortheme_enumColorSet(int n)
+{
+ return WASABI_API_COLORTHEMES->enumGammaSet(n);
+}
+
+int SkinApi::colortheme_getNumColorGroups(const wchar_t *colorset)
+{
+ return WASABI_API_COLORTHEMES->getNumGammaGroups(colorset);
+}
+
+const wchar_t *SkinApi::colortheme_enumColorGroupName(const wchar_t *colorset, int n)
+{
+ return WASABI_API_COLORTHEMES->enumGammaGroup(colorset, n);
+}
+
+ColorThemeGroup *SkinApi::colortheme_enumColorGroup(int colorset, int colorgroup)
+{
+ return WASABI_API_COLORTHEMES->enumColorThemeGroup(colorset, colorgroup);
+}
+
+ColorThemeGroup *SkinApi::colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *colorgroup)
+{
+ return WASABI_API_COLORTHEMES->getColorThemeGroup(colorset, colorgroup);
+}
+
+void SkinApi::colortheme_setColorSet(const wchar_t *colorset)
+{
+ WASABI_API_COLORTHEMES->setGammaSet(colorset);
+ // TODO: benski> move this to a syscallback: SysCallback::SKINCB, SkinCallback::COLORTHEMECHANGED
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"Color Themes/%s", getSkinName()), colorset);
+}
+
+const wchar_t *SkinApi::colortheme_getColorSet()
+{
+ return WASABI_API_COLORTHEMES->getGammaSet();
+}
+
+void SkinApi::colortheme_newColorSet(const wchar_t *set)
+{
+ WASABI_API_COLORTHEMES->newGammaSet(set);
+}
+
+void SkinApi::colortheme_updateColorSet(const wchar_t *set)
+{
+ WASABI_API_COLORTHEMES->updateGammaSet(set);
+}
+
+void SkinApi::colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname)
+{
+ WASABI_API_COLORTHEMES->renameGammaSet(set, newname);
+}
+
+void SkinApi::colortheme_deleteColorSet(const wchar_t *set)
+{
+ WASABI_API_COLORTHEMES->deleteGammaSet(set);
+}
+
+ /* -------------------------------------------- */
+
+int SkinApi::loadSkinFile(const wchar_t *xmlfile)
+{
+ return Skin::loadSkinPart(xmlfile);
+}
+
+void SkinApi::unloadSkinPart(int skinpartid)
+{
+ Skin::unloadSkinPart(skinpartid);
+}
+
+ifc_window *SkinApi::group_create(const wchar_t *groupid, int scripts_enabled)
+{
+ return GroupMgr::instantiate(groupid, GROUP_GROUP, NULL, scripts_enabled);
+}
+
+int SkinApi::group_destroy(ifc_window *group)
+{
+ return GroupMgr::destroy(static_cast<Group*>(group));
+}
+
+int SkinApi::group_exists(const wchar_t *groupid)
+{
+ return GroupMgr::exists(groupid);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+ifc_window *SkinApi::group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled)
+{
+ return GroupMgr::instantiate(groupid, cfgitem, attributename, scripts_enabled);
+}
+#endif // WASABI_COMPILE_CONFIG
+
+#ifdef WASABI_COMPILE_WNDMGR
+ifc_window *SkinApi::group_create_layout(const wchar_t *groupid, int scripts_enabled)
+{
+ return GroupMgr::instantiate(groupid, GROUP_LAYOUTGROUP, NULL, scripts_enabled);
+}
+#endif //WASABI_COMPILE_WNDMGR
+
+OSCURSOR SkinApi::cursor_request(const wchar_t *id)
+{
+ return CursorMgr::requestCursor(id);
+}
+
+int SkinApi::parse(const wchar_t *str, const wchar_t *how)
+{
+ return SkinParser::parse(str, how);
+}
+
+GuiObject *SkinApi::xui_new(const wchar_t *classname)
+{
+ return SkinParser::xui_new(classname);
+}
+
+void SkinApi::xui_delete(GuiObject *o)
+{
+ SkinParser::xui_delete(o);
+}
+
+int SkinApi::getNumGroupDefs()
+{
+ return guiTree->getNumGroupDefs();
+}
+
+SkinItem *SkinApi::enumGroupDef(int n)
+{
+ return guiTree->enumGroupDef(n);
+}
+
+ifc_window *SkinApi::group_createBySkinItem(SkinItem *item, int scripts_enabled)
+{
+ return GroupMgr::instantiate(NULL, GROUP_GROUP, item, scripts_enabled);
+}
+
+SkinItem *SkinApi::getGroupDefAncestor(SkinItem *item)
+{
+ return guiTree->getGroupDefAncestor(item);
+}
+
+int SkinApi::groupdef_getNumObjects(SkinItem *_item)
+{
+ GuiTreeItem *item = static_cast<GuiTreeItem *>(_item);
+ int idx = item->getIdx();
+ idx++;
+ int n = 0;
+ while (1)
+ {
+ GuiTreeItem *it = guiTree->getList()->enumItem(idx);
+ if (it->getType() == XML_TAG_GROUPDEF && it->getParams() == NULL) break;
+ idx++; n++;
+ }
+ return n;
+}
+
+SkinItem *SkinApi::groupdef_enumObject(SkinItem *_item, int n)
+{
+ GuiTreeItem *item = static_cast<GuiTreeItem *>(_item);
+ int idx = item->getIdx();
+ idx++;
+ int _n = 0;
+ GuiTreeItem *it = NULL;
+ while (1)
+ {
+ it = guiTree->getList()->enumItem(idx);
+ if (it->getType() == XML_TAG_GROUPDEF && it->getParams() == NULL) break;
+ if (n == _n) break;
+ idx++; _n++;
+ }
+ return it;
+}
+
+int SkinApi::loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupdef)
+{
+ StringW s;
+ s = L"buf:";
+
+ s += L"<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>"
+ L"<WinampAbstractionLayer version=\"0.8\">";
+
+ s += groupdef;
+
+ s += L"</WinampAbstractionLayer>";
+
+ int r = Skin::loadSkinPart(s);
+ if (lastgroupdef != NULL)
+ *lastgroupdef = guiTree->getLastDefinedGroup();
+ return r;
+}
+
+double SkinApi::skin_getVersion()
+{
+ return SkinParser::getSkinVersion();
+}
+#ifdef WASABI_COMPILE_IMGLDR
+ARGB32 SkinApi::skin_getBitmapColor(const wchar_t *id)
+{
+ SkinBitmap bitmap(id);
+ BltCanvas c(bitmap.getWidth() + 1, bitmap.getHeight() + 1, 0); // TODO: this won't work on the mac i don't think
+ bitmap.blit(&c, 0, 0);
+ int x = bitmap.getWidth() / 2;
+ int y = bitmap.getHeight() / 2;
+ int *bits = (int *)c.getBits();
+ if (bits != NULL)
+ {
+ return bits[x + y*bitmap.getWidth() + 1];
+ }
+ return 0xFFFF00FF;
+}
+#endif
+
+bool SkinApi::skin_isLoaded()
+{
+ return Skin::isLoaded();
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/skinapi.h b/Src/Wasabi/api/skin/skinapi.h
new file mode 100644
index 00000000..b4cedc99
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinapi.h
@@ -0,0 +1,79 @@
+#ifndef __SKINAPI_H
+#define __SKINAPI_H
+
+#include <api/skin/api_skin.h>
+#include <bfc/string/StringW.h>
+#include <api/skin/widgets.h>
+#include <api/xml/xmlparams.h>
+
+class SkinApi : public api_skinI
+{
+ public:
+
+ SkinApi();
+ virtual ~SkinApi();
+ virtual void preShutdown();
+
+ virtual ARGB32 skin_getColorElement(const wchar_t *type, const wchar_t **color_group = NULL);
+ virtual const ARGB32 *skin_getColorElementRef(const wchar_t *type, const wchar_t **color_group = NULL);
+ virtual const int *skin_getIterator();
+ virtual void skin_switchSkin(const wchar_t *skin_name, const wchar_t *skin_path);
+ virtual void skin_unloadSkin();
+ virtual const wchar_t *getSkinName();
+ virtual const wchar_t *getSkinPath();
+ virtual const wchar_t *getSkinsPath();
+ virtual const wchar_t *getDefaultSkinPath();
+ virtual ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached);
+ virtual void imgldr_releaseSkinBitmap(ARGB32 *bmpbits);
+ virtual ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname);
+ virtual void reapplySkinFilters();
+ virtual int colortheme_getNumColorSets();
+ virtual const wchar_t *colortheme_enumColorSet(int n);
+ virtual int colortheme_getNumColorGroups(const wchar_t *colorset);
+ virtual const wchar_t *colortheme_enumColorGroupName(const wchar_t *colorset, int n);
+ virtual ColorThemeGroup *colortheme_enumColorGroup(int colorset, int n);
+ virtual ColorThemeGroup *colortheme_getColorGroup(const wchar_t *colorset, const wchar_t *group);
+ virtual void colortheme_setColorSet(const wchar_t *colorset);
+ virtual const wchar_t *colortheme_getColorSet();
+ virtual void colortheme_newColorSet(const wchar_t *set);
+ virtual void colortheme_updateColorSet(const wchar_t *set);
+ virtual void colortheme_renameColorSet(const wchar_t *set, const wchar_t *newname);
+ virtual void colortheme_deleteColorSet(const wchar_t *set);
+ virtual int loadSkinFile(const wchar_t *xmlfile);
+ virtual int loadGroupDefData(const wchar_t *groupdef, SkinItem **lastgroupitem);
+ virtual void unloadSkinPart(int skinpartid);
+ virtual ifc_window *group_create(const wchar_t *groupid, int scripts_enabled=1);
+ virtual int group_exists(const wchar_t *groupid);
+#ifdef WASABI_COMPILE_CONFIG
+ virtual ifc_window *group_create_cfg(const wchar_t *groupid, CfgItem *cfgitem, const wchar_t *attributename, int scripts_enabled=1);
+#endif // WASABI_COMPILE_CONFIG
+#ifdef WASABI_COMPILE_WNDMGR
+ virtual ifc_window *group_create_layout(const wchar_t *groupid, int scripts_enabled=1);
+#endif //WASABI_COMPILE_WNDMGR
+ virtual int group_destroy(ifc_window *group);
+ virtual int parse(const wchar_t *str, const wchar_t *how);
+ virtual GuiObject *xui_new(const wchar_t *classname);
+ virtual void xui_delete(GuiObject *o);
+ virtual OSCURSOR cursor_request(const wchar_t *id);
+
+ virtual int getNumGroupDefs();
+ virtual SkinItem *enumGroupDef(int n);
+ virtual ifc_window *group_createBySkinItem(SkinItem *item, int scripts_enabled=1);
+ virtual SkinItem *getGroupDefAncestor(SkinItem *item);
+ virtual int groupdef_getNumObjects(SkinItem *item);
+ virtual SkinItem *groupdef_enumObject(SkinItem *groupitem, int n);
+ virtual void skin_setLockUI(int l) { if (l) lockui++; else if (lockui) lockui--; }
+ virtual int skin_getLockUI() { return lockui; }
+ virtual double skin_getVersion();
+#ifdef WASABI_COMPILE_IMGLDR
+ virtual ARGB32 skin_getBitmapColor(const wchar_t *id);
+#endif
+ bool skin_isLoaded();
+
+ private:
+
+ StringW skinspath;
+ int lockui;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/skinbmps.h b/Src/Wasabi/api/skin/skinbmps.h
new file mode 100644
index 00000000..dab8568c
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinbmps.h
@@ -0,0 +1,122 @@
+#ifndef _SKINBMPS_H
+#define _SKINBMPS_H
+/*
+typedef enum {
+ SKIN_BITMAP_UNKNOWN,
+
+ // Base texture
+ SKIN_BITMAP_BASE_TEXTURE,
+
+ // Framewnd
+ SKIN_BITMAP_FRAME_VERTICAL_DIVIDER,
+ SKIN_BITMAP_FRAME_HORIZONTAL_DIVIDER,
+
+ // Listwnd/Treewnd
+ SKIN_BITMAP_LIST_BACKGROUND,
+ SKIN_BITMAP_TREE_BACKGROUND,
+
+ // Appctrl
+ SKIN_BITMAP_APPCTRL_LEFTARROW_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_LEFTARROW_PRESSED,
+ SKIN_BITMAP_APPCTRL_RIGHTARROW_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_RIGHTARROW_PRESSED,
+ SKIN_BITMAP_APPCTRL_WINDOWSIZER,
+ SKIN_BITMAP_APPCTRL_PLAYERMODE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_PLAYERMODE_PRESSED,
+ SKIN_BITMAP_APPCTRL_MINIMIZE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_MINIMIZE_PRESSED,
+ SKIN_BITMAP_APPCTRL_MAXIMIZE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_MAXIMIZE_PRESSED,
+ SKIN_BITMAP_APPCTRL_CLOSE_NONPRESSED,
+ SKIN_BITMAP_APPCTRL_CLOSE_PRESSED,
+ SKIN_BITMAP_APPCTRL_SYSTEMICON,
+ SKIN_BITMAP_APPCTRL_PLACEHOLDER_LEFT,
+ SKIN_BITMAP_APPCTRL_PLACEHOLDER_MIDDLE,
+ SKIN_BITMAP_APPCTRL_PLACEHOLDER_RIGHT,
+ SKIN_BITMAP_APPCTRL_TITLEBAR,
+
+ // Controls
+ SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_STOP_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_STOP_PRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_NONPRESSED,
+ SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_PRESSED,
+
+ // Paintset
+ SKIN_BITMAP_LABEL_UPPERLEFT,
+ SKIN_BITMAP_LABEL_TOP,
+ SKIN_BITMAP_LABEL_UPPERRIGHT,
+ SKIN_BITMAP_LABEL_LEFT,
+ SKIN_BITMAP_LABEL_MIDDLE,
+ SKIN_BITMAP_LABEL_RIGHT,
+ SKIN_BITMAP_LABEL_LOWERLEF,
+ SKIN_BITMAP_LABEL_BOTTOM,
+ SKIN_BITMAP_LABEL_LOWERRIGHT,
+ SKIN_BITMAP_APPBORDER_UPPERLEFT,
+ SKIN_BITMAP_APPBORDER_TOP,
+ SKIN_BITMAP_APPBORDER_UPPERRIGHT,
+ SKIN_BITMAP_APPBORDER_LEFT,
+ SKIN_BITMAP_APPBORDER_RIGHT,
+ SKIN_BITMAP_APPBORDER_LOWERLEFT,
+ SKIN_BITMAP_APPBORDER_BOTTOM,
+ SKIN_BITMAP_APPBORDER_LOWERRIGHT,
+
+ // Seeker
+ SKIN_BITMAP_SEEKBAR_LEFT,
+ SKIN_BITMAP_SEEKBAR_MIDDLE,
+ SKIN_BITMAP_SEEKBAR_RIGHT,
+ SKIN_BITMAP_SEEKBAR_BUTTON_NONPRESSED,
+ SKIN_BITMAP_BUTTON_PRESSED,
+
+ // Status
+ SKIN_BITMAP_STATUSBAR_LEFT,
+ SKIN_BITMAP_STATUSBAR_MIDDLE,
+ SKIN_BITMAP_STATUSBAR_RIGHT,
+
+ // Volbar
+ SKIN_BITMAP_VOLBAR_LEFT,
+ SKIN_BITMAP_VOLBAR_MIDDLE,
+ SKIN_BITMAP_VOLBAR_RIGHT,
+ SKIN_BITMAP_VOLBAR_BUTTON_NONPRESSED,
+ SKIN_BITMAP_VOLBAR_BUTTON_PRESSED,
+
+ // Titlewnd
+ SKIN_BITMAP_COMPONENT_PROP_TOP,
+ SKIN_BITMAP_COMPONENT_PROP,
+ SKIN_BITMAP_COMPONENT_PROP_MIDDLE,
+ SKIN_BITMAP_COMPONENT_PROP_BOTTOM,
+
+ // Videownd
+ SKIN_BITMAP_MOVIE_BACKGROUND,
+
+ // Seditwnd
+ SKIN_BITMAP_AVS_SCRIPT_MARKER,
+ SKIN_BITMAP_AVS_SCRIPT_PLAY_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_PLAY_PRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_PAUSE_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_PAUSE_PRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_STOP_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_STOP_PRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_TIMEARROW,
+ SKIN_BITMAP_AVS_SCRIPT_BACKGROUND,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_TOP,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_MIDDLE,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BOTTOM,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_NONPRESSED,
+ SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_PRESSED,
+
+// ComponentAPI1 ends here
+ NUM_SKIN_BITMAP_ELEMENT_IDS
+} SkinBitmapElementId;
+
+typedef struct {
+ SkinBitmapElementId id;
+ char *fn;
+ } SkinBitmapTableElement;
+*/
+#endif
diff --git a/Src/Wasabi/api/skin/skinelem.cpp b/Src/Wasabi/api/skin/skinelem.cpp
new file mode 100644
index 00000000..45d1a39f
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinelem.cpp
@@ -0,0 +1,316 @@
+#include <precomp.h>
+#include <api.h>
+#include "skinelem.h"
+#include <api/skin/skin.h>
+#include <api/skin/skinparse.h>
+#include <api/wac/compon.h>
+#include <api/wac/wac.h>
+#include <api/font/font.h>
+#include <bfc/parse/pathparse.h>
+#include <api/service/svcs/svc_collection.h>
+#include <tataki/canvas/bltcanvas.h>
+
+xml_elementtag elementtaglist[] =
+ {
+ {L"bitmap", XML_ELEMENTTAG_BITMAP, 0},
+ {L"bitmapfont", XML_ELEMENTTAG_BITMAPFONT, 0},
+ {L"color", XML_ELEMENTTAG_COLOR, 0},
+ {L"cursor", XML_ELEMENTTAG_CURSOR, 0},
+ {L"elements", XML_ELEMENTTAG_ELEMENTS, 1},
+ {L"elementalias", XML_ELEMENTTAG_ELEMENTALIAS, 0},
+ {L"truetypefont", XML_ELEMENTTAG_TRUETYPEFONT, 0},
+ };
+
+//-------------------------
+
+
+
+
+
+
+
+//-------------------------
+
+void SkinElementsMgr::init()
+{
+ if (!quickxmltaglist.getNumItems())
+ {
+ for (int i = 0;i < sizeof(elementtaglist) / sizeof(xml_elementtag);i++)
+ quickxmltaglist.addItem(&elementtaglist[i]);
+ }
+ skinXML.registerCallback(L"WinampAbstractionLayer\felements\f*", &xmlreader); //back compat
+ skinXML.registerCallback(L"WasabiXML\felements\f*", &xmlreader);
+}
+
+void SkinElementsMgr::deinit()
+{
+ resetSkinElements();
+ skinXML.unregisterCallback(&xmlreader);
+}
+
+void SkinElementsMgr::onBeforeLoadingSkinElements(const wchar_t *_rootpath)
+{
+ Skin::sendBeforeLoadingElementsCallback();
+ elementScriptId = WASABI_API_PALETTE->newSkinPart();
+
+ WASABI_API_PALETTE->StartTransaction();
+
+ rootpath = _rootpath;
+ original_rootpath = rootpath;
+ last_includepath = L"";
+}
+
+void SkinElementsMgr::onAfterLoadingSkinElements()
+{
+ WASABI_API_PALETTE->EndTransaction();
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ ComponentManager::broadcastNotify(WAC_NOTIFY_SKINELEMENTSLOADED, Skin::getSkinPartIterator());
+#endif
+}
+
+void SkinElementsXmlReader::xmlReaderOnEndElementCallback(const wchar_t *xmltag)
+{
+ SkinElementsMgr::xmlReaderOnEndElementCallback(xmltag);
+}
+
+void SkinElementsMgr::xmlReaderOnEndElementCallback(const wchar_t *xmltag)
+{
+ xml_elementtag *i = quickxmltaglist.findItem(xmltag);
+ if (!i) return ;
+ if (i->id == XML_ELEMENTTAG_ELEMENTS)
+ {
+ if (inelements)
+ inelements = 0;
+ }
+}
+
+void SkinElementsXmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params)
+{
+ SkinElementsMgr::xmlReaderOnStartElementCallback(xmltag, params);
+}
+
+void SkinElementsMgr::xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params)
+{
+ xml_elementtag *i = quickxmltaglist.findItem(xmltag);
+ if (i)
+ _xmlReaderOnStartElementCallback( i->id, xmltag, params);
+ else
+ _xmlReaderOnStartElementCallback( XML_ELEMENTTAG_UNKNOWN, xmltag, params);
+}
+
+void SkinElementsMgr::_xmlReaderOnStartElementCallback(int tagid, const wchar_t *xmltag, skin_xmlreaderparams *params)
+{
+ const wchar_t *ic = skinXML.getIncludePath();
+ if (WCSICMP(ic, last_includepath))
+ {
+ last_includepath = skinXML.getIncludePath();
+ rootpath = getSkinRootpathFromIncludePath(last_includepath, original_rootpath);
+ }
+ // If we're loading from a buffer, there should be no rootpath prefix.
+ if (!WCSNICMP(rootpath, L"buf:", 4))
+ {
+ rootpath = NULL;
+ }
+ if (tagid == XML_ELEMENTTAG_ELEMENTALIAS)
+ {
+ WASABI_API_PALETTE->AddAlias(params->getItemValue(L"id"), params->getItemValue(L"target"));
+ }
+ else if (tagid == XML_ELEMENTTAG_BITMAP)
+ {
+ StringW id;
+ const wchar_t *fn;
+ id = params->getItemValue(L"id");
+ fn = params->getItemValue(L"file");
+ int x = params->getItemValueInt(L"x", -1);
+ int y = params->getItemValueInt(L"y", -1);
+ int w = params->getItemValueInt(L"w", -1);
+ int h = params->getItemValueInt(L"h", -1);
+
+ const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id);
+ if (aliastarget)
+ id = aliastarget;
+
+ const wchar_t *colorgroup = params->getItemValue(L"colorgroup");
+ if (!colorgroup || !*colorgroup)
+ colorgroup = params->getItemValue(L"gammagroup");
+
+ WASABI_API_PALETTE->AddBitmap(id, fn, rootpath, x, y, w, h, params, colorgroup);
+
+ }
+ else if (tagid == XML_ELEMENTTAG_COLOR)
+ {
+ const wchar_t *colorstr = params->getItemValue(L"value");
+ StringW id = params->getItemValue(L"id");
+ const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id);
+ if (aliastarget)
+ id = aliastarget;
+ const wchar_t *colorgroup = params->getItemValue(L"colorgroup");
+ if (!colorgroup || !*colorgroup)
+ colorgroup = params->getItemValue(L"gammagroup");
+ if (!wcschr(colorstr, ','))
+ {
+ ARGB32 c = WASABI_API_PALETTE->getColorElement((colorstr));
+ WASABI_API_PALETTE->AddColor(id, c, colorgroup, rootpath, params);
+ }
+ else
+ {
+ WASABI_API_PALETTE->AddColor((id), SkinParser::parseColor(colorstr), colorgroup, rootpath, params);
+ }
+ }
+ else if (tagid == XML_ELEMENTTAG_BITMAPFONT)
+ {
+ Font::installBitmapFont(params->getItemValue(L"file"), rootpath, params->getItemValue(L"id"), params->getItemValueInt(L"charwidth", 0), params->getItemValueInt(L"charheight", 0), params->getItemValueInt(L"hspacing", 0), params->getItemValueInt(L"vspacing", 0), elementScriptId, params->getItemValueInt(L"allowmapping", 1));
+ }
+ else if (tagid == XML_ELEMENTTAG_TRUETYPEFONT)
+ {
+ Font::installTrueTypeFont(params->getItemValue(L"file"), rootpath, params->getItemValue(L"id"), elementScriptId, params->getItemValueInt(L"allowmapping", 1), 0);
+ }
+ else if (tagid == XML_ELEMENTTAG_CURSOR)
+ {
+ const wchar_t *bitmap = params->getItemValue(L"bitmap");
+ StringW id = params->getItemValue(L"id");
+ const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id);
+ int x = params->getItemValueInt(L"hotspot_x", 0);
+ int y = params->getItemValueInt(L"hotspot_y", 0);
+ if (aliastarget)
+ id = aliastarget;
+ WASABI_API_PALETTE->AddCursor(id, bitmap, x, y, rootpath, params);
+ }
+ else if (tagid == XML_ELEMENTTAG_UNKNOWN)
+ {
+ CollectionSvcEnum cse(xmltag);
+ svc_collection *svc;
+ if (svc = cse.getFirst())
+ { // got one!
+ svc->addElement(params->getItemValue(L"id"), rootpath, elementScriptId, params);
+ WASABI_API_SVC->service_release(svc);
+ }
+ }
+ else
+ {
+ DebugStringW(L"SkinElementsMgr: tag %s was recognized but not handled!\n", xmltag);
+ }
+}
+
+void SkinElementsMgr::resetSkinElements()
+{
+ WASABI_API_PALETTE->Reset();
+
+ Font::uninstallAll();
+ // remove any element inserted into a hierarchical collection
+ for (int i = 0;i < (int)WASABI_API_SVC->service_getNumServices(WaSvc::COLLECTION);i++)
+ {
+ waServiceFactory *f = WASABI_API_SVC->service_enumService(WaSvc::COLLECTION, i);
+ if (f != NULL)
+ {
+ svc_collection *svc = static_cast<svc_collection*>(f->getInterface(FALSE));
+ svc->removeAllElements();
+ f->releaseInterface(svc);
+ }
+ }
+}
+
+void SkinElementsMgr::onBeforeLoadingScriptElements(const wchar_t *name, int script_id)
+{
+ SkinElementsMgr::rootpathstack.addItem(new StringW(rootpath));
+ oldid = elementScriptId;
+ oldinel = inelements;
+
+ WASABI_API_PALETTE->StartTransaction();
+ wchar_t buf[WA_MAX_PATH] = {0};
+ WCSCPYN(buf, name, WA_MAX_PATH);
+
+ wchar_t *ptr = const_cast<wchar_t *>(Wasabi::Std::filename(buf));
+ if (ptr != NULL) *ptr = '\0';
+ rootpath = buf;
+ rootpath.AddBackslash();
+
+ original_rootpath = rootpath;
+
+ last_includepath = L"";
+
+ inelements = 0;
+ elementScriptId = script_id;
+}
+
+void SkinElementsMgr::onAfterLoadingScriptElements()
+{
+ WASABI_API_PALETTE->EndTransaction();
+ elementScriptId = oldid;
+ inelements = oldinel;
+ rootpath = SkinElementsMgr::rootpathstack.getLast();
+ delete SkinElementsMgr::rootpathstack.getLast();
+ SkinElementsMgr::rootpathstack.removeLastItem();
+}
+
+void SkinElementsMgr::unloadScriptElements(int scriptid)
+{
+ int i;
+
+
+ WASABI_API_PALETTE->UnloadElements(scriptid);
+
+ Font::uninstallByScriptId(scriptid);
+ // remove any element inserted into a hierarchical collection
+ for (i = 0;i < (int)WASABI_API_SVC->service_getNumServices(WaSvc::COLLECTION);i++)
+ {
+ waServiceFactory *f = WASABI_API_SVC->service_enumService(WaSvc::COLLECTION, i);
+ if (f != NULL)
+ {
+ svc_collection *svc = static_cast<svc_collection*>(f->getInterface(FALSE));
+ svc->removeElement(scriptid);
+ f->releaseInterface(svc);
+ }
+ }
+}
+
+int SkinElementsMgr::elementEqual(const wchar_t *file1, const wchar_t *rootpath1,
+ const wchar_t *file2, const wchar_t *rootpath2)
+{
+
+ StringPathCombine a(rootpath1, file1);
+ StringPathCombine b(rootpath2, file2);
+
+ return PATHEQL(a, b);
+}
+
+const wchar_t *SkinElementsMgr::getSkinRootpathFromIncludePath(const wchar_t *includepath, const wchar_t *def)
+{
+ if (!wcsstr(includepath, L"..")) return def;
+
+ PathParserW pp(includepath);
+ if (pp.getNumStrings() < 2 || !WCSCASEEQLSAFE(pp.enumString(0), L"skins")) // UNSAFE if the skinpath isn't "skins"
+ return def;
+
+ StringW baseskin = pp.enumString(1);
+
+ if (wcsstr(includepath, L".."))
+ {
+ int x = 0;
+ for (int i = 0;i < pp.getNumStrings();i++)
+ {
+ const wchar_t *p = pp.enumString(i);
+ if (WCSICMP(p, L".."))
+ {
+ if (x == 1)
+ baseskin = pp.enumString(i);
+ x++;
+ }
+ else
+ x--;
+ }
+ }
+
+ t_rootpath = pp.enumString(0);
+ t_rootpath.AppendFolder(baseskin);
+ return t_rootpath;
+}
+
+SkinElementsXmlReader SkinElementsMgr::xmlreader;
+int SkinElementsMgr::inelements = 0;
+int SkinElementsMgr::elementScriptId = -1;
+int SkinElementsMgr::oldid, SkinElementsMgr::oldinel;
+StringW SkinElementsMgr::rootpath, SkinElementsMgr::original_rootpath, SkinElementsMgr::t_rootpath, SkinElementsMgr::last_includepath;
+PtrList<StringW> SkinElementsMgr::rootpathstack;
+PtrListQuickSorted<xml_elementtag, XmlElementTagComp> SkinElementsMgr::quickxmltaglist;
diff --git a/Src/Wasabi/api/skin/skinelem.h b/Src/Wasabi/api/skin/skinelem.h
new file mode 100644
index 00000000..bc4f8185
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinelem.h
@@ -0,0 +1,106 @@
+#ifndef _SKINELEM_H
+#define _SKINELEM_H
+
+#include <api/xml/xmlreader.h>
+#include <tataki/region/region.h>
+
+#include <api/skin/skinitem.h>
+#include <api/xml/xmlparamsi.h>
+
+typedef struct
+{
+ const wchar_t *tagname;
+ int id;
+ int needclosetag;
+}
+xml_elementtag;
+
+class XmlElementTagComp
+{
+public:
+ static int compareItem(void *p1, void *p2)
+ {
+ return WCSICMP(((xml_elementtag *)p1)->tagname, ((xml_elementtag *)p2)->tagname);
+ }
+ static int compareAttrib(const wchar_t *attrib, void *item)
+ {
+ return WCSICMP(attrib, ((xml_elementtag *)item)->tagname);
+ }
+};
+
+enum {
+ XML_ELEMENTTAG_UNKNOWN = 0,
+ XML_ELEMENTTAG_ELEMENTS,
+ XML_ELEMENTTAG_ELEMENTALIAS,
+ XML_ELEMENTTAG_BITMAP,
+ XML_ELEMENTTAG_COLOR,
+ XML_ELEMENTTAG_BITMAPFONT,
+ XML_ELEMENTTAG_TRUETYPEFONT,
+ XML_ELEMENTTAG_CURSOR,
+
+};
+
+
+class ElementRegionServer;
+
+/*typedef enum {
+ SKIN_BITMAP_ELEMENT,
+ SKIN_FONT_ELEMENT,
+ SKIN_CURSOR_ELEMENT,
+ SKIN_COLOR_ELEMENT
+} SkinElementType;*/
+
+
+
+
+class SkinElementsXmlReader : public XmlReaderCallbackI
+{
+public:
+ void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmltag);
+};
+
+class SkinElementsMgr
+{
+public:
+ static void init();
+ static void deinit();
+
+ static void onBeforeLoadingSkinElements(const wchar_t *rootpath);
+ static void onAfterLoadingSkinElements();
+
+ static void onBeforeLoadingScriptElements(const wchar_t *name, int script_id);
+ static void onAfterLoadingScriptElements();
+
+ static void resetSkinElements();
+ static void unloadScriptElements(int scriptid);
+
+ static void xmlReaderOnStartElementCallback( const wchar_t *xmltag, skin_xmlreaderparams *params);
+ static void _xmlReaderOnStartElementCallback( int tagid, const wchar_t *xmltag, skin_xmlreaderparams *params);
+ static void xmlReaderOnEndElementCallback( const wchar_t *xmltag);
+
+ static const wchar_t *getSkinRootpathFromIncludePath(const wchar_t *includepath, const wchar_t *def);
+ static int elementEqual(const wchar_t *file1, const wchar_t *rootpath1,
+ const wchar_t *file2, const wchar_t *rootpath2);
+
+
+
+private:
+ static SkinElementsXmlReader xmlreader;
+
+ static int inelements;
+ static int elementScriptId;
+
+ static int oldid, oldinel;
+ static StringW rootpath;
+ static StringW original_rootpath;
+ static StringW t_rootpath;
+ static StringW last_includepath;
+ static PtrList<StringW> rootpathstack;
+
+ static PtrListQuickSorted<xml_elementtag, XmlElementTagComp> quickxmltaglist;
+};
+
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/skinfilter.cpp b/Src/Wasabi/api/skin/skinfilter.cpp
new file mode 100644
index 00000000..03dca473
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinfilter.cpp
@@ -0,0 +1,18 @@
+#include <precomp.h>
+#include "skinfilter.h"
+#include <api/service/svcs/svc_skinfilter.h>
+
+void ApplySkinFilters::apply(const wchar_t *elementid, const wchar_t *forced_gammagroup, ARGB32 *bits, int w, int h, int bpp)
+{
+ if ((elementid == NULL && forced_gammagroup == NULL) || bits == NULL || w <= 0 || h <= 0)
+ return;
+ SkinFilterEnum sfe;
+
+ while (1)
+ {
+ svc_skinFilter *obj = sfe.getNext(FALSE);
+ if (!obj) break;
+ obj->filterBitmap((uint8_t *)bits, w, h, bpp, elementid, forced_gammagroup);
+ sfe.getLastFactory()->releaseInterface(obj);
+ }
+}
diff --git a/Src/Wasabi/api/skin/skinfilter.h b/Src/Wasabi/api/skin/skinfilter.h
new file mode 100644
index 00000000..7fa0aaa8
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinfilter.h
@@ -0,0 +1,12 @@
+#ifndef _SKINFILTER_H
+#define _SKINFILTER_H
+
+#include <bfc/wasabi_std.h>
+
+class ApplySkinFilters
+{
+public:
+ static void apply(const wchar_t *element_id, const wchar_t *forced_gammagroup, ARGB32 *bits, int w, int h, int bpp=32);
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/skinfont.cpp b/Src/Wasabi/api/skin/skinfont.cpp
new file mode 100644
index 00000000..1c370e3f
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinfont.cpp
@@ -0,0 +1,48 @@
+#include <precomp.h>
+
+#include "skinfont.h"
+
+#include <bfc/wasabi_std.h>
+
+SkinFont::SkinFont()
+{}
+
+SkinFont::~SkinFont()
+{
+ if (!tempFn.isempty())
+ {
+#ifdef WIN32
+ RemoveFontResourceW(tempFn);
+#else
+ DebugString( "portme -- SkinFont::~SkinFont\n" );
+#endif
+ UNLINK(tempFn);
+ }
+}
+
+int SkinFont::setXmlOption(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ return 0;
+}
+
+void SkinFont::installFont(const wchar_t *filename, const wchar_t *path)
+{
+ OSFILETYPE in, out;
+ StringPathCombine temp(path, filename);
+ in = WFOPEN(temp, WF_READONLY_BINARY);
+ if (in == OPEN_FAILED) return ;
+ int len = (int)FGETSIZE(in);
+ MemBlock<char> m(len);
+ FREAD(m.getMemory(), len, 1, in);
+ tempFn = TMPNAM(NULL);
+ out = WFOPEN(tempFn, WF_WRITE_BINARY);
+ ASSERT(out != OPEN_FAILED);
+ FWRITE(m.getMemory(), len, 1, out);
+ FCLOSE(out);
+ FCLOSE(in);
+#ifdef WIN32
+ AddFontResourceW(tempFn);
+#else
+ DebugString( "portme -- SkinFont::installFont\n" );
+#endif
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/skinfont.h b/Src/Wasabi/api/skin/skinfont.h
new file mode 100644
index 00000000..b70895e0
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinfont.h
@@ -0,0 +1,17 @@
+#ifndef _SKINFONT_H
+#define _SKINFONT_H
+
+#include <api/skin/xmlobject.h>
+
+class SkinFont : public XmlObjectI
+{
+public:
+ SkinFont();
+ ~SkinFont();
+ void installFont(const wchar_t *filename, const wchar_t *path);
+ virtual int setXmlOption(const wchar_t *name, const wchar_t *val);
+private:
+ StringW tempFn;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/skinitem.cpp b/Src/Wasabi/api/skin/skinitem.cpp
new file mode 100644
index 00000000..d4f0f1b3
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinitem.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+#include "skinitem.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS SkinItemI
+START_DISPATCH;
+ CB(SKINITEM_GETXMLROOTPATH, getXmlRootPath);
+ CB(SKINITEM_GETNAME, getName);
+ CB(SKINITEM_GETPARAMS, getParams);
+ CB(SKINITEM_GETSKINPARTID, getSkinPartId);
+ CB(SKINITEM_GETANCESTOR, getAncestor);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/skin/skinitem.h b/Src/Wasabi/api/skin/skinitem.h
new file mode 100644
index 00000000..88d82c13
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinitem.h
@@ -0,0 +1,66 @@
+#ifndef __SKINITEM_H
+#define __SKINITEM_H
+
+#include <bfc/dispatch.h>
+#include "../xml/ifc_xmlreaderparams.h"
+
+class skin_xmlreaderparams;
+
+class SkinItem : public Dispatchable
+{
+ public:
+ const wchar_t *getXmlRootPath();
+ const wchar_t *getName();
+ ifc_xmlreaderparams *getParams();
+ int getSkinPartId();
+ SkinItem *getAncestor();
+
+ enum
+ {
+ SKINITEM_GETXMLROOTPATH = 0,
+ SKINITEM_GETNAME = 10,
+ SKINITEM_GETPARAMS = 20,
+ SKINITEM_GETSKINPARTID = 30,
+ SKINITEM_GETANCESTOR = 40,
+ };
+};
+
+inline const wchar_t *SkinItem::getXmlRootPath()
+{
+ return _call(SKINITEM_GETXMLROOTPATH, (const wchar_t *)0);
+}
+
+inline const wchar_t *SkinItem::getName()
+{
+ return _call(SKINITEM_GETNAME, (const wchar_t *)0);
+}
+
+inline ifc_xmlreaderparams *SkinItem::getParams()
+{
+ return _call(SKINITEM_GETPARAMS, (ifc_xmlreaderparams *)NULL);
+}
+
+inline int SkinItem::getSkinPartId()
+{
+ return _call(SKINITEM_GETSKINPARTID, (int)0);
+}
+
+inline SkinItem *SkinItem::getAncestor()
+{
+ return _call(SKINITEM_GETANCESTOR, (SkinItem *)NULL);
+}
+
+class SkinItemI : public SkinItem
+{
+ public:
+ virtual const wchar_t *getXmlRootPath()=0;
+ virtual const wchar_t *getName()=0;
+ virtual ifc_xmlreaderparams *getParams()=0;
+ virtual int getSkinPartId()=0;
+ virtual SkinItem *getAncestor()=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/skinparse.cpp b/Src/Wasabi/api/skin/skinparse.cpp
new file mode 100644
index 00000000..7df77e81
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinparse.cpp
@@ -0,0 +1,1822 @@
+#include <precomp.h>
+#include <api.h>
+#include <api/skin/widgets/mb/scriptbrowser.h>
+#include <api/skin/skinparse.h>
+#include <api/script/scriptmgr.h>
+//#include <api/wac/main.h>//CUT!!
+#include <api/skin/skinfont.h>
+#include <api/skin/skin.h>
+#include <api/skin/skinelem.h>
+#include <api/font/font.h>
+#include <api/wndmgr/snappnt.h>
+#include <bfc/parse/pathparse.h>
+#include <api/skin/guitree.h>
+#ifdef WASABI_COMPILE_COMPONENTS
+#include <api/wac/compon.h>
+#endif
+#include <api/service/svc_enum.h>
+#include <api/script/objects/guiobject.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/autopopup.h>
+#endif
+#include <bfc/parse/paramparser.h>
+#include <api/skin/gammamgr.h>
+#include <bfc/util/profiler.h>
+#ifdef WASABI_COMPILE_LOCALES
+#include <api/locales/xlatstr.h>
+#include <api/locales/localesmgr.h>
+#else
+#define _
+#endif
+#include <bfc/string/stringdict.h>
+#include <api/skin/widgets.h>
+
+#ifdef _WIN32
+extern HINSTANCE hInstance;
+#endif
+
+#define COLOR_WHITE (0xffffff)
+#define COLOR_BLACK (0x000000)
+#define COLOR_ERROR (0xff00ff)
+
+// with alpha
+#define COLOR_WHITEA (0xffffffff)
+#define COLOR_BLACKA (0xff000000)
+#define COLOR_ERRORA (0xffff00ff)
+
+xml_tag taglist[] = {
+ {L"groupdef", XML_TAG_GROUPDEF, 1},
+ {L"group", XML_TAG_GROUP, 1},
+ {L"cfggroup", XML_TAG_CFGGROUP, 1},
+ {L"elements", XML_TAG_ELEMENTS, 1},
+ {L"snappoint", XML_TAG_SNAPPOINT, 0},
+ {L"script", XML_TAG_SCRIPT, 0},
+ {L"container", XML_TAG_CONTAINER, 1},
+ {L"layout", XML_TAG_LAYOUT, 1},
+ {L"elements", XML_ELEMENTTAG_ELEMENTS, 1},
+ {L"accelerators", XML_TAG_ACCELERATORS, 1},
+ {L"accelerator", XML_TAG_ACCELERATOR, 1},
+ {L"stringtable", XML_TAG_STRINGTABLE, 1},
+ {L"stringentry", XML_TAG_STRINGENTRY, 1},
+ };
+
+BEGIN_STRINGDICTIONARY(_resizevalues)
+SDI(L"top", RESIZE_TOP);
+SDI(L"left", RESIZE_LEFT);
+SDI(L"right", RESIZE_RIGHT);
+SDI(L"bottom", RESIZE_BOTTOM);
+SDI(L"topleft", RESIZE_TOPLEFT);
+SDI(L"topright", RESIZE_TOPRIGHT);
+SDI(L"bottomleft", RESIZE_BOTTOMLEFT);
+SDI(L"bottomright", RESIZE_BOTTOMRIGHT);
+END_STRINGDICTIONARY(_resizevalues, resizevalues)
+
+BEGIN_STRINGDICTIONARY(_parsetypes)
+SDI(L"resize", PARSETYPE_RESIZE);
+SDI(L"color", PARSETYPE_COLOR);
+SDI(L"coloralpha", PARSETYPE_COLORALPHA);
+SDI(L"regionop", PARSETYPE_REGIONOP);
+SDI(L"internal_action", PARSETYPE_INTERNALACTION);
+SDI(L"group_inheritance", PARSETYPE_GROUPINHERITANCE);
+END_STRINGDICTIONARY(_parsetypes, parsetypes)
+
+BEGIN_STRINGDICTIONARY(_actionlist)
+SDI(L"none", ACTION_NONE);
+#ifdef WA3COMPATIBILITY
+SDI(L"about", ACTION_ABOUT);
+SDI(L"mb_forward", ACTION_MB_FORWARD);
+SDI(L"mb_back", ACTION_MB_BACK);
+SDI(L"mb_url", ACTION_MB_URL);
+SDI(L"mb_home", ACTION_MB_HOME);
+SDI(L"mb_stop", ACTION_MB_STOP);
+SDI(L"mb_refresh", ACTION_MB_REFRESH);
+SDI(L"text_larger", ACTION_TEXT_LARGER);
+SDI(L"text_smaller", ACTION_TEXT_SMALLER);
+SDI(L"preferences", ACTION_PREFERENCES);
+SDI(L"view_file_info", ACTION_VIEW_FILE_INFO);
+SDI(L"doublesize", ACTION_DOUBLESIZE);
+SDI(L"add_bookmark", ACTION_ADD_BOOKMARK);
+SDI(L"menu", ACTION_MENU);
+SDI(L"sysmenu", ACTION_SYSMENU);
+SDI(L"windowmenu", ACTION_WINDOWMENU);
+SDI(L"controlmenu", ACTION_CONTROLMENU);
+#endif // wa3compatibility
+#ifdef WASABI_WIDGETS_COMPBUCK
+SDI(L"cb_next", ACTION_CB_NEXT);
+SDI(L"cb_prev", ACTION_CB_PREV);
+SDI(L"cb_prevpage", ACTION_CB_PREVPAGE);
+SDI(L"cb_nextpage", ACTION_CB_NEXTPAGE);
+#endif
+#ifdef WASABI_COMPILE_WNDMGR
+SDI(L"endmodal", ACTION_ENDMODAL);
+SDI(L"minimize", ACTION_MINIMIZE);
+SDI(L"maximize", ACTION_MAXIMIZE);
+SDI(L"close", ACTION_CLOSE);
+SDI(L"close_window", ACTION_CLOSE_WINDOW);
+SDI(L"switch", ACTION_SWITCH);
+SDI(L"toggle", ACTION_TOGGLE);
+SDI(L"reload_skin", ACTION_RELOAD_SKIN);
+SDI(L"enforce_minmax", ACTION_ENFORCEMINMAX);
+SDI(L"toggle_always_on_top", ACTION_TOGGLE_ALWAYS_ON_TOP);
+#endif // wndmgr
+END_STRINGDICTIONARY(_actionlist, actionlist)
+
+#ifdef WASABI_COMPILE_MEDIACORE
+BEGIN_STRINGDICTIONARY(_displaylist)
+SDI(L"songname", DISPLAY_SONGNAME);
+SDI(L"songinfo", DISPLAY_SONGINFO);
+SDI(L"songartist", DISPLAY_SONGARTIST);
+SDI(L"songtitle", DISPLAY_SONGTITLE);
+SDI(L"songalbum", DISPLAY_SONGALBUM);
+SDI(L"songlength", DISPLAY_SONGLENGTH);
+SDI(L"time", DISPLAY_TIME);
+SDI(L"timeelapsed", DISPLAY_TIME);
+SDI(L"timeremaining", DISPLAY_TIME);
+SDI(L"componentbucket", DISPLAY_CB);
+SDI(L"songbitrate", DISPLAY_SONGBITRATE);
+SDI(L"songsamplerate", DISPLAY_SONGSAMPLERATE);
+SDI(L"songinfo_localise", DISPLAY_SONGINFO_TRANSLATED);
+END_STRINGDICTIONARY(_displaylist, displaylist)
+#endif // mediacore
+
+static GUID staticguid;
+
+void SkinParser::initialize()
+{
+ if (!quickxmltaglist.getNumItems())
+ {
+ for (int i = 0;i < sizeof(taglist) / sizeof(xml_tag);i++)
+ quickxmltaglist.addItem(&taglist[i]);
+ }
+
+ // first two are for back compatibility
+ skinXML.registerCallback(L"WinampAbstractionLayer", xmlReaderCallback);
+ skinXML.registerCallback(L"WinampAbstractionLayer\f*", xmlReaderCallback);
+ skinXML.registerCallback(L"WasabiXML", xmlReaderCallback);
+ skinXML.registerCallback(L"WasabiXML\f*", xmlReaderCallback);
+
+ guiTree = new GuiTree();
+
+ xuiCache = new SvcCacheT<svc_xuiObject>;
+}
+
+void SkinParser::shutdown()
+{
+ skinXML.unregisterCallback((void*)xmlReaderCallback);
+ delete guiTree; guiTree = NULL;
+ delete xuiCache; xuiCache = NULL;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void SkinParser::setInitialFocus()
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ {
+ if (containers[i]->isVisible())
+ {
+ Layout *l = containers[i]->getCurrentLayout();
+ if (l)
+ {
+ l->setFocus();
+ return ;
+ }
+ }
+ }
+#ifdef WIN32
+#ifdef WA3COMPATIBILITY
+ SetFocus(Main::gethWnd());
+#endif //WA3COMPATIBILITY
+#else
+ DebugString( "portme -- SkinParser::setInitialFocus\n" );
+#endif //WIN32
+}
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+// do not forget to popParserState(); before returning
+int SkinParser::loadContainers(const wchar_t *skin)
+{
+ wchar_t olddir[WA_MAX_PATH] = {0};
+ Wasabi::Std::getCurDir(olddir, WA_MAX_PATH);
+ Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath());
+ int oldncontains = getNumContainers();
+ pushParserState();
+ allowscripts = 1;
+ centerskin = 1;
+ staticloading = 1;
+ instantiatinggroup = 0;
+ transcientcontainer = 0;
+ inContainer = inLayout = 0;
+ curGroup = NULL;
+ recording_container = 0;
+ recording_groupdef = 0;
+ inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0;
+ includepath = WASABI_API_SKIN->getSkinPath();
+ loading_main_skinfile = 0;
+ SkinElementsMgr::onBeforeLoadingSkinElements(includepath);
+ GammaMgr::onBeforeLoadingGammaGroups();
+ scriptId = WASABI_API_PALETTE->getSkinPartIterator();
+ int skinType = Skin::checkSkin(skin);
+ int retcode = 0;
+ loading_main_skinfile = 1;
+ switch (skinType)
+ {
+ case Skin::CHKSKIN_UNKNOWN:
+ popParserState();
+ break;
+#ifdef WA3COMPATIBILITY
+ case Skin::CHKSKIN_ISWA2:
+ retcode = XmlReader::loadFile("svc:wa2skinxml", includepath);
+ break;
+#endif
+ default:
+ {
+ retcode = skinXML.loadFile(StringPathCombine(includepath, L"skin.xml"), includepath);
+ break;
+ }
+ }
+
+ int n = guiTree->getNumObject(XML_TAG_CONTAINER);
+ for (int i = 0;i < n;i++)
+ {
+ SkinItem *item = guiTree->getObject(XML_TAG_CONTAINER, i);
+ if (item && item->getParams())
+ {
+ if (item->getParams()->getItemValueInt(L"dynamic"))
+ {
+ if (item->getParams()->getItemValueInt(L"default_visible"))
+ {
+ const wchar_t *name = item->getParams()->getItemValue(L"name");
+#ifdef ON_TWEAK_CONTAINER_NAMEW
+ ON_TWEAK_CONTAINER_NAMEW(name);
+#endif
+ wchar_t c[512]=L"-";
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"everloaded/%s", name), c, 511, L"-");
+#endif
+ c[510] = 0;
+ if (c[0] == '-')
+ {
+ // never been created, create it now since it has default_visible
+ staticloading = 0;
+ /*Container *c = */instantiateDynamicContainer(item);
+ staticloading = 1;
+ }
+ }
+ }
+ }
+ }
+
+ loading_main_skinfile = 0;
+
+ Wasabi::Std::setCurDir(olddir);
+
+ int ncontainersloaded = getNumContainers() - oldncontains;
+ if (retcode == 0 || ncontainersloaded == 0)
+ {
+ return 0;
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->setStringPrivate(L"last_skin", Skin::getSkinName());
+#endif
+
+ ASSERT(tha != NULL);
+ SkinElementsMgr::onAfterLoadingSkinElements();
+ GammaMgr::onAfterLoadingGammaGroups();
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ ComponentManager::broadcastNotify(WAC_NOTIFY_SKINGUILOADED, WASABI_API_PALETTE->getSkinPartIterator());
+#endif
+
+ Skin::sendGuiLoadedCallback();
+ popParserState();
+ return ncontainersloaded;
+}
+
+void SkinParser::centerSkin()
+{
+ RECT sr;
+ if (centerskin && getSkinRect(&sr))
+ {
+ int l = getNumContainers();
+ int w = (Wasabi::Std::getScreenWidth() - (sr.right - sr.left)) / 2;
+ int h = (Wasabi::Std::getScreenHeight() - (sr.bottom - sr.top)) / 2;
+ for (int i = 0;i < l;i++)
+ {
+ Container *c = enumContainer(i);
+ if (!c->isVisible()) continue;
+ Layout *l = c->getCurrentLayout();
+ RECT r;
+ l->getWindowRect(&r);
+ r.left += w;
+ r.right += w;
+ r.bottom += h;
+ r.top += h;
+ l->move(r.left, r.top);
+ }
+ }
+ foreach(containers)
+ containers.getfor()->savePositions();
+ endfor;
+}
+
+int SkinParser::getSkinRect(RECT *r, ifc_window *exclude)
+{
+ if (!r) return 0;
+ ZERO(*r);
+ Container *cexcluded = NULL;
+ if (exclude != NULL)
+ {
+ Layout *l = static_cast<Layout *>(exclude->getDesktopParent());
+ if (l != NULL) cexcluded = l->getParentContainer();
+ }
+ int x = 99999, y = 99999, x2 = -1, y2 = -1;
+ int l = getNumContainers();
+ for (int i = 0;i < l;i++)
+ {
+ Container *c = enumContainer(i);
+ if (c == cexcluded) continue;
+ if (!c->isInited()) c->onInit();
+ if (c->isDeleting() || !c->getCurrentLayout()) continue;
+ int cx = c->getDefaultPositionX();
+ int cy = c->getDefaultPositionY();
+ if (cx == -1) cx = 0;
+ if (cy == -1) cy = 0;
+ RECT r;
+ c->getWindowRect(&r);
+ int cw = r.right - r.left;
+ int ch = r.bottom - r.top;
+ if (cx < x) x = cx;
+ if (cy < y) y = cy;
+ if ((cx + cw) > x2) x2 = cx + cw;
+ if ((cy + ch) > y2) y2 = cy + ch;
+ }
+ if (x2 > 0 && y2 > 0 && x != 99999 && y != 99999)
+ {
+ Wasabi::Std::setRect(r, x, y, x2, y2);
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+// do not forget to popParserState(); before returning
+void SkinParser::loadScriptXml(const wchar_t *filename, int scriptid)
+{
+ pushParserState();
+ allowscripts = 1;
+ instantiatinggroup = 0;
+#ifdef WASABI_COMPILE_WNDMGR
+ transcientcontainer = 0;
+ inContainer = inLayout = 0;
+#endif
+ staticloading = 1;
+ recording_container = 0;
+ recording_groupdef = 0;
+ curGroup = NULL;
+ inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0;
+ scriptId = scriptid;
+
+ //CUT char file[WA_MAX_PATH];
+ //CUT char drive[WA_MAX_PATH];
+ //CUT char dir[WA_MAX_PATH];
+ //CUT char fname[WA_MAX_PATH];
+ //CUT char ext[WA_MAX_PATH];
+
+
+ includepath.setValue(L"");
+
+ wchar_t olddir[WA_MAX_PATH] = {0};
+ Wasabi::Std::getCurDir(olddir, WA_MAX_PATH);
+ Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath());
+
+ if (!WCSNICMP(filename, L"buf:", 4))
+ {
+ skinXML.loadFile(filename, includepath);
+ }
+ else
+ {
+ //CUT DebugString("filename is %s\n", filename);
+ includepath = filename;
+ includepath.RemovePath();
+
+ skinXML.loadFile(filename /*file*/, includepath);
+ }
+
+ Wasabi::Std::setCurDir(olddir);
+
+ popParserState();
+}
+
+
+#ifdef WASABI_COMPILE_WNDMGR
+// do not forget to popParserState(); before returning
+Container *SkinParser::loadContainerForWindowHolder(const wchar_t *groupid, GUID g, int initit, int transcient, const wchar_t *containerid, int container_flag)
+{
+ ASSERTPR((g == INVALID_GUID || groupid == NULL) && (g != INVALID_GUID || groupid != NULL), "sorry, one or the other, indulge aristotle");
+ pushParserState();
+ allowscripts = 1;
+ instantiatinggroup = 0;
+ transcientcontainer = transcient;
+ staticloading = 0;
+ recording_container = 0;
+ recording_groupdef = 0;
+ curContainer = NULL;
+ lastCreatedContainer = NULL;
+ curGroup = NULL;
+ inContainer = inLayout = inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0;
+ scriptId = -1; //WASABI_API_PALETTE->getSkinPartIterator();
+ SkinItem *found = NULL;
+ SkinItem *generic = NULL;
+
+ for (int i = guiTree->getNumObject(XML_TAG_CONTAINER) - 1;i >= 0 && found == NULL;i--)
+ {
+ SkinItem *item = guiTree->getObject(XML_TAG_CONTAINER, i);
+ if (item == NULL) continue;
+ ifc_xmlreaderparams *par = item->getParams();
+ if (!par) continue;
+
+ if (g != INVALID_GUID)
+ {
+ for (size_t j = 0;found == NULL && j != par->getNbItems();j++)
+ {
+ const wchar_t *p = par->getItemName(j);
+ if (!WCSICMP(p, L"component") || !WCSICMP(p, L"hold"))
+ {
+ ParamParser pp(par->getItemValue(j));
+ if (pp.hasGuid(g) && found == NULL)
+ {
+ found = item;
+ break;
+ }
+ if (generic == NULL && (pp.hasGuid(GENERIC_GUID) || pp.hasString(L"@ALL@")))
+ {
+ generic = item;
+ }
+ }
+ }
+ }
+ else if (groupid != NULL)
+ {
+ for (size_t j = 0;j != par->getNbItems() && found == NULL;j++)
+ {
+ const wchar_t *p = par->getItemName(j);
+ if (!WCSICMP(p, L"hold"))
+ {
+ ParamParser pp(par->getItemValue(j));
+ if (pp.hasString(groupid))
+ {
+ found = item;
+ break;
+ }
+ if (pp.hasString(L"@ALL@"))
+ {
+ generic = item;
+ }
+ }
+ }
+ }
+ }
+
+ if (found == NULL && generic == NULL)
+ {
+ popParserState();
+ return NULL;
+ }
+
+ if (!found)
+ {
+ if (containerid != NULL)
+ {
+ SkinItem *item = guiTree->getContainerById(containerid);
+ if (item != NULL)
+ {
+ Container *c = instantiateDynamicContainer(item, initit);
+ popParserState();
+ return c;
+ }
+ }
+ else
+ {
+ if (container_flag != 0) return NULL;
+ }
+ }
+
+ Container *c = instantiateDynamicContainer(found != NULL ? found : generic, initit);
+ popParserState();
+ return c;
+}
+
+Container *SkinParser::instantiateDynamicContainer(SkinItem *containeritem, int initit)
+{
+
+ int quit = 0;
+ int guitreeid = guiTree->getObjectIdx(containeritem);
+ for (int i = guitreeid;i < guiTree->getNumObject() && !quit;i++)
+ {
+ SkinItem *ii = guiTree->getList()->enumItem(i);
+ ifc_xmlreaderparams *params = ii->getParams();
+ const wchar_t *path = ii->getXmlRootPath();
+ if (path)
+ includepath = path;
+ int object_type = guiTree->getObjectType(ii);
+ const wchar_t *name = ii->getName();
+ if (!params)
+ {
+ if (object_type == XML_TAG_CONTAINER)
+ quit = 1;
+ _onXmlEndElement(object_type, name);
+ }
+ else
+ {
+ _onXmlStartElement(object_type, name, params);
+ }
+ }
+ return lastCreatedContainer;
+}
+
+// do not forget to popParserState(); before returning
+Container *SkinParser::newDynamicContainer(const wchar_t *containerid, int transcient)
+{
+
+ pushParserState();
+
+ allowscripts = 1;
+ instantiatinggroup = 0;
+ transcientcontainer = transcient;
+ staticloading = 0;
+ recording_container = 0;
+ recording_groupdef = 0;
+ curContainer = NULL;
+ lastCreatedContainer = NULL;
+ curGroup = NULL;
+ inContainer = inLayout = inElements = inGroup = inGroupDef = inAccelerators = inStringTable = 0;
+ scriptId = WASABI_API_PALETTE->getSkinPartIterator();
+ SkinItem *found = NULL;
+
+ for (int i = guiTree->getNumObject(XML_TAG_CONTAINER) - 1;i >= 0 && found == NULL;i--)
+ {
+ SkinItem *item = guiTree->getObject(XML_TAG_CONTAINER, i);
+ ifc_xmlreaderparams *par = item->getParams();
+ if (!par) continue;
+ const wchar_t *p = par->getItemValue(L"id");
+ if (!WCSICMP(p, containerid))
+ {
+ found = item;
+ break;
+ }
+ }
+
+ Container *c = NULL;
+ if (found != NULL)
+ c = instantiateDynamicContainer(found);
+
+ popParserState();
+
+ return c;
+}
+
+#endif
+
+// do not forget to popParserState(); before returning
+void SkinParser::fillGroup(Group *group, const wchar_t *groupid, SkinItem *specific_item, int params_only, int no_params, int scripts_enabled)
+{
+ ASSERT(group != NULL);
+ pushParserState();
+
+ instantiatinggroup = 1;
+
+#ifdef WASABI_COMPILE_WNDMGR
+ transcientcontainer = 0;
+#endif
+
+ allowscripts = scripts_enabled;
+ staticloading = 0;
+ recording_container = 0;
+ recording_groupdef = 0;
+ lastCreatedGroup = NULL;
+ scriptId = group->getSkinPartId();
+ SkinItem *found = NULL;
+
+ PtrList<ifc_xmlreaderparams> ancestor_param_list;
+
+ found = specific_item == NULL ? guiTree->getGroupDef(groupid) : specific_item;
+
+ if (found == NULL)
+ {
+ popParserState();
+ return ;
+ }
+
+ curGroup = group;
+ inGroup = 1;
+ parseGroup(found, &ancestor_param_list, params_only);
+
+ if (!no_params)
+ {
+ XmlObject *xo = static_cast<XmlObject *>(curGroup->getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ for (int i = ancestor_param_list.getNumItems() - 1;i >= 0;i--)
+ initXmlObject(xo, ancestor_param_list.enumItem(i), 1);
+ }
+
+ popParserState();
+}
+
+GuiObject *SkinParser::newDynamicGroup(const wchar_t *groupid, int grouptype, SkinItem *specific_item, int specific_scriptid, int scripts_enabled)
+{
+#ifdef WASABI_COMPILE_CONFIG
+ int iscfggroup = (grouptype == GROUP_CFGGROUP);
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+ int islayoutgroup = (grouptype == GROUP_LAYOUTGROUP);
+#endif
+
+ Group *r = NULL;
+#ifdef WASABI_COMPILE_CONFIG
+ if (!iscfggroup)
+ {
+#endif
+#ifdef WASABI_COMPILE_WNDMGR
+ if (!islayoutgroup)
+ r = new Group;
+ else
+ {
+ Layout *l = new Layout;
+ r = l;
+ l->setParentContainer(NULL);
+ }
+#else // wndmgr
+ r = new Group;
+#endif // wndmgr
+#ifdef WASABI_COMPILE_CONFIG
+
+ }
+ else
+ r = new CfgGroup;
+#endif
+
+ r->setSkinPartId(specific_scriptid > -1 ? specific_scriptid : WASABI_API_PALETTE->getSkinPartIterator());
+
+ if (r != NULL)
+ {
+ r->setXmlParam(L"id", groupid);
+ r->setGroupContent(groupid, specific_item, scripts_enabled);
+ fillGroup(r, groupid, specific_item, 1, 0, scripts_enabled);
+ return r->getGuiObject();
+ }
+ return NULL;
+}
+
+void SkinParser::pushParserState()
+{
+ parser_status *p = new parser_status;
+#ifdef WASABI_COMPILE_WNDMGR
+ p->curContainer = curContainer;
+ p->curLayout = curLayout;
+ p->inContainer = inContainer;
+ p->inLayout = inLayout;
+ p->transcientcontainer = transcientcontainer;
+#endif
+ p->staticloading = staticloading;
+ p->curGroup = curGroup;
+ p->includepath = includepath;
+ p->inElements = inElements;
+ p->inGroup = inGroup;
+ p->inGroupDef = inGroupDef;
+ p->instantiatinggroup = instantiatinggroup;
+ p->scriptid = scriptId;
+ p->allowscripts = allowscripts;
+ p->inAccelerators = inAccelerators;
+ p->inStringTable = inStringTable;
+ statusstack.addItem(p);
+}
+
+void SkinParser::popParserState()
+{
+ ASSERT(statusstack.getNumItems() > 0);
+ parser_status *p = statusstack.enumItem(statusstack.getNumItems() - 1);
+ statusstack.removeByPos(statusstack.getNumItems() - 1);
+ ASSERT(p != NULL);
+#ifdef WASABI_COMPILE_WNDMGR
+ curContainer = p->curContainer;
+ curLayout = p->curLayout;
+ inContainer = p->inContainer;
+ inLayout = p->inLayout;
+ transcientcontainer = p->transcientcontainer;
+#endif
+ curGroup = p->curGroup;
+ includepath = p->includepath;
+ inElements = p->inElements;
+ inAccelerators = p->inAccelerators;
+ inStringTable = p->inStringTable;
+ inGroup = p->inGroup;
+ inGroupDef = p->inGroupDef;
+ staticloading = p->staticloading;
+ instantiatinggroup = p->instantiatinggroup;
+ scriptId = p->scriptid;
+ allowscripts = p->allowscripts;
+ delete p;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+
+Container *SkinParser::getContainer(const wchar_t *id)
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ if (!WCSICMP(id, containers.enumItem(i)->getId()))
+ return containers.enumItem(i);
+ return NULL;
+}
+
+Layout *SkinParser::getLayout(const wchar_t *contlay)
+{
+ PathParserW pp(contlay, L",");
+ if (pp.getNumStrings() == 2)
+ {
+ Container *c = SkinParser::getContainer(pp.enumString(0));
+ if (c)
+ {
+ Layout *l = c->getLayout(pp.enumString(1));
+ if (l)
+ {
+ return l;
+ }
+ }
+ }
+ return NULL;
+}
+
+int SkinParser::script_getNumContainers()
+{
+ return containers.getNumItems();
+}
+
+Container *SkinParser::script_enumContainer(int n)
+{
+ return containers.enumItem(n);
+}
+
+int SkinParser::isContainer(Container *c)
+{
+ return containers.haveItem(c);
+}
+
+Container *SkinParser::script_getContainer(const wchar_t *id)
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ {
+ Container *c = containers.enumItem(i);
+ if (c)
+ {
+ const wchar_t *c_id = containers.enumItem(i)->getId();
+ if (c_id && !WCSICMP(id, c_id))
+ return containers.enumItem(i);
+ }
+ }
+ return NULL;
+}
+
+void SkinParser::componentToggled(GUID *g, int visible)
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ containers[i]->componentToggled(g, visible);
+}
+
+void SkinParser::sendNotifyToAllContainers(int notifymsg, int param1, int param2)
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ containers[i]->sendNotifyToAllLayouts(notifymsg, param1, param2);
+}
+
+
+void SkinParser::toggleContainer(int num)
+{
+ if (num < 0) return ;
+ if (num > containers.getNumItems()) return ;
+
+ Container *c = containers[num];
+ if (!c) return ;
+ c->toggle();
+}
+
+void SkinParser::startupContainers(int scriptid)
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ {
+ if (scriptid == -1 || containers[i]->getScriptId() == scriptid && !containers[i]->isDynamic())
+ containers[i]->onInit();
+ }
+}
+
+void SkinParser::showContainer(int num, int show)
+{
+ if (num < 0) return ;
+ if (num > containers.getNumItems()) return ;
+
+ Container *c = containers[num];
+ c->setVisible(show);
+}
+
+#endif // wndmgr
+
+int SkinParser::getHex(const wchar_t *p, int size)
+{
+ int v = 0, i = 0;
+ while (*p != 0 && *p != '-' && *p != '}')
+ {
+ unsigned int a = *p;
+ if (a >= '0' && a <= '9') a -= '0';
+ if (a >= 'a' && a <= 'f') a -= 'a' -10;
+ if (a >= 'A' && a <= 'F') a -= 'A' -10;
+ v = (v * 16) + a;
+ p++;
+ i++; if (size != -1 && i == size) return v;
+ }
+ return v;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+int SkinParser::getComponentGuid(GUID *g, const wchar_t *p)
+{
+ g->Data1 = getHex(p);
+ while (*p != 0 && *p != '-') p++;
+ if (*p == '-')
+ {
+ p++;
+ g->Data2 = getHex(p);
+ while (*p != 0 && *p != '-') p++;
+ if (*p == '-')
+ {
+ p++;
+ g->Data3 = getHex(p);
+ while (*p != 0 && *p != '-') p++;
+ if (*p == '-')
+ {
+ p++;
+ g->Data4[0] = getHex(p, 2); p += 2;
+ g->Data4[1] = getHex(p, 2); p += 3;
+ g->Data4[2] = getHex(p, 2); p += 2;
+ g->Data4[3] = getHex(p, 2); p += 2;
+ g->Data4[4] = getHex(p, 2); p += 2;
+ g->Data4[5] = getHex(p, 2); p += 2;
+ g->Data4[6] = getHex(p, 2); p += 2;
+ g->Data4[7] = getHex(p, 2);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+GUID *SkinParser::getComponentGuid(const wchar_t *id)
+{
+ static GUID g;
+ g = nsGUID::fromCharW(id);
+ if (g == INVALID_GUID) return NULL;
+ return &g;
+}
+
+#endif
+
+int SkinParser::parse(const wchar_t *str, const wchar_t *what)
+{
+ int a = parsetypes.getId(what);
+ if (a < 0) return WTOI(str);
+ switch (a)
+ {
+ case PARSETYPE_RESIZE: return parseResize(str);
+ case PARSETYPE_COLOR: return parseColor(str);
+ case PARSETYPE_COLORALPHA: return parseColorAlpha(str);
+ case PARSETYPE_REGIONOP: return parseRegionOp(str);
+ case PARSETYPE_INTERNALACTION: return getAction(str);
+ case PARSETYPE_GROUPINHERITANCE: return parseGroupInheritance(str);
+ }
+ // todo: add svc_intParser
+ return 0;
+}
+
+int SkinParser::parseGroupInheritance(const wchar_t *str)
+{
+ if (WCSCASEEQLSAFE(str, L"1")) return GROUP_INHERIT_ALL;
+ if (WCSCASEEQLSAFE(str, L"0")) return GROUP_INHERIT_NOTHING;
+ ParamParser pp(str);
+ int v = 0;
+ for (int i = 0;i < pp.getNumItems();i++)
+ {
+ const wchar_t *s = pp.enumItem(i);
+ if (WCSCASEEQLSAFE(s, L"xui")) v |= GROUP_INHERIT_XUIOBJECTS;
+ if (WCSCASEEQLSAFE(s, L"scripts")) v |= GROUP_INHERIT_SCRIPTS;
+ if (WCSCASEEQLSAFE(s, L"params")) v |= GROUP_INHERIT_PARAMS;
+ }
+ return v;
+}
+
+ARGB32 SkinParser::parseColor(const wchar_t *color, int *error)
+{
+ if (color == NULL || *color == '\0') { if (error) *error = 1; return COLOR_ERROR; }
+ if (!WCSICMP(color, L"white")) return COLOR_WHITE;
+ if (!WCSICMP(color, L"black")) return COLOR_BLACK;
+ if (wcschr(color, ','))
+ {
+ int r = 0, g = 0, b = 0;
+ if (swscanf(color, L"%d,%d,%d", &r, &g, &b) != 3) return COLOR_ERROR;
+ return RGB(r, g, b); // our colors are reversed internally
+ }
+ if (*color == '#')
+ {
+ int r = 0, g = 0, b = 0;
+ if (swscanf(color, L"#%02x%02x%02x", &r, &g, &b) != 3) return COLOR_ERROR;
+ return RGB(r, g, b);
+ }
+ if (error) *error = 1;
+ return COLOR_ERROR;
+}
+
+ARGB32 SkinParser::parseColorAlpha(const wchar_t *color)
+{
+ if (color == NULL || *color == '\0') return COLOR_BLACKA;
+ if (!WCSICMP(color, L"white")) return COLOR_WHITEA;
+ if (!WCSICMP(color, L"black")) return COLOR_BLACKA;
+ if (wcschr(color, ','))
+ {
+ int r = 0, g = 0, b = 0, a = 255;
+ // note that 3 params is ok
+ if (swscanf(color, L"%d,%d,%d,%d", &r, &g, &b, &a) < 3) return COLOR_ERRORA;
+ ARGB32 ret = RGB(r, g, b); // our colors are reversed internally
+ ret |= ((a & 0xff) << 24);
+ return ret;
+ }
+ if (*color == '#')
+ {
+ int r = 0, g = 0, b = 0, a = 255;
+ if (swscanf(color, L"#%02x%02x%02x%02x", &r, &g, &b, &a) < 3) return COLOR_ERRORA;
+ ARGB32 ret = RGB(r, g, b); // our colors are reversed internally
+ ret |= ((a & 0xff) << 24);
+ return ret;
+ }
+ return COLOR_ERRORA;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+
+void SkinParser::toggleContainer(const wchar_t *id)
+{
+ // component toggling
+ GUID *g;
+ if (g = getComponentGuid(id))
+ {
+ GUID g2;
+ MEMCPY(&g2, g, sizeof(GUID));
+ WASABI_API_WNDMGR->skinwnd_toggleByGuid(g2);
+ return ;
+ }
+ for (int i = 0;i < containers.getNumItems();i++)
+ if (!WCSICMP(id, containers[i]->getId())) toggleContainer(i);
+}
+
+void SkinParser::showContainer(const wchar_t *id, int show)
+{
+ // component guid
+ /* GUID *g;
+ if (g = getComponentGuid(id)) {
+ WASABI_API_WNDMGR->setComponentVisible(*g, show);
+ return;
+ }*/
+
+ foreach(containers)
+ if (!WCSICMP(id, containers.getfor()->getId()))
+ showContainer(foreach_index, show);
+ endfor
+}
+
+#endif // wndmgr
+
+#pragma warning( disable : 4065 )
+int SkinParser::getAction(const wchar_t *action, const wchar_t **name)
+{
+ //CT> this should be a binary search for more efficiency
+ if (name != NULL) *name = NULL;
+ int a = actionlist.getId(action);
+ if (a == -1) return ACTION_NONE;
+
+ // these strings are for accessibility when no text has been assigned to the control that triggers these actions
+ if (name != NULL)
+ {
+ switch (a)
+ {
+#ifdef WASABI_COMPILE_WNDMGR
+ case ACTION_RELOAD_SKIN: *name = _(L"Reload skin"); break;
+ case ACTION_MINIMIZE: *name = _(L"Minimize window"); break;
+ case ACTION_MAXIMIZE: *name = _(L"Maximize window"); break;
+ case ACTION_CLOSE: *name = _(L"Close"); break;
+ case ACTION_SWITCH: *name = _(L"Switch to"); break;
+ case ACTION_TOGGLE: *name = _(L"Toggle"); break;
+ case ACTION_CLOSE_WINDOW: *name = _(L"Close window"); break;
+#endif
+
+#ifdef WA3COMPATIBILITY
+ case ACTION_ABOUT: *name = _(L"About"); break;
+ case ACTION_SYSMENU: *name = _(L"Open system menu"); break;
+ case ACTION_CONTROLMENU: *name = _(L"Open control menu"); break;
+ case ACTION_MENU: *name = _(L"Open menu"); break;
+ case ACTION_WINDOWMENU: *name = _(L"Window menu"); break;
+ case ACTION_MB_FORWARD: *name = _(L"Forward"); break;
+ case ACTION_MB_BACK: *name = _(L"Back"); break;
+ case ACTION_MB_URL: *name = _(L"Url"); break;
+ case ACTION_MB_HOME: *name = _(L"Home"); break;
+ case ACTION_MB_STOP: *name = _(L"Stop loading"); break;
+ case ACTION_MB_REFRESH: *name = _(L"Refresh"); break;
+ case ACTION_TEXT_LARGER: *name = _(L"Increase text size"); break;
+ case ACTION_TEXT_SMALLER: *name = _(L"Decrease text size"); break;
+ case ACTION_PREFERENCES: *name = _(L"Preferences"); break;
+ case ACTION_TOGGLE_ALWAYS_ON_TOP: *name = _(L"Toggle Always on top"); break;
+ case ACTION_VIEW_FILE_INFO: *name = _(L"View file info"); break;
+ case ACTION_ADD_BOOKMARK: *name = _(L"Add bookmark"); break;
+ case ACTION_DOUBLESIZE: *name = _(L"Toggle double size mode"); break;
+#endif
+#ifdef WASABI_WIDGETS_COMPBUCK
+ case ACTION_CB_NEXT: *name = _(L"More"); break;
+ case ACTION_CB_PREV: *name = _(L"More"); break;
+#endif
+ default: break;
+ }
+ }
+ return a;
+}
+#pragma warning( default : 4065 )
+
+#ifdef WASABI_COMPILE_MEDIACORE
+int SkinParser::getDisplay(const wchar_t *display)
+{
+ int a = displaylist.getId(display);
+ if (a == -1) return DISPLAY_SERVICE;
+ return a;
+}
+#endif
+
+int SkinParser::getAlign(const wchar_t *align)
+{
+#ifdef _WIN32
+ if (!WCSICMP(align, L"LEFT")) return ALIGN_LEFT;
+ if (!WCSICMP(align, L"CENTER")) return ALIGN_CENTER;
+ if (!WCSICMP(align, L"RIGHT")) return ALIGN_RIGHT;
+ if (!WCSICMP(align, L"TOP")) return ALIGN_TOP;
+ if (!WCSICMP(align, L"BOTTOM")) return ALIGN_BOTTOM;
+#else
+#warning port me
+#endif
+ return DISPLAY_NONE;
+}
+
+int SkinParser::getOrientation(const wchar_t *orient)
+{
+ if (!WCSICMP(orient, L"V") || !WCSICMP(orient, L"VERTICAL"))
+ return ORIENTATION_VERTICAL;
+ return ORIENTATION_HORIZONTAL;
+}
+
+// link guiobject to guiobject
+void SkinParser::initGuiObject(GuiObject *g, Group *pgroup)
+{
+ ASSERT(pgroup);
+ pgroup->addObject(g);
+}
+
+// This sends the params to the script object through its XmlObject
+// interface. Try not to add code here, but instead in setXmlParam/XmlInit
+// in the object itself
+void SkinParser::initXmlObject(XmlObject *o, ifc_xmlreaderparams *params, int no_id)
+{
+ ASSERT(o);
+ if (params)
+ for (size_t i = 0;i != params->getNbItems();i++)
+ if (!no_id || WCSICMP(params->getItemName(i), L"id")) // don't pass along id="blah" stuff
+ o->setXmlParam(params->getItemName(i), params->getItemValue(i));
+ // o->XmlInit(); //fg> now defered
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+
+// This sends the params to the script object through its XmlObject
+// interface. Try not to add code here, but instead in setXmlParam/XmlInit
+// in the object itself
+void SkinParser::initLayout(Layout *l, Container *pcont)
+{
+ ASSERT(pcont);
+ l->setParentContainer(pcont);
+ pcont->addLayout(l);
+}
+
+#endif
+
+void SkinParser::xmlReaderCallback(int start, const wchar_t *xmltag, skin_xmlreaderparams *params)
+{
+ if (start) onXmlStartElement(xmltag, params);
+ else onXmlEndElement(xmltag);
+}
+
+void SkinParser::onXmlStartElement(const wchar_t *name, skin_xmlreaderparams *params)
+{
+ xml_tag *i = quickxmltaglist.findItem(name);
+ if (i) _onXmlStartElement(i->id, name, params);
+ else _onXmlStartElement(XML_TAG_UNKNOWN, name, params);
+}
+
+void SkinParser::onXmlEndElement(const wchar_t *name)
+{
+ xml_tag *i = quickxmltaglist.findItem(name);
+ if (i)
+ {
+ if (i->needclosetag)
+ _onXmlEndElement(i->id, name);
+ } /*else
+ _onXmlEndElement(XML_TAG_UNKNOWN, name);*/ // not needed yet
+}
+
+
+
+void SkinParser::parseGroup(SkinItem *groupitem, PtrList<ifc_xmlreaderparams> *ancestor_param_list, int params_only, int overriding_inheritance_flags)
+{
+ ifc_xmlreaderparams *par = groupitem->getParams();
+ const wchar_t *groupid = par->getItemValue(L"id");
+ const wchar_t *ic = par->getItemValue(L"inherit_content");
+ const wchar_t *og = par->getItemValue(L"inherit_group");
+ const wchar_t *ip = par->getItemValue(L"inherit_params");
+
+ int inheritance_flags = parseGroupInheritance(ic);
+ int inherit_params = 1;
+ if (ip != NULL && *ip != 0) inherit_params = WTOI(ip);
+ if ((og && *og) && (!ic || !*ic)) inheritance_flags = GROUP_INHERIT_ALLCONTENT;
+
+ if (inherit_params) inheritance_flags |= GROUP_INHERIT_PARAMS;
+
+ if (WCSCASEEQLSAFE(og, groupid)) og = NULL;
+
+
+ if (inheritance_flags != GROUP_INHERIT_NOTHING)
+ {
+ SkinItem *prior_item = NULL;
+ if (og != NULL && *og)
+ prior_item = guiTree->getGroupDef(og);
+ else
+ prior_item = guiTree->getGroupDefAncestor(groupitem);
+ if (prior_item != NULL)
+ parseGroup(prior_item, ancestor_param_list, params_only, inheritance_flags);
+ }
+
+ if (overriding_inheritance_flags & GROUP_INHERIT_PARAMS)
+ ancestor_param_list->addItem(groupitem->getParams());
+
+ if (!params_only)
+ {
+ int guitreeid = guiTree->getObjectIdx(groupitem);
+ for (int i = guitreeid + 1;i < guiTree->getNumObject();i++)
+ {
+ SkinItem *item = guiTree->getList()->enumItem(i);
+ ifc_xmlreaderparams *params = item->getParams();;
+ const wchar_t *path = item->getXmlRootPath();
+ if (path)
+ includepath = path;
+ int object_type = guiTree->getObjectType(item);
+ if (object_type == XML_TAG_GROUPDEF && !params) break;
+ if (object_type == XML_TAG_SCRIPT && !(overriding_inheritance_flags & GROUP_INHERIT_SCRIPTS)) continue;
+ if (object_type != XML_TAG_SCRIPT && !(overriding_inheritance_flags & GROUP_INHERIT_XUIOBJECTS)) continue;
+ const wchar_t *name = item->getName();
+ if (!params)
+ _onXmlEndElement(object_type, name);
+ else
+ _onXmlStartElement(object_type, name, params);
+ }
+ }
+
+}
+
+void SkinParser::_onXmlStartElement(int object_type, const wchar_t *object_name, ifc_xmlreaderparams *params)
+{
+ GuiObject *g = NULL; // We'll need to build a GUI object
+ XmlObject *x = NULL;
+ Group *g_group = NULL;
+
+ if (object_type == XML_TAG_UNKNOWN)
+ {
+ if (loading_main_skinfile && (!WCSICMP(object_name, L"WinampAbstractionLayer") || !WCSICMP(object_name, L"WasabiXML")))
+ {
+ skinversion = WTOF(params->getItemValue(L"version"));
+ }
+ }
+
+/*#ifdef WASABI_COMPILE_WNDMGR
+ int isacontainer = 0;
+#endif // wndmgr*/
+
+ if (object_type == XML_TAG_GROUPDEF)
+ {
+ if (staticloading)
+ {
+ recording_groupdef++;
+ }
+ inGroupDef++;
+ }
+
+ if (object_type == XML_TAG_ACCELERATORS)
+ {
+ const wchar_t *section = params->getItemValue(L"section");
+ if (!section)
+ LocalesManager::setAcceleratorSection(L"general");
+ else
+ LocalesManager::setAcceleratorSection(section);
+
+ inAccelerators = 1;
+ }
+
+ if (object_type == XML_TAG_STRINGTABLE)
+ {
+ const wchar_t *section = params->getItemValue(L"id");
+ if (!section)
+ LocalesManager::SetStringTable(L"nullsoft.wasabi");
+ else
+ LocalesManager::SetStringTable(section);
+
+ inStringTable = 1;
+ }
+
+ if (inStringTable && object_type == XML_TAG_STRINGENTRY)
+ {
+ const wchar_t *b = params->getItemValue(L"id");
+ const wchar_t *a = params->getItemValue(L"string");
+ if (b && a)
+ {
+ LocalesManager::AddString(WTOI(b), a);
+ }
+ }
+
+ if (inAccelerators && object_type == XML_TAG_ACCELERATOR)
+ {
+ const wchar_t *b = params->getItemValue(L"bind");
+ const wchar_t *a = params->getItemValue(L"action");
+ if (b && a)
+ {
+ //LocalesManager::addAccelerator(b, a);
+ //Martin> this is a temporary fix to protect skin.xml from overriding the language pack accels
+ LocalesManager::addAcceleratorFromSkin(b, a);
+ }
+ }
+
+ if ((!recording_container && !recording_groupdef) && !inGroupDef)
+ {
+ if (object_type == XML_TAG_SCRIPT)
+ {
+ // const char *id = params->getItemValue(L"id");
+ if (1)
+ {
+ if (allowscripts)
+ {
+ int vcpuid = Script::addScript(includepath, params->getItemValue(L"file"), params->getItemValue(L"id"));
+ if (vcpuid != -1)
+ {
+ Script::setScriptParam(vcpuid, params->getItemValue(L"param"));
+ Script::setParentGroup(vcpuid, curGroup);
+ Script::setSkinPartId(vcpuid, scriptId);
+ if (curGroup != NULL)
+ curGroup->addScript(vcpuid);
+ else // todo: schedule this for the end of skinparse, after all layouts are inited
+ SOM::getSystemObjectByScriptId(vcpuid)->onLoad();
+ }
+ }
+ }
+ }
+ }
+
+#ifdef WASABI_COMPILE_WNDMGR
+ if ((!recording_groupdef && !recording_container) && (inContainer || inGroup) && !inGroupDef)
+ { // Am I in a container definition ?
+ if (inLayout || inGroup)
+ { // Am I in a layout or in a group ?
+#else // wndmgr
+ if ((!recording_groupdef && !recording_container) && inGroup && !inGroupDef)
+ {
+ { // Am I in definition ?
+#endif // wndmgr
+
+
+ // Create appropriate GuiObject descendant
+ if (object_type == XML_TAG_GROUP || object_type == XML_TAG_CFGGROUP)
+ {
+ Group *old = curGroup;
+ GuiObject *newgrp = newDynamicGroup(params->getItemValue(L"id"), (object_type == XML_TAG_CFGGROUP) ? GROUP_CFGGROUP : GROUP_GROUP);
+ if (newgrp)
+ {
+ x = static_cast<XmlObject *>(newgrp->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ g = newgrp;
+ }
+ curGroup = old;
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+ else if (object_type == XML_TAG_SNAPPOINT)
+ {
+ x = new SnapPoint(curLayout, curContainer);
+ }
+#endif
+ else if (object_type != XML_TAG_UNKNOWN)
+ {
+ g = NULL;
+ }
+ else
+ {
+ SkinItem *item = guiTree->getXuiGroupDef(object_name);
+ if (item != NULL)
+ {
+ Group *old = curGroup;
+ const wchar_t *grpid = NULL;
+ if (item->getParams() != NULL)
+ grpid = item->getParams()->getItemValue(L"id");
+ GuiObject *newgrp = NULL;
+ if (grpid == NULL)
+ newgrp = newDynamicGroup(params->getItemValue(L"id"), GROUP_GROUP, item);
+ else
+ newgrp = newDynamicGroup(grpid, GROUP_GROUP, NULL, -1, allowscripts);
+ if (newgrp)
+ {
+ x = static_cast<XmlObject *>(newgrp->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ g = newgrp;
+ }
+ curGroup = old;
+ }
+ else
+ {
+ g = createExternalGuiObject(object_name, &x, params);
+ }
+ }
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+ else
+ { // if inlayout
+
+ if (object_type == XML_TAG_LAYOUT)
+ { // Now enters a new layout
+ curLayout = new Layout;
+ curGroup = curLayout;
+ inLayout = 1;
+ initLayout(curLayout, curContainer);
+ x = static_cast<XmlObject *>(curLayout->getGuiObject()->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ }
+ }
+#endif // wndmgr
+
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+ else
+ { // if inContainer
+
+ if (inElements)
+ {
+ // do nothing
+ }
+ else if (object_type == XML_TAG_CONTAINER)
+ {
+ //isacontainer = 1;
+ const wchar_t *d = params->getItemValue(L"dynamic");
+ int dyn = WASABI_WNDMGR_ALLCONTAINERSDYNAMIC ? 1 : (d ? WTOI(d) : 0);
+
+ if (dyn && staticloading)
+ {
+ recording_container = 1;
+ }
+ else
+ {
+ inContainer = 1;
+ curContainer = new Container(scriptId);
+ curContainer->setId(params->getItemValue(L"id"));
+ containers.addItem(curContainer);
+#ifdef _DEBUG
+ DebugStringW(L"new Container - skinpartid = %d\n", scriptId);
+#endif
+ if (transcientcontainer) curContainer->setTranscient(1);
+ x = curContainer;
+ }
+ }
+ else
+ {
+ if (object_type == XML_TAG_SCRIPTS)
+ inScripts = 1;
+ else if (object_type == XML_TAG_ELEMENTS)
+ inElements = 1;
+ }
+
+ } // if container else
+#endif // wndmgr
+
+ if (g_group)
+ {
+ curGroup = g_group;
+ }
+ else if (g)
+ initGuiObject(g, curGroup);
+
+ if (x)
+ initXmlObject(x, params);
+
+ if (recording_container || recording_groupdef)
+ guiTree->addItem(object_type, object_name, params, scriptId, includepath.v());
+}
+
+void SkinParser::_onXmlEndElement(int object_type, const wchar_t *name)
+{
+ if (recording_container || recording_groupdef)
+ guiTree->addItem(object_type, name, NULL, scriptId, includepath);
+
+ if (object_type == XML_TAG_GROUPDEF)
+ {
+ lastCreatedGroup = curGroup;
+ if (staticloading)
+ recording_groupdef--;
+ if (recording_groupdef < 0) recording_groupdef = 0;
+ inGroup = 0;
+ inGroupDef--;
+ curGroup = NULL;
+ }
+
+#ifdef WASABI_COMPILE_WNDMGR
+ if (object_type == XML_TAG_CONTAINER)
+ {
+ if (inContainer)
+ {
+ //if (!curContainer->isDynamic()) containers.addItem(curContainer); //FG>script
+ //containers.addItem(curContainer);
+ lastCreatedContainer = curContainer;
+ curContainer = NULL;
+ inContainer = 0;
+ }
+ recording_container = 0;
+ if (recording_groupdef)
+ {
+ WASABI_API_WNDMGR->messageBox(L"container closed but group still open, closing group", L"error in xml data", 0, NULL, NULL);
+ recording_groupdef = 0;
+ }
+ }
+
+ if (inLayout && object_type == XML_TAG_LAYOUT)
+ {
+#ifdef WA3COMPATIBILITY
+ curLayout->setForwardMsgWnd(WASABI_API_WND->main_getRootWnd()->gethWnd());
+#endif
+ curLayout->setAutoResizeAfterInit(1);
+#ifndef WA3COMPATIBILITY
+#ifdef _WIN32
+ curLayout->init(hInstance, curLayout->getCustomOwner() ? curLayout->getCustomOwner()->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE);
+#else
+#warning port me
+ curLayout->init(0, curLayout->getCustomOwner() ? curLayout->getCustomOwner()->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE);
+#endif
+#else
+ curLayout->init(hInstance, curLayout->getCustomOwner() ? curLayout->getCustomOwner()->gethWnd() : Main::gethWnd(), TRUE);
+#endif
+ curLayout->getGuiObject()->guiobject_onStartup();
+ curLayout = NULL;
+ inLayout = 0;
+ curGroup = NULL;
+ }
+#endif
+
+ if (inScripts && object_type == XML_TAG_SCRIPTS)
+ {
+ inScripts = 0;
+ }
+
+ if (inElements && object_type == XML_TAG_ELEMENTS)
+ {
+ inElements = 0;
+ }
+
+ if (inAccelerators && object_type == XML_TAG_ACCELERATORS)
+ {
+ LocalesManager::setAcceleratorSection(L"");
+ inAccelerators = 0;
+ }
+
+ if (inStringTable && object_type == XML_TAG_STRINGTABLE)
+ {
+ LocalesManager::SetStringTable(L"");
+ inStringTable = 0;
+ }
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+int SkinParser::verifyContainer(Container *c)
+{
+ for (int i = 0;i < containers.getNumItems();i++)
+ {
+ if (containers.enumItem(i) == c)
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+int SkinParser::parseResize(const wchar_t *r)
+{
+ int a = resizevalues.getId(r);
+ if (a < 0) return WTOI(r);
+ return a;
+}
+
+int SkinParser::parseRegionOp(const wchar_t *r)
+{
+ if (!WCSICMP(r, L"or")) return REGIONOP_OR;
+ if (!WCSICMP(r, L"and")) return REGIONOP_AND;
+ if (!WCSICMP(r, L"sub")) return REGIONOP_SUB;
+ if (!WCSICMP(r, L"sub2")) return REGIONOP_SUB2;
+ return WTOI(r);
+}
+
+void SkinParser::cleanupScript(int scriptid)
+{
+ if (scriptid == -1) scriptid = WASABI_API_PALETTE->getSkinPartIterator();
+ int i;
+ for (i = 0;i < SOM::getNumSystemObjects();i++)
+ {
+ if (SOM::getSystemObject(i)->getSkinPartId() == scriptid)
+ {
+ int vcpu = SOM::getSystemObject(i)->getScriptId();
+ Script::unloadScript(vcpu);
+ i--;
+ }
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+ for (i = 0;i < containers.getNumItems();i++)
+ {
+ Container *c = containers[i];
+ if (c->getScriptId() == scriptid)
+ {
+ c->setDeleting();
+ delete c; // c autodeletes from containers
+ i--;
+ }
+ }
+#endif
+ guiTree->removeSkinPart(scriptid);
+#ifdef WASABI_COMPILE_WNDMGR
+ AutoPopup::removeSkinPart(scriptid);
+#endif
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void SkinParser::unloadAllContainers()
+{
+ foreach(containers)
+ containers.getfor()->setDeleting();
+ endfor;
+ containers.deleteAllSafe();
+ //script_containers.removeAll();
+}
+#endif
+
+void SkinParser::cleanUp()
+{
+#ifdef WASABI_COMPILE_WNDMGR
+ AutoPopup::removeAllAddons();
+#endif
+ Script::unloadAllScripts();
+#ifdef WASABI_COMPILE_WNDMGR
+ unloadAllContainers();
+#endif
+ guiTree->reset();
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+int SkinParser::getNumContainers()
+{
+ return containers.getNumItems();
+}
+
+Container *SkinParser::enumContainer(int n)
+{
+ return containers.enumItem(n);
+}
+#endif
+
+const wchar_t *SkinParser::getXmlRootPath()
+{
+ return includepath;
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+const wchar_t *SkinParser::getCurrentContainerId()
+{
+ if (curContainer) return curContainer->getId();
+ return NULL;
+}
+
+const wchar_t *SkinParser::getCurrentGroupId()
+{
+ if (curGroup) return curGroup->getGuiObject()->guiobject_getId();
+ return NULL;
+}
+#endif
+
+GuiObject *SkinParser::createExternalGuiObject(const wchar_t *object_name, XmlObject **x, ifc_xmlreaderparams *params)
+{
+ svc_xuiObject *svc = NULL;
+ waServiceFactory *sf = xuiCache->findServiceFactory(object_name);
+ if (sf != NULL)
+ svc = castService<svc_xuiObject>(sf, FALSE);
+ else
+ {
+ XuiObjectSvcEnum xose(object_name);
+ svc = xose.getNext(FALSE);
+ sf = xose.getLastFactory();
+ }
+ if (svc != NULL)
+ {
+ GuiObject *go = svc->instantiate(object_name, params);
+ if (!go) return NULL;
+ go->guiobject_setXuiService(svc);
+ go->guiobject_setXuiServiceFactory(sf);
+ ScriptObject *so = go->guiobject_getScriptObject();
+ ASSERTPR(so != NULL, "tell francis to fix scriptobjectless xuiobjects");
+ if (x) *x = static_cast<XmlObject *>(so->vcpu_getInterface(xmlObjectGuid));
+ return go;
+ }
+ return NULL;
+}
+
+void SkinParser::destroyGuiObject(GuiObject *o)
+{
+ svc_xuiObject *svc = o->guiobject_getXuiService();
+ if (!svc)
+ {
+ ScriptObject *so = o->guiobject_getScriptObject();
+ ASSERT(so != NULL);
+ GuiObjectWnd *go = static_cast<GuiObjectWnd *>(so->vcpu_getInterface(guiObjectWndGuid));
+ ASSERT(go != NULL);
+ delete go;
+ }
+ else
+ {
+ waServiceFactory *sf = o->guiobject_getXuiServiceFactory();
+ svc->destroy(o);
+ sf->releaseInterface(svc);
+ }
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void SkinParser::focusFirst()
+{
+ foreach(containers)
+ for (int j = 0;j < containers.getfor()->getNumLayouts();j++)
+ {
+ Layout *l = containers.getfor()->enumLayout(j);
+ if (l != NULL && l->isVisible())
+ {
+ l->setFocus();
+ return ;
+ }
+ }
+ endfor;
+}
+
+#ifdef WA3COMPATIBILITY
+// non portable, the skin might be missing/buggy as hell, we need to use the os' msgbox
+void SkinParser::emmergencyReloadDefaultSkin()
+{
+ if (!Main::revert_on_error)
+ {
+ if (!STRCASEEQLSAFE("Default", WASABI_API_SKIN->getSkinName()))
+ {
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ Std::messageBox(StringPrintfW(L"Failed to load the skin (%s). Did you remove it ?\nThis could also be due to missing components (ie: wa2skin.wac for winamp 2 skins), please check the skin's documentation.\nReverting to default skin.", WASABI_API_SKIN->getSkinName()), "Error", 0);
+ WASABI_API_WND->appdeactivation_setbypass(0);
+ Skin::toggleSkin("Default");
+ }
+ else
+ {
+ WASABI_API_WND->appdeactivation_setbypass(1);
+ Std::messageBox("The default skin did not load any user interface! Ooch! What should I do ? Oh well, good luck...", "Danger Danger Will Robinson!", 0);
+ WASABI_API_WND->appdeactivation_setbypass(0);
+ }
+ }
+}
+#endif
+#endif
+
+GuiObject *SkinParser::xui_new(const wchar_t *classname)
+{
+ SkinItem *item = guiTree->getXuiGroupDef(classname);
+ if (item != NULL)
+ {
+ Group *old = curGroup;
+ const wchar_t *grpid = NULL;
+ if (item->getParams() != NULL)
+ grpid = item->getParams()->getItemValue(L"id");
+ GuiObject *newgrp = NULL;
+ if (grpid != NULL)
+ newgrp = newDynamicGroup(grpid, GROUP_GROUP);
+ curGroup = old;
+ if (newgrp != NULL) return newgrp;
+ }
+ return createExternalGuiObject(classname, NULL, NULL);
+}
+
+void SkinParser::xui_delete(GuiObject *o)
+{
+ destroyGuiObject(o);
+}
+
+double SkinParser::getSkinVersion()
+{
+ return skinversion;
+}
+
+void SkinParser::setAllLayoutsRatio(double ra)
+{
+ foreach(containers)
+ Container *c = containers.getfor();
+ int n = c->getNumLayouts();
+ for (int i = 0;i < n;i++)
+ {
+ Layout *l = c->enumLayout(i);
+ if (l->getNoParent() != 1)
+ l->setRenderRatio(ra);
+ }
+ endfor;
+}
+
+void SkinParser::setAllLayoutsTransparency(int v)
+{
+ foreach(containers)
+ Container *c = containers.getfor();
+ int n = c->getNumLayouts();
+ for (int i = 0;i < n;i++)
+ {
+ Layout *l = c->enumLayout(i);
+ if (l->getNoParent() != 1)
+ l->setAlpha(v);
+ }
+ endfor;
+}
+
+Layout *SkinParser::getMainLayout()
+{
+ foreach(containers)
+ Container *c = containers.getfor();
+ if (!c->isMainContainer()) continue;
+ return c->enumLayout(0);
+ endfor;
+ return NULL;
+}
+
+/*
+void SkinParser::setAllLayoutsAutoOpacify(int ao, int force) {
+ foreach(containers)
+ Container *c = containers.getfor();
+ int n = c->getNumLayouts();
+ for (int i=0;i<n;i++) {
+ Layout *l = c->enumLayout(i);
+ if (l->getNoParent() != 1)
+ l->setAutoOpacify(ao, force);
+ }
+ endfor;
+}
+
+void SkinParser::setAllLayoutsOverrideAlpha(int oa) {
+ foreach(containers)
+ Container *c = containers.getfor();
+ int n = c->getNumLayouts();
+ for (int i=0;i<n;i++) {
+ Layout *l = c->enumLayout(i);
+ if (l->isInited() && l->isTransparencySafe() && l->getTransparencyOverride() == -1) {
+ if (l->getNoParent() != 1)
+ l->setTransparency(oa);
+ }
+ }
+ endfor;
+}
+*/
+
+Group *SkinParser::curGroup, *SkinParser::lastCreatedGroup;
+int SkinParser::inScripts = 0, SkinParser::inElements = 0, SkinParser::inGroupDef = 0, SkinParser::inGroup = 0, SkinParser::inAccelerators = 0, SkinParser::inStringTable = 0;
+int SkinParser::scriptId = 0;
+int SkinParser::recording_container = 0;
+int SkinParser::recording_groupdef = 0;
+int SkinParser::staticloading = 0;
+PtrList<parser_status> SkinParser::statusstack;
+int SkinParser::instantiatinggroup = 0;
+int SkinParser::allowscripts = 0;
+skin_xmlreaderparams *SkinParser::groupparams = NULL;
+PtrListQuickSorted<xml_tag, XmlTagComp> SkinParser::quickxmltaglist;
+double SkinParser::skinversion = 0.0;
+
+#ifdef WASABI_COMPILE_WNDMGR
+Container *SkinParser::curContainer, *SkinParser::lastCreatedContainer;
+Layout *SkinParser::curLayout;
+int SkinParser::inContainer, SkinParser::inLayout;
+//PtrList<Container> SkinParser::script_containers;
+PtrList<Container> SkinParser::containers;
+int SkinParser::centerskin;
+int SkinParser::transcientcontainer;
+SvcCacheT<svc_xuiObject> *SkinParser::xuiCache;
+int SkinParser::loading_main_skinfile = 0;
+StringW SkinParser::includepath;
+#endif
diff --git a/Src/Wasabi/api/skin/skinparse.h b/Src/Wasabi/api/skin/skinparse.h
new file mode 100644
index 00000000..b232e92d
--- /dev/null
+++ b/Src/Wasabi/api/skin/skinparse.h
@@ -0,0 +1,337 @@
+#ifndef __SKINPARSER_H
+#define __SKINPARSER_H
+
+#include <bfc/wasabi_std.h>
+#include <api/wnd/basewnd.h>
+#include <api/service/svccache.h>
+
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/layout.h>
+#include <api/wndmgr/container.h>
+#else
+class Container;
+class Layout;
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+#include <api/font/skinfont.h>
+#endif
+
+#ifdef WASABI_COMPILE_XMLPARSER
+#include <api/xml/xmlreader.h>
+#else
+class skin_xmlreaderparams;
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+#include <api/skin/group.h>
+#else
+class Group;
+class SkinItem;
+#endif
+
+class XmlObject;
+
+enum {
+ PARSETYPE_RESIZE=0,
+ PARSETYPE_COLOR,
+ PARSETYPE_COLORALPHA,
+ PARSETYPE_REGIONOP,
+ PARSETYPE_INTERNALACTION,
+ PARSETYPE_GROUPINHERITANCE,
+} ;
+
+enum {
+ XML_TAG_CONTAINER,
+ XML_TAG_GROUP,
+ XML_TAG_CFGGROUP,
+ XML_TAG_GROUPDEF,
+ XML_TAG_LAYOUT,
+ XML_TAG_ACCELERATORS,
+ XML_TAG_ACCELERATOR,
+ XML_TAG_ELEMENTS,
+ XML_TAG_STRINGTABLE,
+ XML_TAG_STRINGENTRY,
+ XML_TAG_SCRIPTS,
+ XML_TAG_SNAPPOINT,
+ XML_TAG_TRUETYPEFONT,
+ XML_TAG_BITMAPFONT,
+ XML_TAG_SCRIPT,
+ XML_TAG_UNKNOWN,
+};
+
+#define GROUP_INHERIT_NOTHING 0
+#define GROUP_INHERIT_XUIOBJECTS 1
+#define GROUP_INHERIT_SCRIPTS 2
+#define GROUP_INHERIT_PARAMS 4
+#define GROUP_INHERIT_ALL GROUP_INHERIT_XUIOBJECTS | GROUP_INHERIT_SCRIPTS | GROUP_INHERIT_PARAMS
+#define GROUP_INHERIT_ALLCONTENT GROUP_INHERIT_XUIOBJECTS | GROUP_INHERIT_SCRIPTS
+
+#define GROUP_GROUP 0
+#define GROUP_CFGGROUP 1
+
+#ifdef WASABI_COMPILE_WNDMGR
+#define GROUP_LAYOUTGROUP 2
+#endif
+
+enum {
+ ACTION_NONE,
+ ACTION_UNIMPLEMENTED=0x1000,
+ ACTION_MINIMIZE,
+ ACTION_MAXIMIZE,
+ ACTION_CLOSE,
+ ACTION_ABOUT,
+ ACTION_SWITCH,
+ ACTION_TOGGLE,
+ ACTION_SYSMENU,
+ ACTION_CONTROLMENU,
+ ACTION_REPORT_BUGS,
+ ACTION_MB_BACK, //FG
+ ACTION_MB_FORWARD, //FG
+ ACTION_MB_URL, //FG
+ ACTION_MB_STOP, //FG
+ ACTION_MB_REFRESH, //FG
+ ACTION_MB_HOME, //FG
+ ACTION_CB_NEXT, //FG
+ ACTION_CB_PREV, //FG
+ ACTION_CB_NEXTPAGE,
+ ACTION_CB_PREVPAGE,
+ ACTION_SCALE_50, //FG
+ ACTION_SCALE_75, //FG
+ ACTION_SCALE_100, //FG
+ ACTION_SCALE_125, //FG
+ ACTION_SCALE_150, //FG
+ ACTION_SCALE_200, //FG
+ ACTION_SCALE_400, //BU :)
+ ACTION_RELOAD_SKIN,
+ ACTION_TEXT_LARGER,
+ ACTION_TEXT_SMALLER,
+ ACTION_PREFERENCES,
+ ACTION_REGISTRY,
+ ACTION_ALPHA_10, //FG
+ ACTION_ALPHA_20, //FG
+ ACTION_ALPHA_30, //FG
+ ACTION_ALPHA_40, //FG
+ ACTION_ALPHA_50, //FG
+ ACTION_ALPHA_60, //FG
+ ACTION_ALPHA_70, //FG
+ ACTION_ALPHA_80, //FG
+ ACTION_ALPHA_90, //FG
+ ACTION_ALPHA_100, //FG
+ ACTION_AOT, //BU always-on-top for this window only
+ ACTION_TOGGLE_ALWAYS_ON_TOP,
+ ACTION_MENU,
+ ACTION_VIEW_FILE_INFO,
+ ACTION_ADD_BOOKMARK,
+ ACTION_EDIT_BOOKMARKS,
+ ACTION_ENDMODAL,
+ ACTION_ENFORCEMINMAX,
+ ACTION_DOUBLESIZE,
+ ACTION_CLOSE_WINDOW,
+ ACTION_WINDOWMENU,
+ ACTION_EQ_TOGGLE,
+ ACTION_AUTOOPACIFY,
+};
+
+enum {
+ DISPLAY_NONE,
+ DISPLAY_SONGNAME,
+ DISPLAY_SONGINFO,
+ DISPLAY_SONGTITLE, //BU
+ DISPLAY_SONGARTIST,
+ DISPLAY_SONGALBUM,
+ DISPLAY_SONGLENGTH,
+ DISPLAY_TIME,
+ DISPLAY_CB, //FG
+ DISPLAY_SONGBITRATE,
+ DISPLAY_SONGSAMPLERATE,
+ DISPLAY_SERVICE,
+ DISPLAY_SONGINFO_TRANSLATED,
+};
+
+enum {
+ ORIENTATION_HORIZONTAL,
+ ORIENTATION_VERTICAL
+};
+
+enum {
+ ALIGN_TOP,
+ ALIGN_BOTTOM,
+};
+
+typedef struct
+{
+ const wchar_t *tagname;
+ int id;
+ int needclosetag;
+} xml_tag;
+
+class XmlTagComp
+{
+public:
+ static int compareItem(void *p1, void *p2)
+ {
+ return WCSICMP(((xml_tag *)p1)->tagname, ((xml_tag *)p2)->tagname);
+ }
+ static int compareAttrib(const wchar_t *attrib, void *item)
+ {
+ return WCSICMP(attrib, ((xml_tag *)item)->tagname);
+ }
+};
+
+typedef struct {
+ int staticloading;
+ int recording_container;
+ int recording_groupdef;
+ Group *curGroup;
+ int inElements;
+ int inAccelerators;
+ int inStringTable;
+ int inGroupDef;
+ int inGroup;
+ StringW includepath;
+ skin_xmlreaderparams *groupparams;
+ int instantiatinggroup;
+ int scriptid;
+ int allowscripts;
+#ifdef WASABI_COMPILE_WNDMGR
+ Container *curContainer;
+ Layout *curLayout;
+ int inContainer;
+ int inLayout;
+ int transcientcontainer;
+#endif
+} parser_status;
+
+class SkinParser {
+
+public:
+ static void initialize();
+ static void shutdown();
+
+ static void setInitialFocus();
+
+ static GuiObject *newDynamicGroup(const wchar_t *groupid, int grouptype=GROUP_GROUP, SkinItem *item=NULL, int specific_scriptid=-1, int scripts_enabled=1);
+ static void parseGroup(SkinItem *groupitem, PtrList<ifc_xmlreaderparams> *ancestor_param_list, int params_only=0, int content_flags=GROUP_INHERIT_ALL);
+ static void loadScriptXml(const wchar_t *filename, int scriptid);
+
+ static void xmlReaderCallback(int start, const wchar_t *xmltag, skin_xmlreaderparams *params);
+ static void onXmlStartElement(const wchar_t *name, skin_xmlreaderparams *params);
+ static void onXmlEndElement(const wchar_t *name);
+
+ static void _onXmlStartElement(int object_type, const wchar_t *object_name, ifc_xmlreaderparams *params);
+ static void _onXmlEndElement(int object_type, const wchar_t *object_name);
+
+#ifdef WASABI_COMPILE_WNDMGR
+ static GUID *getComponentGuid(const wchar_t *id);
+ static int getComponentGuid(GUID *g, const wchar_t *p);
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+ static int loadContainers(const wchar_t *skin); // todo: change name
+ static void startupContainers(int scriptid=-1); // todo: change name
+ static Container *loadContainerForWindowHolder(const wchar_t *groupid=NULL, GUID g=INVALID_GUID, int initit=1, int transcient=0, const wchar_t *containerid=NULL/*any*/, int container_flag=0/*dontcare*/);
+ static Container *newDynamicContainer(const wchar_t *containerid, int transcient=0);
+ static Container *getContainer(const wchar_t *name);
+ static Layout *getLayout(const wchar_t *container_layout_pair);
+ static Container *script_getContainer(const wchar_t *name);
+ static Container *instantiateDynamicContainer(SkinItem *containeritem, int initit=1);
+ static void componentToggled(GUID *g, int visible);
+ static void sendNotifyToAllContainers(int notifymsg, int param1=0, int param2=0);
+ static void toggleContainer(const wchar_t *);
+ static void toggleContainer(int);
+ static void showContainer(int num, int show);
+ static void showContainer(const wchar_t *, int show);
+ static PtrList<Container> containers;
+ //static PtrList<Container> script_containers;
+ static int getNumContainers();
+ static Container *enumContainer(int n);
+ static int script_getNumContainers();
+ static Container *script_enumContainer(int id);
+ static int isContainer(Container *c);
+ static int verifyContainer(Container *);
+ static void unloadAllContainers();
+ static const wchar_t *getCurrentContainerId();
+#endif
+
+ static void cleanupScript(int scriptid);
+ static void cleanUp();
+#ifdef WA3COMPATIBILITY
+ static void emmergencyReloadDefaultSkin();
+#endif
+ static void initGuiObject(GuiObject *o, Group *pgroup);
+ static void initXmlObject(XmlObject *x, ifc_xmlreaderparams *params, int no_id=0);
+ static void initLayout(Layout *l, Container *c);
+
+ static int getAction(const wchar_t *action, const wchar_t **name=NULL);
+ static int getDisplay(const wchar_t *display);
+ static int getAlign(const wchar_t *align);
+ static int getOrientation(const wchar_t *orient);
+ static int parse(const wchar_t *str, const wchar_t *how);
+ static int parseResize(const wchar_t *r);
+ static int parseRegionOp(const wchar_t *r);
+ static int parseGroupInheritance(const wchar_t *str);
+ static ARGB32 parseColor(const wchar_t *color, int *error=NULL); // 1 for bitmap colors please
+ static ARGB32 parseColorAlpha(const wchar_t *color); // 1 for bitmap colors please
+ static const wchar_t *getXmlRootPath();
+ static void pushParserState();
+ static void popParserState();
+
+#ifdef WASABI_COMPILE_WNDMGR
+ static void noCenterSkin() { centerskin=0; }
+#endif
+ static const wchar_t *getCurrentGroupId();
+ static void destroyGuiObject(GuiObject *o);
+ static void fillGroup(Group *group, const wchar_t *groupid, SkinItem *specific_item=NULL, int params_only=0, int no_params=0, int scripts_enabled=1);
+
+ static int getSkinRect(RECT *r, ifc_window *exclude=NULL);
+ static void centerSkin();
+ static void focusFirst();
+
+ static GuiObject *xui_new(const wchar_t *classname);
+ static void xui_delete(GuiObject *o);
+
+ static double getSkinVersion();
+
+ static void setAllLayoutsRatio(double ra);
+ static void setAllLayoutsTransparency(int v);
+// static void setAllLayoutsAutoOpacify(int v, int force=0);
+// static void setAllLayoutsOverrideAlpha(int oa);
+ static Layout *getMainLayout();
+
+private:
+ static GuiObject *createExternalGuiObject(const wchar_t *object_name, XmlObject **x, ifc_xmlreaderparams *params);
+
+ static int getHex(const wchar_t *p,int size=-1);
+
+ // xml parser handlers
+ static Group *curGroup, *lastCreatedGroup;
+ static int inScripts;
+ static int inElements, inAccelerators, inStringTable;
+ static int inGroupDef, inGroup;
+ static StringW includepath;
+ static int recording_container;
+ static int recording_groupdef;
+ static int staticloading;
+ static PtrList<parser_status> statusstack;
+ static int instantiatinggroup;
+ static int scriptId;
+ static int allowscripts;
+ static skin_xmlreaderparams *groupparams;
+
+#ifdef WASABI_COMPILE_WNDMGR
+ static Container *curContainer, *lastCreatedContainer;
+ static Layout *curLayout;
+ static int centerskin;
+ static int transcientcontainer;
+ static int inContainer;
+ static int inLayout;
+#endif
+ static double skinversion;
+ static int loading_main_skinfile;
+
+ static PtrListQuickSorted<xml_tag,XmlTagComp> quickxmltaglist;
+ static SvcCacheT<svc_xuiObject> *xuiCache;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets.cpp b/Src/Wasabi/api/skin/widgets.cpp
new file mode 100644
index 00000000..86fe0f05
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets.cpp
@@ -0,0 +1,451 @@
+#include <precomp.h>
+#include <api/skin/widgets.h>
+
+#include <api/skin/widgets/group.h>
+
+#ifdef WASABI_WIDGETS_LAYER
+#include <api/skin/widgets/layer.h>
+#endif
+
+#ifdef WASABI_WIDGETS_ANIMLAYER
+#include <api/skin/widgets/animlayer.h>
+#endif
+
+#ifdef WASABI_WIDGETS_BUTTON
+#include <api/skin/widgets/button.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TGBUTTON
+#include <api/skin/widgets/tgbutton.h>
+#endif
+
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+
+#ifdef WASABI_WIDGETS_GROUPLIST
+#include <api/skin/widgets/grouplist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MOUSEREDIR
+#include <api/skin/widgets/mouseredir.h>
+#endif
+
+#ifdef WASABI_WIDGETS_SLIDER
+#include <api/skin/widgets/pslider.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+#include <api/skin/widgets/seqband.h>
+#include <api/skin/widgets/seqpreamp.h>
+#include <api/skin/widgets/svolbar.h>
+#include <api/skin/widgets/sseeker.h>
+#include <api/skin/widgets/spanbar.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MEDIAVIS
+#include <api/skin/widgets/sa.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MEDIAEQCURVE
+#include <api/skin/widgets/seqvis.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MEDIASTATUS
+#include <api/skin/widgets/sstatus.h>
+#endif
+
+#ifdef _WIN32
+#include <api/skin/widgets/wa2/xuiwa2slider.h>
+#endif
+
+#ifdef WASABI_WIDGETS_SVCWND
+#include <api/skin/widgets/script/svcwnd.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TEXT
+#include <api/skin/widgets/text.h>
+#endif
+
+#ifdef WASABI_WIDGETS_EDIT
+#include <api/skin/widgets/edit.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TITLEBAR
+#include <api/skin/widgets/title.h>
+#endif
+
+#ifdef WASABI_WIDGETS_COMPBUCK
+#include <api/skin/widgets/compbuck2.h>
+#endif
+
+#ifdef WASABI_WIDGETS_BROWSER
+#include <api/skin/widgets/mb/xuibrowser.h>
+#ifdef WASABI_WIDGETS_BROWSERSVC
+#include <api/skin/widgets/mb/iebrowser.h>
+#include <api/skin/widgets/mb/mbsvc.h>
+#endif
+#endif
+
+#ifdef WASABI_WIDGETS_FRAME
+#include <api/skin/widgets/xuiframe.h>
+#endif
+
+#ifdef WASABI_WIDGETS_GRID
+#include <api/skin/widgets/xuigrid.h>
+#endif
+
+#ifdef WASABI_WIDGETS_QUERYDRAG
+#include <api/skin/widgets/xuiquerydrag.h>
+#endif
+
+#ifdef WASABI_WIDGETS_QUERYLIST
+#include <api/skin/widgets/db/xuiquerylist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_FILTERLIST
+#include <api/skin/widgets/db/xuifilterlist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_QUERYLINE
+#include <api/skin/widgets/db/xuiqueryline.h>
+#endif
+
+#ifdef WASABI_WIDGETS_WNDHOLDER
+#include <api/skin/widgets/xuiwndholder.h>
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+
+#ifdef WASABI_WIDGETS_LAYOUTSTATUS
+#include <api/skin/widgets/xuistatus.h>
+#endif
+
+#endif // wndmgr
+
+#ifdef WASABI_WIDGETS_TABSHEET
+#include <api/skin/widgets/xuitabsheet.h>
+#endif
+
+#ifdef WASABI_WIDGETS_CHECKBOX
+#include <api/skin/widgets/xuicheckbox.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TITLEBOX
+#include <api/skin/widgets/xuititlebox.h>
+#endif
+
+#ifdef WASABI_WIDGETS_CUSTOMOBJECT
+#include <api/skin/widgets/xuicustomobject.h>
+#endif
+
+#ifdef WASABI_WIDGETS_OSWNDHOST
+#include <api/skin/widgets/xuioswndhost.h>
+#endif
+
+#ifdef WASABI_WIDGETS_RADIOGROUP
+#include <api/skin/widgets/xuiradiogroup.h>
+#endif
+
+#ifdef WASABI_TOOLOBJECT_HIDEOBJECT
+#include <api/skin/widgets/xuihideobject.h>
+#endif
+
+#ifdef WASABI_TOOLOBJECT_SENDPARAMS
+#include <api/skin/widgets/xuisendparams.h>
+#endif
+
+#ifdef WASABI_TOOLOBJECT_ADDPARAMS
+#include <api/skin/widgets/xuiaddparams.h>
+#endif
+
+#ifdef WASABI_WIDGETS_LIST
+#include <api/skin/widgets/xuilist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_TREE
+#include <api/skin/widgets/xuitree.h>
+#endif
+
+#ifdef WASABI_WIDGETS_DROPDOWNLIST
+#include <api/skin/widgets/xuidropdownlist.h>
+#endif
+
+#ifdef WASABI_WIDGETS_COMBOBOX
+#include <api/skin/widgets/xuicombobox.h>
+#endif
+
+#ifdef WASABI_WIDGETS_HISTORYEDITBOX
+#include <api/skin/widgets/xuihistoryedit.h>
+#endif
+
+#ifdef WASABI_WIDGETS_OBJECTDIRECTORY
+#include <api/skin/widgets/xuiobjdirwnd.h>
+#endif
+
+#ifdef WASABI_WIDGETS_RECTANGLE
+#include <api/skin/widgets/xuirect.h>
+#endif
+
+#ifdef WASABI_WIDGETS_PATHPICKER
+#include <api/skin/widgets/xuipathpicker.h>
+#endif
+
+#ifdef WASABI_WIDGETS_GRADIENT
+#include <api/skin/widgets/xuigradientwnd.h>
+#endif
+
+#ifdef WASABI_WIDGETS_MENU
+#include <api/skin/widgets/xuimenu.h>
+#endif
+
+#include <api/skin/widgets/xuidownloadslist.h>
+
+#ifdef WASABI_COMPILE_STATSWND
+#include <api/skin/widgets/stats/xuistats.h>
+#include <api/skin/widgets/stats/statswnd.h>
+#endif
+
+extern StringW g_resourcepath;
+
+Widgets::Widgets() {
+ count = 0;
+
+ registerService(new XuiObjectCreator<GuiObjectXuiSvc>);
+
+ #ifdef WASABI_WIDGETS_LAYER
+ registerService(new XuiObjectCreator<LayerXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_ANIMLAYER
+ registerService(new XuiObjectCreator<AnimLayerXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_BUTTON
+ registerService(new XuiObjectCreator<ButtonXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_TGBUTTON
+ registerService(new XuiObjectCreator<ToggleButtonXuiSvc>);
+ registerService(new XuiObjectCreator<nStatesTgButtonXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_GROUPLIST
+ registerService(new XuiObjectCreator<GroupListXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_MOUSEREDIR
+ registerService(new XuiObjectCreator<MouseRedirXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_SLIDER
+ registerService(new XuiObjectCreator<SliderXuiSvc>);
+ #endif
+#ifdef _WIN32
+ registerService(new XuiObjectCreator<Wa2SliderXuiSvc>);
+#endif
+ #ifdef WASABI_WIDGETS_MEDIASLIDERS
+ registerService(new XuiObjectCreator<EqBandXuiSvc>);
+ registerService(new XuiObjectCreator<EqPreAmpXuiSvc>);
+ registerService(new XuiObjectCreator<VolBarXuiSvc>);
+ registerService(new XuiObjectCreator<SeekBarXuiSvc>);
+ registerService(new XuiObjectCreator<PanBarXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_MEDIAVIS
+ registerService(new XuiObjectCreator<VisXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_MEDIAEQCURVE
+ registerService(new XuiObjectCreator<EqVisXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_MEDIASTATUS
+ registerService(new XuiObjectCreator<StatusXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_SVCWND
+ registerService(new XuiObjectCreator<SvcWndXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_TEXT
+ registerService(new XuiObjectCreator<TextXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_EDIT
+ registerService(new XuiObjectCreator<EditXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_TITLEBAR
+ registerService(new XuiObjectCreator<TitleBarXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_COMPBUCK
+ registerService(new XuiObjectCreator<ComponentBucketXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_BROWSER
+ registerService(new XuiObjectCreator<BrowserXuiSvc>);
+ #ifdef WASABI_WIDGETS_BROWSERSVC
+ registerService(new waServiceFactoryT<svc_miniBrowser, MbSvc>);
+ #endif
+ #endif
+ #ifdef WASABI_WIDGETS_FRAME
+ registerService(new XuiObjectCreator<FrameXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_GRID
+ registerService(new XuiObjectCreator<GridXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_QUERYDRAG
+ registerService(new XuiObjectCreator<QueryDragXuiSvc>);
+ #endif
+ #ifdef WASABI_COMPILE_METADB
+ #ifdef WASABI_WIDGETS_QUERYLIST
+ registerService(new XuiObjectCreator<QueryListXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_FILTERLIST
+ registerService(new XuiObjectCreator<FilterListXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_QUERYLINE
+ registerService(new XuiObjectCreator<QueryLineXuiSvc>);
+ #endif
+ #endif // metadb
+ #ifdef WASABI_WIDGETS_WNDHOLDER
+ registerService(new XuiObjectCreator<WindowHolderXuiSvc>);
+ registerService(new XuiObjectCreator<WindowHolderXuiSvc2>);
+ #endif // components
+ #ifdef WASABI_COMPILE_WNDMGR
+ #ifdef WASABI_WIDGETS_LAYOUTSTATUS
+ registerService(new XuiObjectCreator<LayoutStatusXuiSvc>);
+ #endif
+ #endif // wndmgr
+ #ifdef WASABI_WIDGETS_TABSHEET
+ registerService(new XuiObjectCreator<ScriptTabSheetXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_CHECKBOX
+ registerService(new XuiObjectCreator<ScriptCheckBoxXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_TITLEBOX
+ registerService(new XuiObjectCreator<ScriptTitleBoxXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_CUSTOMOBJECT
+ registerService(new XuiObjectCreator<CustomObjectXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_OSWNDHOST
+ registerService(new XuiObjectCreator<OSWndHostXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_RADIOGROUP
+ registerService(new XuiObjectCreator<ScriptRadioGroupXuiSvc>);
+ #endif
+ #ifdef WASABI_TOOLOBJECT_HIDEOBJECT
+ registerService(new XuiObjectCreator<HideObjectXuiSvc>);
+ #endif
+ #ifdef WASABI_TOOLOBJECT_SENDPARAMS
+ registerService(new XuiObjectCreator<SendParamsXuiSvc>);
+ #endif
+ #ifdef WASABI_TOOLOBJECT_ADDPARAMS
+ registerService(new XuiObjectCreator<AddParamsXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_LIST
+ registerService(new XuiObjectCreator<ScriptListXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_TREE
+ registerService(new XuiObjectCreator<ScriptTreeXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_DROPDOWNLIST
+ registerService(new XuiObjectCreator<DropDownListXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_COMBOBOX
+ registerService(new XuiObjectCreator<ComboBoxXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_HISTORYEDITBOX
+ registerService(new XuiObjectCreator<HistoryEditXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_OBJECTDIRECTORY
+ registerService(new XuiObjectCreator<ScriptObjDirWndXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_RECTANGLE
+ registerService(new XuiObjectCreator<ScriptRectXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_PATHPICKER
+ registerService(new XuiObjectCreator<PathPickerXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_GRADIENT
+ registerService(new XuiObjectCreator<GradientWndXuiSvc>);
+ #endif
+ #ifdef WASABI_WIDGETS_MENU
+ registerService(new XuiObjectCreator<MenuXuiSvc>);
+ #endif
+
+ //registerService(new XuiObjectCreator<DownloadsListXuiSvc>);
+
+ #ifdef WASABI_COMPILE_WNDMGR
+ //registerSkinFile("xml/msgbox/msgbox.xml");
+ #endif
+
+ #ifdef WASABI_WIDGETS_TOOLTIPS
+ //registerSkinFile("xml/tooltips/tooltips.xml");
+ #endif
+
+ #ifdef WASABI_COMPILE_STATSWND
+ registerService(new XuiObjectCreator<XuiStatsXuiSvc>);
+ statswnd = new StatsWnd();
+ #endif
+
+ //loadResources();
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SysCallbackI *>(this));
+}
+
+Widgets::~Widgets() {
+#ifdef WASABI_COMPILE_STATSWND
+ delete statswnd;
+#endif
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SysCallbackI *>(this));
+ if (WASABI_API_SVC != NULL)
+ {
+ int i=factories.getNumItems();
+ while (i--)
+ WASABI_API_SVC->service_deregister(factories[i]);
+ }
+ factories.deleteAll();
+}
+
+
+void Widgets::registerService(waServiceFactoryI *f)
+{
+ WASABI_API_SVC->service_register(f);
+ factories.addItem(f);
+}
+
+int Widgets::skincb_onBeforeLoadingElements() {
+ if (count++ > 0) // if 0, we're already loaded so that the lib is usable without 'a skin'
+ loadResources();
+ return 1;
+}
+
+void Widgets::loadResources()
+{
+ // TODO: benski> want to put this into gen_ff somewhere, instead.
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\winamp\\cover\\cover.xml"));
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\winamp\\thinger\\thinger.xml"));
+
+ #ifndef WA3COMPATIBILITY // ifNdef
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\wasabi\\wasabi.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_PATHPICKER
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\pathpicker\\pathpicker.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_LAYOUTSTATUS
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\statusbar\\statusbar.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_TABSHEET
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\tabsheet\\tabsheet.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_CHECKBOX
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\checkbox\\checkbox.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_TITLEBOX
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\titlebox\\titlebox.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_DROPDOWNLIST
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\dropdownlist\\dropdownlist.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_COMBOBOX
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\combobox\\combobox.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_HISTORYEDITBOX
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\historyeditbox\\historyeditbox.xml"));
+ #endif
+ #ifdef WASABI_WIDGETS_TOOLTIPS
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\tooltips\\tooltips.xml"));
+ #endif
+ #ifdef WASABI_COMPILE_WNDMGR
+ //WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,"xml\\msgbox\\msgbox.xml"));
+ #endif
+ WASABI_API_SKIN->loadSkinFile(StringPathCombine(g_resourcepath,L"xml\\about\\about.xml"));
+}
diff --git a/Src/Wasabi/api/skin/widgets.h b/Src/Wasabi/api/skin/widgets.h
new file mode 100644
index 00000000..0089dfd2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets.h
@@ -0,0 +1,35 @@
+#ifndef __WIDGETS_H
+#define __WIDGETS_H
+
+#include <wasabicfg.h>
+#include <bfc/ptrlist.h>
+#include <api/syscb/callbacks/skincb.h>
+
+class waServiceFactoryI;
+
+#ifdef WASABI_COMPILE_STATSWND
+class StatsWnd;
+#endif
+
+class Widgets : public SkinCallbackI {
+ public:
+ Widgets();
+ virtual ~Widgets();
+
+ void registerService(waServiceFactoryI *f);
+ int skincb_onBeforeLoadingElements();
+
+ void loadResources();
+ private:
+
+
+ PtrList<waServiceFactoryI> factories;
+ int count;
+#ifdef WASABI_COMPILE_STATSWND
+ StatsWnd *statswnd;
+#endif
+};
+
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/animlayer.cpp b/Src/Wasabi/api/skin/widgets/animlayer.cpp
new file mode 100644
index 00000000..10c7da1a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/animlayer.cpp
@@ -0,0 +1,880 @@
+#include "precomp.h"
+#include <api/script/scriptmgr.h>
+#include <api/script/script.h>
+#include <api/skin/widgets/animlayer.h>
+#include <tataki/canvas/canvas.h>
+
+const wchar_t animLayerXuiObjectStr[] = L"AnimatedLayer"; // This is the xml tag
+char animLayerXuiSvcName[] = "Animated Layer xui object"; // this is the name of the xuiservice
+
+AnimLayerScriptController _animlayerController;
+AnimLayerScriptController *animlayerController = &_animlayerController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct AnimLayerScriptController::exportedFunction[] = {
+ {L"setSpeed", 1, (void*)AnimatedLayer::script_vcpu_setSpeed },
+ {L"gotoFrame", 1, (void*)AnimatedLayer::script_vcpu_gotoFrame },
+ {L"setStartFrame", 1, (void*)AnimatedLayer::script_vcpu_setStartFrame },
+ {L"setEndFrame", 1, (void*)AnimatedLayer::script_vcpu_setEndFrame },
+ {L"setAutoReplay", 1, (void*)AnimatedLayer::script_vcpu_setAutoReplay },
+ {L"play", 0, (void*)AnimatedLayer::script_vcpu_play },
+ {L"togglePause", 0, (void*)AnimatedLayer::script_vcpu_pause },
+ {L"stop", 0, (void*)AnimatedLayer::script_vcpu_stop },
+ {L"pause", 0, (void*)AnimatedLayer::script_vcpu_pause },
+ {L"isPlaying", 0, (void*)AnimatedLayer::script_vcpu_isPlaying },
+ {L"isPaused", 0, (void*)AnimatedLayer::script_vcpu_isPaused },
+ {L"isStopped", 0, (void*)AnimatedLayer::script_vcpu_isStopped },
+ {L"getStartFrame", 0, (void*)AnimatedLayer::script_vcpu_getStartFrame },
+ {L"getEndFrame", 0, (void*)AnimatedLayer::script_vcpu_getEndFrame },
+ {L"getLength", 0, (void*)AnimatedLayer::script_vcpu_getLength },
+ {L"getDirection", 0, (void*)AnimatedLayer::script_vcpu_getDirection },
+ {L"getAutoReplay", 0, (void*)AnimatedLayer::script_vcpu_getAutoReplay },
+ {L"getCurFrame", 0, (void*)AnimatedLayer::script_vcpu_getCurFrame },
+ {L"onPlay", 0, (void*)AnimatedLayer::script_vcpu_onPlay },
+ {L"onPause", 0, (void*)AnimatedLayer::script_vcpu_onPause },
+ {L"onResume", 0, (void*)AnimatedLayer::script_vcpu_onResume },
+ {L"onStop", 0, (void*)AnimatedLayer::script_vcpu_onStop },
+ {L"onFrame", 1, (void*)AnimatedLayer::script_vcpu_onFrame },
+ {L"setRealtime", 1, (void*)AnimatedLayer::script_vcpu_setRealtime },
+ };
+// --------------------------------------------------------
+
+const wchar_t *AnimLayerScriptController::getClassName()
+{
+ return L"AnimatedLayer";
+}
+
+const wchar_t *AnimLayerScriptController::getAncestorClassName()
+{
+ return L"Layer";
+}
+
+ScriptObject *AnimLayerScriptController::instantiate()
+{
+ AnimatedLayer *a = new AnimatedLayer;
+ ASSERT(a != NULL);
+ return a->getScriptObject();
+}
+
+void AnimLayerScriptController::destroy(ScriptObject *o)
+{
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ ASSERT(a != NULL);
+ delete a;
+}
+
+void *AnimLayerScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for animatedlayer yet
+}
+
+void AnimLayerScriptController::deencapsulate(void *o)
+{}
+
+int AnimLayerScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *AnimLayerScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID AnimLayerScriptController::getClassGuid()
+{
+ return animLayerGuid;
+}
+XMLParamPair AnimatedLayer::params[] =
+ {
+ {ANIMLAYER_AUTOPLAY, L"AUTOPLAY"},
+ {ANIMLAYER_AUTOREPLAY, L"AUTOREPLAY"},
+ {ANIMLAYER_DEBUG, L"DEBUG"},
+ {ANIMLAYER_ELEMENTFRAMES, L"ELEMENTFRAMES"},
+ {ANIMLAYER_END, L"END"},
+ {ANIMLAYER_FRAMEHEIGHT, L"FRAMEHEIGHT"},
+ {ANIMLAYER_FRAMEWIDTH, L"FRAMEWIDTH"},
+ {ANIMLAYER_REALTIME, L"REALTIME"},
+ {ANIMLAYER_SPEED, L"SPEED"},
+ {ANIMLAYER_START, L"START"},
+ };
+
+AnimatedLayer::AnimatedLayer()
+{
+ getScriptObject()->vcpu_setInterface(animLayerGuid, (void *)static_cast<AnimatedLayer *>(this));
+ getScriptObject()->vcpu_setClassName(L"AnimatedLayer");
+ getScriptObject()->vcpu_setController(animlayerController);
+ autoplay = 0;
+ startframe = -1;
+ endframe = -1;
+ curframe = 0;
+ autoreplay = 1;
+ speed = 200;
+ timerset = 0;
+ status = ANIM_STOPPED;
+ realtime = 0;
+ debug = 0;
+ style = ANIM_UNKNOWN;
+ oldstyle = ANIM_UNKNOWN;
+ frameHeight = AUTOWH;
+ frameWidth = AUTOWH;
+ multiple_elements_frames = 0;
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void AnimatedLayer::CreateXMLParameters(int master_handle)
+{
+ //ANIMLAYER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+AnimatedLayer::~AnimatedLayer()
+{
+ bitmap_elements.deleteAll();
+ regionlist.deleteAll();
+}
+
+int AnimatedLayer::onInit()
+{
+ ANIMLAYER_PARENT::onInit();
+
+ int w, h;
+ getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, &h, NULL, NULL, NULL, NULL);
+ if (frameWidth == AUTOWH && w != AUTOWH) setWidth(w, 1);
+ if (frameHeight == AUTOWH && h != AUTOWH) setHeight(h, 1);
+ if (style == 0)
+ {
+ SkinBitmap *bm = getBitmap();
+ if (bm)
+ {
+ if (bm->getWidth() != w) style = ANIM_HORZ;
+ else if (bm->getHeight() != h) style = ANIM_VERT;
+ }
+ }
+
+ if (getRegionOp())
+ makeRegion();
+ reloadMultipleElements();
+
+ if (autoplay)
+ {
+ if (startframe == -1)
+ setStartFrame(0);
+ if (endframe == -1)
+ setEndFrame(getLength() - 1);
+ play();
+ }
+ return 1;
+}
+
+int AnimatedLayer::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *strvalue)
+{
+ if (xuihandle == _xuihandle)
+ {
+ switch (xmlattributeid)
+ {
+ case ANIMLAYER_AUTOREPLAY: setAutoReplay(WTOI(strvalue)); return 1;
+ case ANIMLAYER_AUTOPLAY: setAutoPlay(WTOI(strvalue)); return 1;
+ case ANIMLAYER_SPEED: setSpeed(WTOI(strvalue)); return 1;
+ case ANIMLAYER_FRAMEHEIGHT: setHeight(WTOI(strvalue)); return 1;
+ case ANIMLAYER_FRAMEWIDTH: setWidth(WTOI(strvalue)); return 1;
+ case ANIMLAYER_REALTIME: setRealtime(WTOI(strvalue)); return 1;
+ case ANIMLAYER_ELEMENTFRAMES: setElementFrames(WTOI(strvalue)); return 1;
+ case ANIMLAYER_START: setStartFrame(WTOI(strvalue)); return 1;
+ case ANIMLAYER_END: setEndFrame(WTOI(strvalue)); return 1;
+ case ANIMLAYER_DEBUG: debug = WTOI(strvalue); return 1;
+ }
+ }
+ return ANIMLAYER_PARENT::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, strvalue);
+}
+
+void AnimatedLayer::_invalidate()
+{
+ if (realtime)
+ {
+ if (isVisible() && !isMinimized()) cascadeRepaint();
+ }
+ else
+ invalidate();
+}
+
+void AnimatedLayer::setElementFrames(int n)
+{
+ if (multiple_elements_frames == n) return ;
+ multiple_elements_frames = n;
+ if (n > 0)
+ {
+ if (style != ANIM_MULTI)
+ oldstyle = style;
+ style = ANIM_MULTI;
+ }
+ else
+ {
+ style = oldstyle;
+ oldstyle = ANIM_UNKNOWN;
+ }
+ invalidateRegionCache();
+}
+
+void AnimatedLayer::setHeight(int h, int selfset)
+{
+ ASSERTPR(selfset || style == ANIM_UNKNOWN, "can't set frameHeight if frameWidth has already been set");
+ frameHeight = h;
+ if (!selfset) style = ANIM_VERT;
+}
+
+int AnimatedLayer::getHeight()
+{
+ if (style == ANIM_MULTI)
+ {
+ SkinBitmap *bm0 = getElementBitmap(0);
+ if (bm0 == NULL) return AUTOWH;
+ return bm0->getHeight();
+ }
+ if (style == ANIM_HORZ)
+ return ANIMLAYER_PARENT::getHeight();
+ return frameHeight;
+}
+
+void AnimatedLayer::setWidth(int w, int selfset)
+{
+ ASSERTPR(selfset || style == ANIM_UNKNOWN, "can't set frameWidth if frameHeight has already been set");
+ frameWidth = w;
+ if (!selfset) style = ANIM_HORZ;
+}
+
+int AnimatedLayer::getWidth()
+{
+ if (style == ANIM_MULTI)
+ {
+ SkinBitmap *bm0 = getElementBitmap(0);
+ if (bm0 == NULL) return AUTOWH;
+ return bm0->getWidth();
+ }
+ if (style == ANIM_VERT)
+ return ANIMLAYER_PARENT::getWidth();
+ return frameWidth;
+}
+
+void AnimatedLayer::setRealtime(int r)
+{
+ realtime = r;
+}
+
+int AnimatedLayer::getLength()
+{
+ if (style == ANIM_VERT && frameHeight < 0) return 0;
+ if (style == ANIM_HORZ && frameWidth < 0) return 0;
+ ASSERT(getBitmap() != NULL);
+ if (style == ANIM_VERT)
+ return ANIMLAYER_PARENT::getHeight() / frameHeight;
+ else if (style == ANIM_HORZ)
+ return ANIMLAYER_PARENT::getWidth() / frameWidth;
+ else if (style == ANIM_MULTI)
+ return multiple_elements_frames;
+ return 0;
+}
+
+void AnimatedLayer::timerCallback(int id)
+{
+ switch (id)
+ {
+ case TIMER_ANIM:
+ {
+ int oldframe = curframe;
+ for (int i = 0;i < timerclient_getSkipped() + 1;i++)
+ {
+ if (curframe == getEndFrame())
+ {
+ if (!autoreplay)
+ {
+ stop();
+ break;
+ }
+ else
+ curframe = getStartFrame();
+ }
+ else
+ {
+ curframe += getDirection();
+ if (curframe != oldframe)
+ script_onFrame(curframe);
+ }
+ }
+ if (curframe != oldframe)
+ _invalidate();
+ break;
+ }
+ default:
+ ANIMLAYER_PARENT::timerCallback(id);
+ break;
+ }
+}
+
+int AnimatedLayer::getSourceOffsetY()
+{
+ if (style == ANIM_MULTI) return 0;
+ if (style == ANIM_HORZ) return 0;
+ if (curframe > getLength() - 1) return 0;
+ return curframe * getHeight();
+}
+
+int AnimatedLayer::getSourceOffsetX()
+{
+ if (style == ANIM_MULTI) return 0;
+ if (style == ANIM_VERT) return 0;
+ if (curframe > getLength() - 1) return 0;
+ return curframe * getWidth();
+}
+
+void AnimatedLayer::setSpeed(int s)
+{
+ speed = s;
+ if (status == ANIM_PLAYING)
+ {
+ stopTimer();
+ startTimer();
+ }
+}
+
+void AnimatedLayer::stopTimer()
+{
+ if (timerset)
+ {
+ killTimer(TIMER_ANIM);
+ timerset = 0;
+ }
+}
+
+void AnimatedLayer::startTimer()
+{
+ if (!timerset)
+ {
+ setTimer(TIMER_ANIM, speed);
+ timerset = 1;
+ }
+}
+
+void AnimatedLayer::play()
+{
+ gotoFrame(startframe);
+ startTimer();
+ status = ANIM_PLAYING;
+ script_onPlay();
+}
+
+void AnimatedLayer::stop()
+{
+ stopTimer();
+ status = ANIM_STOPPED;
+ script_onStop();
+}
+
+void AnimatedLayer::pause()
+{
+ if (status == ANIM_PAUSED)
+ {
+ startTimer();
+ status = ANIM_PLAYING;
+ script_onResume();
+ }
+ else
+ if (status == ANIM_PLAYING)
+ {
+ stopTimer();
+ status = ANIM_PAUSED;
+ script_onPause();
+ }
+}
+
+int AnimatedLayer::getCurFrame()
+{
+ return curframe;
+}
+
+void AnimatedLayer::setStartFrame(int s)
+{
+ if (s < 0) return ;
+ startframe = s;
+}
+
+void AnimatedLayer::setEndFrame(int e)
+{
+ if (e < 0) return ;
+ endframe = e;
+}
+
+void AnimatedLayer::setAutoReplay(int r)
+{
+ autoreplay = r;
+}
+
+void AnimatedLayer::setAutoPlay(int r)
+{
+ autoplay = r;
+ // no need to trigger an event here, we can't be in a script if we
+ // need to autoplay at xml loading
+}
+
+int AnimatedLayer::getStartFrame()
+{
+ return startframe == -1 ? 0 : startframe;
+}
+
+int AnimatedLayer::getEndFrame()
+{
+ return endframe == -1 ? getLength() - 1 : endframe;
+}
+
+int AnimatedLayer::getSpeed()
+{
+ return speed;
+}
+
+int AnimatedLayer::isPlaying()
+{
+ return status == ANIM_PLAYING;
+}
+
+int AnimatedLayer::isStopped()
+{
+ return status == ANIM_STOPPED;
+}
+
+int AnimatedLayer::isPaused()
+{
+ return status == ANIM_PAUSED;
+}
+
+int AnimatedLayer::getAutoReplay()
+{
+ return autoreplay;
+}
+
+int AnimatedLayer::getDirection()
+{
+ return getStartFrame() < getEndFrame() ? 1 : -1;
+}
+
+void AnimatedLayer::gotoFrame(int n)
+{
+ if (n != curframe)
+ {
+ curframe = n;
+ _invalidate();
+ script_onFrame(n);
+ }
+}
+
+api_region *AnimatedLayer::getBitmapRegion()
+{
+ if (curframe > getLength() - 1) return NULL;
+ return regionlist.enumItem(getCurFrame());
+}
+
+void AnimatedLayer::makeRegion()
+{
+ if (!isInited()) return ;
+ regionlist.deleteAll();
+ for (int i = 0;i < getLength();i++)
+ {
+ RegionI *rg;
+ if (style == ANIM_VERT)
+ {
+ RECT g = {0, i * getHeight(), getWidth(), i * getHeight() + getHeight()};
+ rg = new RegionI(getBitmap(), &g, 0, -i * getHeight(), FALSE);
+ }
+ else if (style == ANIM_HORZ)
+ {
+ RECT g = {i * getWidth(), 0, i * getWidth() + getWidth(), getHeight()};
+ rg = new RegionI(getBitmap(), &g, -i * getWidth(), 0, FALSE);
+ }
+ else if (style == ANIM_MULTI)
+ {
+ RECT g = {0, 0, getWidth(), getHeight()};
+ rg = new RegionI(getElementBitmap(i), &g, 0, 0, FALSE);
+ }
+ else
+ return;
+ regionlist.addItem(rg);
+ }
+}
+
+void AnimatedLayer::deleteRegion()
+{
+ regionlist.deleteAll();
+}
+
+SkinBitmap *AnimatedLayer::getBitmap()
+{
+ if (style != ANIM_MULTI)
+ return layer_getBitmap();
+ return getElementBitmap(getCurFrame());
+}
+
+SkinBitmap *AnimatedLayer::getElementBitmap(int n)
+{
+ return bitmap_elements.enumItem(n);
+}
+
+void AnimatedLayer::reloadMultipleElements()
+{
+ bitmap_elements.deleteAll();
+ if (style != ANIM_MULTI) return ;
+ // basically blah$$$$.png becomes blah0000.png, blah0001.png etc
+ for (int i = 0;i < multiple_elements_frames;i++)
+ {
+ StringW elementname(layer_getBitmapName());
+ elementname.replaceNumericField(i);
+ bitmap_elements.addItem(new SkinBitmap(elementname));
+ }
+}
+
+void AnimatedLayer::setBitmap(const wchar_t *name)
+{
+ ANIMLAYER_PARENT::setBitmap(name);
+ reloadMultipleElements();
+}
+
+// Script virtuals
+
+int AnimatedLayer::script_getStartFrame()
+{
+ return getStartFrame();
+}
+
+int AnimatedLayer::script_getEndFrame()
+{
+ return getEndFrame();
+}
+
+int AnimatedLayer::script_getSpeed()
+{
+ return getSpeed();
+}
+
+int AnimatedLayer::script_getCurFrame()
+{
+ return getCurFrame();
+}
+
+int AnimatedLayer::script_getDirection()
+{
+ return getDirection();
+}
+
+int AnimatedLayer::script_getAutoReplay()
+{
+ return getAutoReplay();
+}
+
+int AnimatedLayer::script_getLength()
+{
+ return getLength();
+}
+
+int AnimatedLayer::script_isPlaying()
+{
+ return isPlaying();
+}
+
+int AnimatedLayer::script_isStopped()
+{
+ return isStopped();
+}
+
+int AnimatedLayer::script_isPaused()
+{
+ return isPaused();
+}
+
+void AnimatedLayer::script_play()
+{
+ play();
+}
+
+void AnimatedLayer::script_pause()
+{
+ pause();
+}
+
+void AnimatedLayer::script_stop()
+{
+ stop();
+}
+
+void AnimatedLayer::script_setStartFrame(int s)
+{
+ setStartFrame(s);
+}
+
+void AnimatedLayer::script_setEndFrame(int e)
+{
+ setEndFrame(e);
+}
+
+void AnimatedLayer::script_setRealtime(int r)
+{
+ setRealtime(r);
+}
+
+void AnimatedLayer::script_setAutoReplay(int r)
+{
+ setAutoReplay(r);
+}
+/*
+void AnimatedLayer::script_gotoFrame(int n) {
+ gotoFrame(n);
+}*/
+
+void AnimatedLayer::script_setSpeed(int n)
+{
+ setSpeed(n);
+}
+
+void AnimatedLayer::script_onPause()
+{
+ script_vcpu_onPause(SCRIPT_CALL, getScriptObject());
+}
+
+void AnimatedLayer::script_onResume()
+{
+ script_vcpu_onResume(SCRIPT_CALL, getScriptObject());
+}
+
+void AnimatedLayer::script_onStop()
+{
+ script_vcpu_onStop(SCRIPT_CALL, getScriptObject());
+}
+
+void AnimatedLayer::script_onPlay()
+{
+ script_vcpu_onPlay(SCRIPT_CALL, getScriptObject());
+}
+
+void AnimatedLayer::script_onFrame(int n)
+{
+ if (getRegionOp()) { invalidateRegionCache(); getParent()->invalidateWindowRegion(); }
+ scriptVar _n = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_n, n);
+ script_vcpu_onFrame(SCRIPT_CALL, getScriptObject(), _n);
+}
+
+// end virtuals
+
+// VCPU
+
+scriptVar AnimatedLayer::script_vcpu_gotoFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&f));
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a-> /*script_*/gotoFrame(SOM::makeInt(&f));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getLength());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_setStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&s));
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_setStartFrame(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_setEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar e)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&e));
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_setEndFrame(SOM::makeInt(&e));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_setAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar rp)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&rp));
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_setAutoReplay(SOM::makeBoolean(&rp));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_play(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_play();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_pause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_pause();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_stop();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_onPlay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, animlayerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar AnimatedLayer::script_vcpu_onStop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, animlayerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar AnimatedLayer::script_vcpu_onPause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, animlayerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar AnimatedLayer::script_vcpu_onResume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, animlayerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar AnimatedLayer::script_vcpu_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, animlayerController, f);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, f);
+}
+
+scriptVar AnimatedLayer::script_vcpu_getAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getAutoReplay());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_getDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getDirection());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_getStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getStartFrame());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_getEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getEndFrame());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_isPlaying(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_BOOLEAN(a->script_isPlaying());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_isPaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_BOOLEAN(a->script_isPaused());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_isStopped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_BOOLEAN(a->script_isStopped());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getSpeed());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_getCurFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) return MAKE_SCRIPT_INT(a->script_getCurFrame());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar AnimatedLayer::script_vcpu_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&s));
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_setSpeed(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar AnimatedLayer::script_vcpu_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r)
+{
+ SCRIPT_FUNCTION_INIT;
+ AnimatedLayer *a = static_cast<AnimatedLayer *>(o->vcpu_getInterface(animLayerGuid));
+ if (a) a->script_setRealtime(SOM::makeInt(&r));
+ RETURN_SCRIPT_VOID;
+}
+
+
+int AnimatedLayer::onPaint(Canvas *canvas)
+{
+ int r = ANIMLAYER_PARENT::onPaint(canvas);
+ if (debug && canvas != NULL)
+ {
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = 14;
+ canvas->textOut(0, 0, StringPrintfW(L"%d", curframe), &fontInfo);
+ }
+ return r;
+}
diff --git a/Src/Wasabi/api/skin/widgets/animlayer.h b/Src/Wasabi/api/skin/widgets/animlayer.h
new file mode 100644
index 00000000..94c45606
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/animlayer.h
@@ -0,0 +1,214 @@
+#ifndef _ANIMLAYER_H
+#define _ANIMLAYER_H
+
+#include "layer.h"
+
+// {6B64CD27-5A26-4c4b-8C59-E6A70CF6493A}
+static const GUID animLayerGuid =
+{ 0x6b64cd27, 0x5a26, 0x4c4b, { 0x8c, 0x59, 0xe6, 0xa7, 0xc, 0xf6, 0x49, 0x3a } };
+
+#define ANIMLAYER_SCRIPTPARENT Layer
+
+class AnimLayerScriptController : public LayerScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return layerController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern AnimLayerScriptController *animlayerController;
+
+
+#ifndef _NOSTUDIO
+
+#define TIMER_ANIM 872
+
+#define ANIM_STOPPED 0
+#define ANIM_PLAYING 1
+#define ANIM_PAUSED 2
+
+#define ANIMLAYER_PARENT Layer
+
+#define ANIM_UNKNOWN 0
+#define ANIM_VERT 1
+#define ANIM_HORZ 2
+#define ANIM_MULTI 3
+
+class AnimatedLayer : public ANIMLAYER_SCRIPTPARENT {
+public:
+ AnimatedLayer();
+ virtual ~AnimatedLayer();
+
+ virtual int onInit();
+ virtual int getHeight();
+ virtual int getWidth();
+ virtual void timerCallback(int id);
+ virtual int getSourceOffsetY();
+ virtual int getSourceOffsetX();
+ virtual void setAutoPlay(int p);
+ virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void setHeight(int h, int selfset=0);
+ virtual void setWidth(int w, int selfset=0);
+ virtual SkinBitmap *getBitmap();
+
+ void play();
+ void pause();
+ void stop();
+ int getLength();
+ void setStartFrame(int s);
+ void setEndFrame(int e);
+ void setAutoReplay(int r);
+ int getStartFrame();
+ int getEndFrame();
+ int isPlaying();
+ int isPaused();
+ int isStopped();
+ int getSpeed();
+ int getDirection();
+ void gotoFrame(int n);
+ void setSpeed(int s);
+ int getAutoReplay();
+ int getCurFrame();
+ void setRealtime(int r);
+
+ virtual api_region *getBitmapRegion();
+ SkinBitmap *getElementBitmap(int n);
+ virtual void makeRegion();
+ virtual void deleteRegion();
+ void reloadMultipleElements();
+ virtual void setElementFrames(int n);
+ virtual void setBitmap(const wchar_t *name);
+
+ virtual int onPaint(Canvas *canvas);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ enum {
+ ANIMLAYER_AUTOREPLAY=0,
+ ANIMLAYER_AUTOPLAY,
+ ANIMLAYER_SPEED,
+ ANIMLAYER_FRAMEHEIGHT,
+ ANIMLAYER_FRAMEWIDTH,
+ ANIMLAYER_REALTIME,
+ ANIMLAYER_ELEMENTFRAMES,
+ ANIMLAYER_START,
+ ANIMLAYER_END,
+ ANIMLAYER_DEBUG,
+ };
+
+private:
+ int frameHeight, frameWidth;
+ int startframe;
+ int endframe;
+ int status;
+ int curframe;
+ int autoreplay;
+ int speed;
+ int timerset;
+ int realtime;
+ int style;
+ int autoplay;
+ PtrList<SkinBitmap> bitmap_elements;
+ int multiple_elements_frames;
+ int debug;
+ int xuihandle;
+
+ void _invalidate();
+
+ void stopTimer();
+ void startTimer();
+
+ PtrList<RegionI> regionlist;
+ int oldstyle;
+ static XMLParamPair params[];
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+
+public:
+
+ // virtuals
+
+ virtual void script_play();
+ virtual void script_pause();
+ virtual void script_stop();
+ virtual int script_getLength();
+ virtual void script_setStartFrame(int s);
+ virtual void script_setEndFrame(int e);
+ virtual void script_setAutoReplay(int r);
+ virtual void script_setSpeed(int a);
+ virtual int script_getStartFrame();
+ virtual int script_getEndFrame();
+ virtual int script_getSpeed();
+ virtual int script_getDirection();
+ virtual int script_getAutoReplay();
+ virtual int script_isPlaying();
+ virtual int script_isStopped();
+ virtual int script_isPaused();
+ //virtual void script_gotoFrame(int f);
+ virtual void script_onFrame(int n);
+ virtual void script_onStop();
+ virtual void script_onPlay();
+ virtual void script_onPause();
+ virtual void script_onResume();
+ virtual int script_getCurFrame();
+ virtual void script_setRealtime(int r);
+
+ static scriptVar script_vcpu_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_gotoFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f);
+ static scriptVar script_vcpu_setStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_setEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar e);
+ static scriptVar script_vcpu_setAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ar);
+ static scriptVar script_vcpu_play(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_pause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static scriptVar script_vcpu_isPlaying(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_isPaused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_isStopped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getStartFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getEndFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getLength(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getAutoReplay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getCurFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar script_vcpu_onPlay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onStop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onPause(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onResume(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar f);
+
+
+#else
+class AnimatedLayer : public ANIMLAYER_SCRIPTPARENT {
+
+public:
+
+#endif
+
+// INSERT_SCRIPT_OBJECT_CONTROL
+
+};
+
+extern const wchar_t animLayerXuiObjectStr[];
+extern char animLayerXuiSvcName[];
+class AnimLayerXuiSvc : public XuiObjectSvc<AnimatedLayer, animLayerXuiObjectStr, animLayerXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/button.cpp b/Src/Wasabi/api/skin/widgets/button.cpp
new file mode 100644
index 00000000..639443bc
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/button.cpp
@@ -0,0 +1,508 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "button.h"
+#include <api/skin/skinparse.h>
+
+#include <api/script/scriptmgr.h>
+
+#ifdef WASABI_WIDGETS_COMPBUCK
+#include <api/skin/widgets/compbuck2.h>
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+#include <api/core/api_core.h>
+#endif
+
+#include <api/service/svcs/svc_action.h>
+
+const wchar_t buttonXuiObjectStr[] = L"Button"; // This is the xml tag
+char buttonXuiSvcName[] = "Button xui object"; // this is the name of the xuiservice
+
+
+ButtonScriptController _buttonController;
+ButtonScriptController *buttonController = &_buttonController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ButtonScriptController::exportedFunction[] = {
+{L"onActivate", 1, (void*)Wasabi::Button::script_vcpu_onActivate },
+ {L"setActivated", 1, (void*)Wasabi::Button::script_vcpu_setActivated },
+ {L"getActivated", 0, (void*)Wasabi::Button::script_vcpu_getActivated },
+ {L"onLeftClick", 0, (void*)Wasabi::Button::script_vcpu_onLeftClick },
+ {L"onRightClick", 0, (void*)Wasabi::Button::script_vcpu_onRightClick },
+ {L"leftClick", 0, (void*)Wasabi::Button::script_vcpu_leftClick },
+ {L"rightClick", 0, (void*)Wasabi::Button::script_vcpu_rightClick },
+ {L"setActivatedNoCallback", 1, (void*)Wasabi::Button::script_vcpu_setActivatedNoCallback },
+
+};
+// --------------------------------------------------------
+
+const wchar_t *ButtonScriptController::getClassName() {
+ return L"Button";
+}
+
+const wchar_t *ButtonScriptController::getAncestorClassName() {
+ return L"GuiObject";
+}
+
+ScriptObject *ButtonScriptController::instantiate() {
+ Wasabi::Button *b = new Wasabi::Button;
+ ASSERT(b != NULL);
+ return b->getScriptObject();
+}
+
+void ButtonScriptController::destroy(ScriptObject *o) {
+ Wasabi::Button *b = static_cast<Wasabi::Button *>(o->vcpu_getInterface(buttonGuid));
+ ASSERT(b != NULL);
+ delete b;
+}
+
+void *ButtonScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for buttojn yet
+}
+
+void ButtonScriptController::deencapsulate(void *o) {
+}
+
+int ButtonScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ButtonScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID ButtonScriptController::getClassGuid() {
+ return buttonGuid;
+}
+
+XMLParamPair Wasabi::Button::params[] =
+{
+ {BUTTON_ACTION, L"ACTION"},
+ {BUTTON_ACTIONTARGET, L"ACTION_TARGET"},
+ {BUTTON_ACTIVEIMAGE, L"ACTIVEIMAGE"},
+ {BUTTON_BORDERS, L"BORDERS"},
+ #ifdef WASABI_WIDGETS_COMPBUCK
+ {BUTTON_CBTARGET, L"CBTARGET"},
+#endif
+ {BUTTON_CENTER_IMAGE, L"CENTER_IMAGE"},
+ {BUTTON_DOWNIMAGE, L"DOWNIMAGE"},
+ {BUTTON_HOVERIMAGE, L"HOVERIMAGE"},
+ {BUTTON_IMAGE, L"IMAGE"},
+ {BUTTON_PARAM, L"PARAM"},
+ // {BUTTON_RECTRGN, "RECTRGN"},
+ {BUTTON_RETCODE, L"RETCODE"},
+ {BUTTON_BORDERSTYLE, L"STYLE"},
+ {BUTTON_TEXT, L"TEXT"},
+ {BUTTON_TEXTCOLOR, L"TEXTCOLOR"},
+ {BUTTON_TEXTHOVERCOLOR, L"TEXTDIMMEDCOLOR"},
+ {BUTTON_TEXTHOVERCOLOR, L"TEXTHOVERCOLOR"},
+};
+// -----------------------------------------------------------------------
+
+Wasabi::Button::Button() {
+ disablenextcontextmenu = 0;
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+#endif
+ getScriptObject()->vcpu_setInterface(buttonGuid, (void *)static_cast<Button*>(this));
+ getScriptObject()->vcpu_setClassName(L"Button");
+ getScriptObject()->vcpu_setController(buttonController);
+ cbtarget = NULL;
+ setBorders(FALSE);
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void Wasabi::Button::CreateXMLParameters(int master_handle)
+{
+ //BUTTON_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Wasabi::Button::~Button() {
+ //int c=getNotifyId();
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+#endif
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
+}
+
+int Wasabi::Button::onInit()
+{
+ BUTTON_PARENT::onInit();
+ if (!action.isempty())
+ setAction(action);
+ //FG> this is retarded, and yes, i'm the one who coded it in
+ //if (s_normal.isempty() && s_down.isempty() && s_hover.isempty() && s_active.isempty())
+ // setRectRgn(1);
+ setupBitmaps();
+ //int c=getNotifyId();
+ setHandleRightClick(TRUE);
+#ifdef WASABI_COMPILE_MEDIACORE
+ if (WCSCASEEQLSAFE(actionstr, L"eq_toggle")
+ || WCSCASEEQLSAFE(actionstr, L"eq_auto"))
+ {
+ if (WCSCASEEQLSAFE(actionstr, L"eq_toggle"))
+ corecb_onEQStatusChange(WASABI_API_MEDIACORE->core_getEqStatus(0));
+ else corecb_onEQAutoChange(WASABI_API_MEDIACORE->core_getEqAuto(0));
+ }
+#endif
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
+ return 1;
+}
+
+void Wasabi::Button::setupBitmaps()
+{
+ setBitmaps(s_normal, s_down, s_hover, s_active);
+}
+
+void Wasabi::Button::setParam(const wchar_t *p)
+{
+ param=p;
+}
+
+void Wasabi::Button::setAction(const wchar_t *_action)
+{
+ actionstr = _action;
+ const wchar_t *name;
+ int id = SkinParser::getAction(_action, &name);
+ actionname = name;
+ if (id == ACTION_NONE || !action_target.isempty())
+ action = _action;
+ else {
+ setNotifyId(id);
+ action = L"";
+ }
+}
+
+int Wasabi::Button::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue) {
+ if (xuihandle == _xuihandle) {
+ switch (xmlattributeid) {
+ case BUTTON_TEXT: setButtonText(strvalue); return 1;
+ case BUTTON_ACTION: action = strvalue; if (isInited()) { setAction(action); } return 1;
+ case BUTTON_IMAGE: s_normal = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1;
+ case BUTTON_DOWNIMAGE: s_down = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1;
+ case BUTTON_HOVERIMAGE: s_hover = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1;
+ case BUTTON_ACTIVEIMAGE: s_active = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); }return 1;
+ case BUTTON_PARAM: setParam(strvalue); return 1;
+ //case BUTTON_RECTRGN: setRectRgn(WTOI(strvalue)); return 1;
+#ifdef WASABI_WIDGETS_COMPBUCK
+ case BUTTON_CBTARGET: setCBTarget(strvalue); return 1;
+#endif
+ case BUTTON_BORDERS: setBorders(WTOI(strvalue)); return 1;
+ case BUTTON_BORDERSTYLE: setBorderStyle(strvalue); return 1;
+ case BUTTON_RETCODE: setModalRetCode(WTOI(strvalue)); return 1;
+ case BUTTON_ACTIONTARGET: {
+ action_target = strvalue;
+ if (!actionstr.isempty()) {
+ action = actionstr;
+ setAction(action);
+ }
+ return 1;
+ }
+ case BUTTON_CENTER_IMAGE: setBitmapCenter(WTOI(strvalue)); return 1;
+ case BUTTON_TEXTCOLOR: setTextColor(strvalue); return 1;
+ case BUTTON_TEXTHOVERCOLOR: setTextHoverColor(strvalue); return 1;
+ case BUTTON_TEXTDIMMEDCOLOR: setTextDimmedColor(strvalue); return 1;
+ }
+ }
+ return BUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, paramname, strvalue);
+}
+
+#ifdef WASABI_WIDGETS_COMPBUCK
+void Wasabi::Button::setCBTarget(const wchar_t *t) {
+ cbtarget = ComponentBucket2::getComponentBucket(t);
+}
+#endif
+
+const wchar_t *Wasabi::Button::getParam()
+{
+ return param;
+}
+
+int Wasabi::Button::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+#ifdef WASABI_COMPILE_WNDMGR
+ switch(msg)
+ {
+#ifdef _WIN32
+ case WM_WA_CONTAINER_TOGGLED:
+ if(!param) break;
+ if(!WCSICMP((const wchar_t *)param1,param)) setActivatedButton(param2);
+ break;
+#else
+#warning port me
+#endif
+#ifdef WASABI_COMPILE_COMPONENTS
+ case WM_WA_COMPONENT_TOGGLED:
+ if(!param) break;
+ GUID *g;
+ if(g=SkinParser::getComponentGuid(param)) {
+ if(!MEMCMP((GUID *)param1,g,sizeof(GUID))) setActivatedButton(param2);
+ }
+ break;
+#endif
+ }
+#endif
+ return BUTTON_PARENT::childNotify(child, msg, param1, param2);
+}
+
+#ifdef WASABI_COMPILE_MEDIACORE
+int Wasabi::Button::corecb_onEQStatusChange(int newval) {
+ if(WCSCASEEQLSAFE(actionstr, L"eq_toggle")) setActivatedButton(newval);
+ return 0;
+}
+
+int Wasabi::Button::corecb_onEQAutoChange(int newval) {
+ if(WCSCASEEQLSAFE(actionstr,L"eq_auto")) setActivatedButton(newval);
+ return 0;
+}
+#endif
+
+int Wasabi::Button::onLeftButtonUp(int x, int y) {
+ BUTTON_PARENT::onLeftButtonUp(x, y);
+ if (!WASABI_API_MAKI->vcpu_getComplete()) {
+#ifdef WASABI_WIDGETS_COMPBUCK
+ if (getNotifyId() == ACTION_CB_NEXT) {
+ if (cbtarget)
+ cbtarget->ComponentBucket2::next_up();
+ else
+ ComponentBucket2::next_up(getGuiObject()->guiobject_getParentGroup());
+ } else if (getNotifyId() == ACTION_CB_PREV) {
+ if (cbtarget)
+ cbtarget->ComponentBucket2::prev_up();
+ else
+ ComponentBucket2::prev_up(getGuiObject()->guiobject_getParentGroup());
+ } else if (getNotifyId() == ACTION_CB_NEXTPAGE) {
+ if (cbtarget)
+ cbtarget->ComponentBucket2::next_page();
+ else
+ ComponentBucket2::next_page(getGuiObject()->guiobject_getParentGroup());
+ } else if (getNotifyId() == ACTION_CB_PREVPAGE) {
+ if (cbtarget)
+ cbtarget->ComponentBucket2::prev_page();
+ else
+ ComponentBucket2::prev_page(getGuiObject()->guiobject_getParentGroup());
+ }
+#endif
+ }
+ return 1;
+}
+
+int Wasabi::Button::onLeftButtonDown(int x, int y) {
+ BUTTON_PARENT::onLeftButtonDown(x, y);
+ if (!WASABI_API_MAKI->vcpu_getComplete()) {
+#ifdef WASABI_WIDGETS_COMPBUCK
+ if (getNotifyId() == ACTION_CB_NEXT) {
+ if (cbtarget)
+ cbtarget->ComponentBucket2::next_down();
+ else
+ ComponentBucket2::next_down(getGuiObject()->guiobject_getParentGroup());
+ } else if (getNotifyId() == ACTION_CB_PREV) {
+ if (cbtarget)
+ cbtarget->ComponentBucket2::prev_down();
+ else
+ ComponentBucket2::prev_down(getGuiObject()->guiobject_getParentGroup());
+ }
+#endif
+ }
+ return 1;
+}
+
+void Wasabi::Button::onLeftPush(int x, int y) {
+ BUTTON_PARENT::onLeftPush(x, y);
+ script_vcpu_onLeftClick(SCRIPT_CALL, getScriptObject());
+ if (!WASABI_API_MAKI->vcpu_getComplete()) {
+ if (!action.isempty()) {
+ if (!action_target.isempty())
+ {
+ GuiObject *go = getGuiObject()->guiobject_findObject(action_target);
+ if (!go)
+ {
+ ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target);
+ if (so != NULL)
+ go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
+ }
+ if (go) {
+ ifc_window *w = go->guiobject_getRootWnd();
+ if (w) {
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ sendAction(w, actionstr, getParam(), _x, _y);
+ }
+ }
+ } else {
+ svc_action *act = ActionEnum(actionstr).getNext();
+ if (act) {
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ act->onAction(actionstr, getParam(), _x, _y, NULL, 0, this);
+ SvcEnum::release(act);
+ }
+ }
+ }
+ }
+}
+
+int Wasabi::Button::wantAutoContextMenu() {
+ int a = disablenextcontextmenu;
+ disablenextcontextmenu = 0;
+ return !a;
+}
+
+void Wasabi::Button::onRightPush(int x, int y) {
+ BUTTON_PARENT::onRightPush(x, y);
+ script_vcpu_onRightClick(SCRIPT_CALL, getScriptObject());
+ if (!WASABI_API_MAKI->vcpu_getComplete()) {
+ if (!action.isempty()) {
+ if (!action_target.isempty())
+ {
+ GuiObject *go = getGuiObject()->guiobject_findObject(action_target);
+ if (!go) {
+ ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target);
+ if (so != NULL)
+ go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
+ }
+ if (go) {
+ ifc_window *w = go->guiobject_getRootWnd();
+ if (w) {
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ sendAction(w, actionstr, getParam(), _x, _y);
+ disablenextcontextmenu = 1;
+ }
+ }
+ } else {
+ svc_action *act = ActionEnum(actionstr).getNext();
+ if (act) {
+ const wchar_t *par = getParam();
+ if (par == NULL || *par == 0) par = L"1";
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ disablenextcontextmenu = act->onAction(actionstr, par, _x, _y, NULL, 0, this);
+ SvcEnum::release(act);
+ }
+ }
+ }
+ }
+}
+
+int Wasabi::Button::onActivateButton(int is) {
+ BUTTON_PARENT::onActivateButton(is);
+ scriptVar _is = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_is, is);
+ script_vcpu_onActivate(SCRIPT_CALL, getScriptObject(), _is);
+ return 1;
+}
+
+int Wasabi::Button::getPreferences(int what) {
+ if (what == SUGGESTED_W) return getWidth();
+ if (what == SUGGESTED_H) return getHeight();
+ return BUTTON_PARENT::getPreferences(what);
+}
+
+int Wasabi::Button::onShowWindow(Container *c, GUID guid, const wchar_t *groupid)
+{
+ if(!param) return 1;
+ if (groupid != NULL && !WCSICMP(groupid, param))
+ {
+ setActivatedButton(1);
+ return 1;
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+ GUID *g;
+ if (g=SkinParser::getComponentGuid(param))
+ {
+ if(*g != INVALID_GUID && guid == *g) setActivatedButton(1);
+ }
+#endif
+ return 1;
+}
+
+int Wasabi::Button::onHideWindow(Container *c, GUID guid, const wchar_t *groupid) {
+ if(!param) return 1;
+ if (groupid != NULL && !WCSICMP(groupid, param)) {
+ setActivatedButton(0);
+ return 1;
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+ GUID *g;
+ if (g=SkinParser::getComponentGuid(param)) {
+ if(guid == *g) setActivatedButton(0);
+ }
+#endif
+ return 1;
+}
+
+scriptVar Wasabi::Button::script_vcpu_setActivatedNoCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&v));
+ Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
+ if (b) b->setActivatedNoCallback(SOM::makeBoolean(&v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Wasabi::Button::script_vcpu_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, buttonController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Wasabi::Button::script_vcpu_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, buttonController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Wasabi::Button::script_vcpu_leftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ RECT r;
+ Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
+ if (b) {
+ b->getClientRect(&r);
+ b->onLeftPush(r.left, r.top);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Wasabi::Button::script_vcpu_rightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ RECT r;
+ Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
+ if (b) {
+ b->getClientRect(&r);
+ b->onRightPush(r.left, r.top);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Wasabi::Button::script_vcpu_setActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&v));
+ Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
+ if (b) b->setActivatedButton(SOM::makeBoolean(&v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Wasabi::Button::script_vcpu_getActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
+ if (b) return MAKE_SCRIPT_BOOLEAN(b->getActivatedButton());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Wasabi::Button::script_vcpu_onActivate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, buttonController, v);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, v);
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/button.h b/Src/Wasabi/api/skin/widgets/button.h
new file mode 100644
index 00000000..383c9b75
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/button.h
@@ -0,0 +1,134 @@
+#ifndef _BUTTON_H
+#define _BUTTON_H
+
+#include <bfc/string/bfcstring.h>
+#include <api/script/script.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <api/script/objects/guiobj.h>
+#include <api/syscb/callbacks/corecbi.h>
+#include <api/wndmgr/layout.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/service/svcs/svc_xuiobject.h>
+
+#define BUTTON_PARENT ButtonWnd
+
+class ComponentBucket2;
+
+class ScriptObject;
+
+class ButtonScriptController: public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern ButtonScriptController *buttonController;
+
+namespace Wasabi // Apple defines "Button" so we're pretty much forced to namespace this... annoying
+{
+#ifdef WASABI_COMPILE_MEDIACORE
+class Button : public BUTTON_PARENT, public CoreCallbackI {
+#else
+class Button : public BUTTON_PARENT {
+#endif
+
+public:
+ Button();
+ virtual ~Button();
+
+ virtual int onInit();
+ virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue);
+ virtual void setParam(const wchar_t *p);
+ virtual int getPreferences(int what);
+ virtual const wchar_t *getParam();
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onLeftButtonDown(int x, int y);
+ virtual void onLeftPush(int x, int y);
+ virtual void onRightPush(int x, int y);
+ virtual int onActivateButton(int is);
+
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2);
+
+ virtual int wantAutoContextMenu();
+#ifdef WASABI_WIDGETS_COMPBUCK
+ virtual void setCBTarget(const wchar_t *t);
+#endif
+ virtual void setAction(const wchar_t *action);
+
+ virtual int onShowWindow(Container *c, GUID guid, const wchar_t *groupid);
+ virtual int onHideWindow(Container *c, GUID guid, const wchar_t *groupid);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+#ifdef WASABI_COMPILE_MEDIACORE
+ virtual int corecb_onEQStatusChange(int newval);
+ virtual int corecb_onEQAutoChange(int newval);
+#endif
+ StringW s_normal, s_down, s_hover, s_active;
+ int btn_getXuiHandle() { return xuihandle; }
+ int retcode;
+ virtual void setupBitmaps();
+
+ enum {
+ BUTTON_TEXT = 0,
+ BUTTON_ACTION,
+ BUTTON_IMAGE,
+ BUTTON_DOWNIMAGE,
+ BUTTON_HOVERIMAGE,
+ BUTTON_ACTIVEIMAGE,
+ BUTTON_PARAM,
+ BUTTON_RECTRGN,
+ BUTTON_CBTARGET,
+ BUTTON_BORDERS,
+ BUTTON_BORDERSTYLE,
+ BUTTON_RETCODE,
+ BUTTON_ACTIONTARGET,
+ BUTTON_CENTER_IMAGE,
+ BUTTON_TEXTCOLOR,
+ BUTTON_TEXTHOVERCOLOR,
+ BUTTON_TEXTDIMMEDCOLOR,
+ BUTTON_NUMPARAMS,
+ };
+
+private:
+ StringW param;
+ StringW action, actionstr, actionname;
+ StringW action_target;
+ ComponentBucket2 *cbtarget;
+ int borders;
+ int disablenextcontextmenu;
+ int xuihandle;
+ static XMLParamPair params[];
+
+public:
+ static scriptVar script_vcpu_setActivatedNoCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_leftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_rightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_getActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onActivate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+};
+}
+
+extern const wchar_t buttonXuiObjectStr[];
+extern char buttonXuiSvcName[];
+class ButtonXuiSvc : public XuiObjectSvc<Wasabi::Button, buttonXuiObjectStr, buttonXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/checkbox.cpp b/Src/Wasabi/api/skin/widgets/checkbox.cpp
new file mode 100644
index 00000000..505687b2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/checkbox.cpp
@@ -0,0 +1,262 @@
+#include <precomp.h>
+#include "checkbox.h"
+#include <api/service/svcs/svc_action.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/objects/c_script/c_button.h>
+#include <api/script/objects/guiobject.h>
+#include <api/script/scriptguid.h>
+#include <api/script/api_maki.h>
+
+// -----------------------------------------------------------------------
+CheckBox::CheckBox(const wchar_t *_text, const wchar_t *_radioid) :
+ textclicks(NULL), toggleclicks(NULL), text(_text), radioid(_radioid),
+ buttonGuiObj(NULL), use_radioval(0),
+ CHECKBOX_PARENT() { }
+
+CheckBox::~CheckBox() {
+ delete textclicks;
+ delete toggleclicks;
+}
+
+int CheckBox::onInit() {
+ int r = CHECKBOX_PARENT::onInit();
+ if (radioid.len()) {
+ abstract_setContent(L"wasabi.radiobutton.group");
+ // After we set the content for radio, we should register ourselves
+ // as a radio button under the radio group we are assigned.
+ GuiObject *radioGuiObj = abstract_findObject(radioid); // this will actually go down a level
+ if (radioGuiObj != NULL) {
+ ifc_window *radioRootWnd = *radioGuiObj; // explicit cast operator :)
+ // Now, once we have the rootwnd, we can send our radio group object a message, it will turn off other items as we turn on specific ones
+ if (radioRootWnd != NULL) {
+ sendAction(radioRootWnd, L"REGISTER", NULL, -1, -1, 0, 0, (void *)getGuiObject(), 4);
+ }
+ }
+ } else {
+ abstract_setContent(L"wasabi.checkbox.group");
+ }
+ return r;
+}
+
+void CheckBox::onNewContent() {
+ // remove all previous hooks because our content changed
+ delete toggleclicks;
+ toggleclicks = NULL;
+
+ delete textclicks;
+ textclicks = NULL;
+
+ // Capture the clicks on the button
+ buttonGuiObj = abstract_findObject(L"checkbox.toggle");
+ if (buttonGuiObj != NULL) {
+ toggleclicks = new ToggleClicks(*buttonGuiObj, this);
+ }
+
+ // Capture the clicks on the text
+ GuiObject *textGuiObj = abstract_findObject(L"checkbox.text");
+ if (textGuiObj != NULL) {
+ textclicks = new TextClicks(*textGuiObj, this);
+ }
+
+ // Set the text object to display the requested text.
+ updateText();
+}
+
+int CheckBox::getPreferences(int what) {
+ ifc_window *w = abstract_getContentRootWnd();
+ if (w != NULL)
+ return w->getPreferences(what);
+ return CHECKBOX_PARENT::getPreferences(what);
+}
+
+void CheckBox::setActivated(int activated, int writetocfg) {
+ // this is usually called as a response to onReloadConfig, but could also be called
+ // directly by a 3rd party, so if we can, we read the current value and do nothing if
+ // it hasn't changed.
+ GuiObject *toggleGuiObj = abstract_findObject(L"checkbox.toggle");
+ if (toggleGuiObj != NULL) {
+ C_Button buttonObj(*toggleGuiObj);
+ int act = buttonObj.getActivated();
+ if (!!act == !!activated) return;
+ buttonObj.setActivatedNoCallback(!!activated);
+ }
+ if (writetocfg) {
+ if (use_radioval) {
+ if (activated) {
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgString(radioval);
+#endif
+ if (radioval != 0) doAction();
+ }
+ } else {
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgInt(activated);
+#endif
+ if (activated) doAction();
+ }
+ }
+}
+
+// This is called by the click catchers
+void CheckBox::toggle(int self_switch) {
+
+ if (!buttonGuiObj) return;
+
+ int activated = !!isActivated();
+ if (self_switch) activated = !activated;
+
+/* int no_setactive = self_switch;
+
+ if (radioid.len() > 0 && activated) { // but if we're a radiobox, do not toggle if we're already activated
+ no_setactive = 1;
+ }
+
+ if (self_switch) activated = !!!activated;
+*/
+
+ if (!(activated && !radioid.isempty()))
+ activated = !activated;
+
+ if (!use_radioval || activated) {
+ C_Button b(*buttonGuiObj);
+ b.setActivatedNoCallback(activated);
+ }
+
+ if (activated) {
+ if (use_radioval) {
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgString(radioval);
+#endif
+ if (radioval != 0) doAction();
+ } else {
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgInt(activated);
+#endif
+ if (activated) doAction();
+ }
+ } else
+#ifdef WASABI_COMPILE_CONFIG
+ if (radioid.len() == 0) getGuiObject()->guiobject_setCfgInt(0); // if we're a radioid being turned off, we shouldn't write our value, as we'll prolly be sharing the same cfgattr with other radioboxes, todo: make that optional
+#endif
+
+ if (radioid.len() > 0 && activated) {
+ GuiObject *radioGuiObj = abstract_findObject(radioid);
+ ifc_window *radioRootWnd = *radioGuiObj;
+ if (radioRootWnd != NULL)
+ sendAction(radioRootWnd, L"TOGGLE", NULL, -1, -1, 0, 0, (void *)getGuiObject(), 4);
+ }
+
+ onToggle();
+}
+
+void CheckBox::onToggle() {
+}
+
+void CheckBox::setText(const wchar_t *_text)
+{
+ text = _text;
+ setName(text);
+ if (isInited()) {
+ updateText();
+ }
+}
+
+const wchar_t *CheckBox::getText() {
+ return text;
+}
+
+void CheckBox::setRadioid(const wchar_t *_radioid)
+{
+ radioid = _radioid;
+}
+
+void CheckBox::setRadioVal(const wchar_t *val, int _use_radioval)
+{
+ radioval = val;
+ use_radioval = _use_radioval;
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+int CheckBox::onReloadConfig()
+{
+ StringW newVal = getGuiObject()->guiobject_getCfgString();
+ int checkit = use_radioval ? (newVal == radioval) : WTOI(newVal);
+ setActivated(checkit, 0);
+ return CHECKBOX_PARENT::onReloadConfig();
+}
+#endif
+
+void CheckBox::updateText() {
+ GuiObject *textGuiObj = abstract_findObject(L"checkbox.text");
+ if (textGuiObj != NULL) {
+ textGuiObj->guiobject_setXmlParam(L"text", text);
+ }
+}
+int CheckBox::isActivated() {
+ if (!buttonGuiObj) return 0;
+ C_Button b(*buttonGuiObj);
+ return b.getActivated();
+}
+
+int CheckBox::onChar(unsigned int c) {
+ switch (c) {
+#ifdef _WIN32
+ case VK_SPACE:
+ toggle(0);
+ break;
+#else
+#warning port me
+#endif
+ default:
+ return CHECKBOX_PARENT::onChar(c);
+ }
+ return 1;
+}
+
+void CheckBox::setAction(const wchar_t *str)
+{
+ action = str;
+}
+
+void CheckBox::setActionTarget(const wchar_t *target) {
+ action_target = target;
+}
+
+void CheckBox::setActionParam(const wchar_t *param) {
+ action_param = param;
+}
+
+const wchar_t *CheckBox::getActionParam()
+{
+ return action_param;
+}
+
+void CheckBox::doAction()
+{
+ if (!action_target.isempty())
+ {
+ GuiObject *go = getGuiObject()->guiobject_findObject(action_target);
+ if (!go) {
+ ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target);
+ if (so != NULL)
+ go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
+ }
+ if (go) {
+ ifc_window *w = go->guiobject_getRootWnd();
+ if (w) {
+ RECT cr;
+ getClientRect(&cr);
+ int _x = cr.left;
+ int _y = cr.top;
+ clientToScreen(&_x, &_y);
+ sendAction(w, action, action_target, _x, _y);
+ }
+ }
+ } else {
+ svc_action *act = ActionEnum(action).getNext();
+ if (act) {
+ act->onAction(action, getActionParam());
+ SvcEnum::release(act);
+ }
+ }
+}
diff --git a/Src/Wasabi/api/skin/widgets/checkbox.h b/Src/Wasabi/api/skin/widgets/checkbox.h
new file mode 100644
index 00000000..213d25a0
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/checkbox.h
@@ -0,0 +1,246 @@
+#ifndef __CHECKBOX_H
+#define __CHECKBOX_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+#include <api/script/objects/c_script/h_button.h>
+
+#define CHECKBOX_PARENT GuiObjectWnd
+
+class TextClicks;
+class ToggleClicks;
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class CheckBox : public CHECKBOX_PARENT {
+
+ public:
+
+ CheckBox(const wchar_t *_text = L"ERROR", const wchar_t *_radioid = NULL);
+ virtual ~CheckBox();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int getPreferences(int what);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void toggle(int self_switch); // this is called by the click catchers.
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setActivated(int activated, int writetocfg=1);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int isActivated();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setText(const wchar_t *_text);
+ const wchar_t *getText();
+ void setRadioid(const wchar_t *_radioid);
+ const wchar_t *getRadioid() { return radioid; }
+ void setRadioVal(const wchar_t *val, int use_radioval=TRUE);
+ const wchar_t *getRadioVal() { return radioval; }
+
+
+#ifdef WASABI_COMPILE_CONFIG
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onReloadConfig();
+#endif
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onNewContent();
+
+ virtual int wantFocus() { return 1; }
+ virtual int onChar(unsigned int c);
+
+ virtual void setAction(const wchar_t *str);
+ virtual void setActionTarget(const wchar_t *target);
+ virtual void setActionParam(const wchar_t *param);
+ virtual const wchar_t *getActionParam();
+
+ protected:
+ virtual void onToggle(); //override to catch toggles
+
+ private:
+
+ void doAction();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void updateText();
+
+ TextClicks *textclicks;
+ ToggleClicks *toggleclicks;
+ StringW text;
+ StringW radioid;
+ GuiObject *buttonGuiObj;
+ StringW radioval;
+ int use_radioval;
+ StringW action, action_target, action_param;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class TextClicks : public H_GuiObject {
+ public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ TextClicks(ScriptObject *textobj, CheckBox *_callback) :
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ callback(_callback), H_GuiObject(textobj) {
+ }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onLeftButtonDown(int x, int y) {
+ callback->toggle(0);
+ }
+ private:
+ CheckBox *callback;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ToggleClicks : public H_Button {
+ public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ToggleClicks(ScriptObject *button, CheckBox *_callback) :
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ callback(_callback), H_Button(button) {
+ inhere=0;
+ }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onActivate(int activate) {
+ if (inhere) return;
+ inhere=1;
+ callback->toggle(1);
+ inhere=0;
+ }
+
+ private:
+ CheckBox *callback;
+ int inhere;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/combobox.cpp b/Src/Wasabi/api/skin/widgets/combobox.cpp
new file mode 100644
index 00000000..9096e7be
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/combobox.cpp
@@ -0,0 +1,270 @@
+#include <precomp.h>
+#include "combobox.h"
+#include <api/script/objects/c_script/c_edit.h>
+#include <api/skin/xmlobject.h>
+
+ComboBox::ComboBox() {
+ keys_edit = NULL;
+ lastlist = NULL;
+ disable_getselection = 0;
+ savedidle = 0;
+ savedautoenter = 0;
+}
+
+ComboBox::~ComboBox() {
+ delete keys_edit;
+}
+
+void ComboBox::abstract_onNewContent() {
+ COMBOBOX_PARENT::abstract_onNewContent();
+ trapControls();
+}
+
+void ComboBox::trapControls() {
+ delete keys_edit;
+
+ keys_edit = NULL;
+
+ if (wantTrapEdit()) {
+ GuiObject *editGuiObj = getGuiObject()->guiobject_findObject(combobox_getEditId());
+ if (editGuiObj) keys_edit = new HEBKeysCallback(*editGuiObj, this);
+ }
+}
+
+void ComboBox::updateTextInControl(const wchar_t *txt)
+{
+ if (txt == NULL) return;
+ if (WCSCASEEQLSAFE(getText(), txt)) return;
+ GuiObject *content = getContent();
+ if (content != NULL) {
+ if (wantTrapEdit()) {
+ GuiObject *text = content->guiobject_findObject(combobox_getEditId());
+ if (text != NULL) {
+ C_Edit t(*text);
+ t.setText(txt);
+ curtxt = txt;
+ }
+ }
+ }
+}
+
+void ComboBox::dropdownlist_onCloseList() {
+ COMBOBOX_PARENT::dropdownlist_onCloseList();
+ if (wantTrapEdit()) {
+ GuiObject *o = embeddedxui_getEmbeddedObject();
+ if (o != NULL) {
+ o->guiobject_getRootWnd()->setFocus();
+ GuiObject *edit = o->guiobject_findObjectByInterface(editGuid);
+ if (edit != NULL) {
+ C_Edit e(*edit);
+ e.setAutoEnter(savedautoenter);
+ e.setIdleEnabled(savedidle);
+ }
+ }
+ }
+ if (wantEnterOnSelect())
+ enter();
+ disable_getselection = 0;
+}
+
+void ComboBox::dropdownlist_onOpenList() {
+ COMBOBOX_PARENT::dropdownlist_onOpenList();
+ if (wantTrapEdit()) {
+ GuiObject *o = embeddedxui_getEmbeddedObject();
+ if (o != NULL) {
+ o->guiobject_getRootWnd()->setFocus();
+ GuiObject *edit = o->guiobject_findObjectByInterface(editGuid);
+ if (edit != NULL) {
+ C_Edit e(*edit);
+ savedidle = e.getIdleEnabled();
+ savedautoenter = e.getAutoEnter();
+ e.setIdleEnabled(0);
+ e.setAutoEnter(0);
+ }
+ }
+ }
+}
+
+void ComboBox::setText(const wchar_t *text, int hover) {
+ updateTextInControl(text);
+ selectItem(-1, hover);
+ selectEditor();
+}
+
+const wchar_t *ComboBox::getText(int fromcontrol)
+{
+
+ if (!fromcontrol)
+ return curtxt;
+
+ const wchar_t *c = NULL;
+ GuiObject *content = getContent();
+ if (content != NULL) {
+ if (wantTrapEdit()) {
+ GuiObject *text = content->guiobject_findObject(combobox_getEditId());
+ if (text != NULL) {
+ C_Edit t(*text);
+ c = t.getText();
+ }
+ }
+ }
+ curtxt = c;
+ return c;
+}
+
+void ComboBox::dropdownlist_onConfigureList(GuiObject *o) {
+ COMBOBOX_PARENT::dropdownlist_onConfigureList(o);
+ ifc_window *w = o->guiobject_getRootWnd()->findWindowByInterface(listGuid);
+ sendAction(w, L"register_tempselectnotify");
+ //w->getGuiObject()->guiobject_setXmlParam("select", getCustomText());
+ lastlist = w->getGuiObject();
+}
+
+void ComboBox::onSelect(int id, int hover) {
+ COMBOBOX_PARENT::onSelect(id, hover);
+ if (!hover) {
+ selectEditor();
+ if (wantEnterOnSelect())
+ enter();
+ }
+}
+
+void ComboBox::enter() {
+ GuiObject *content = getContent();
+ if (content != NULL) {
+ if (wantTrapEdit()) {
+ GuiObject *text = content->guiobject_findObject(combobox_getEditId());
+ if (text != NULL) {
+ C_Edit t(*text);
+ t.enter();
+ }
+ }
+ }
+}
+
+void ComboBox::selectEditor() {
+ GuiObject *content = getContent();
+ if (content != NULL) {
+ if (wantTrapEdit()) {
+ GuiObject *text = content->guiobject_findObject(combobox_getEditId());
+ if (text != NULL) {
+ C_Edit t(*text);
+ t.selectAll();
+ }
+ }
+ }
+}
+
+int ComboBox::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ int r = COMBOBOX_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ if (WCSCASEEQLSAFE(action, L"tempselectnotify")) {
+ if (!disable_getselection)
+ setText(param, 1);
+ }
+ return r;
+}
+
+void ComboBox::onEditKeyDown(int vk) {
+ if (Std::keyDown(VK_CONTROL)) return;
+ if (vk == VK_DOWN) {
+ if (wantDownOpenList()) {
+ if (!isListOpen())
+ openList();
+ else {
+ if (wantTransferDownToList())
+ listDown();
+ }
+ }
+ } else if (vk == VK_UP) {
+ if (wantTransferUpToList())
+ listUp();
+ } else if (vk == VK_HOME) {
+ if (wantTransferHomeToList())
+ listHome();
+ } else if (vk == VK_END) {
+ if (wantTransferEndToList())
+ listEnd();
+ } else if (vk == VK_PRIOR) {
+ if (wantTransferPgUpToList())
+ listPageUp();
+ } else if (vk == VK_NEXT) {
+ if (wantTransferPgDnToList())
+ listPageDown();
+ } else if (vk == VK_ESCAPE) {
+ if (isListOpen())
+ closeList();
+ } else if (vk == VK_BACK || vk == VK_DELETE || vk == VK_LEFT || vk == VK_RIGHT) {
+ if (wantCloseListOnChar()) {
+ if (isListOpen())
+ closeList();
+ }
+ }
+}
+
+void ComboBox::onEditKeyUp(int vk)
+{
+ curtxt = getText(1);
+}
+
+void ComboBox::onEditEnter(const wchar_t *txt)
+{
+ if (isListOpen()) {
+ if (wantTransferEnterToList())
+ listSelect();
+ }
+}
+
+void ComboBox::onEditChar(int c) {
+ if (wantCloseListOnChar()) {
+ if (isListOpen())
+ closeList();
+ }
+}
+
+
+void ComboBox::listUp() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"up");
+ }
+}
+
+void ComboBox::listDown() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"down");
+ }
+}
+
+void ComboBox::listHome() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"home");
+ }
+}
+
+void ComboBox::listEnd() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"end");
+ }
+}
+
+void ComboBox::listPageUp() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"pageup");
+ }
+}
+
+void ComboBox::listPageDown() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"pagedown");
+ }
+}
+
+void ComboBox::listSelect() {
+ if (lastlist != NULL && isListOpen()) {
+ sendAction(lastlist->guiobject_getRootWnd(), L"select_current");
+ }
+}
+
+void ComboBox::onPreCloseList() {
+ disable_getselection = 1;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/combobox.h b/Src/Wasabi/api/skin/widgets/combobox.h
new file mode 100644
index 00000000..08ec11bf
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/combobox.h
@@ -0,0 +1,121 @@
+#ifndef __COMBOBOX_H
+#define __COMBOBOX_H
+
+#include <api/skin/widgets/dropdownlist.h>
+#include <api/script/objects/c_script/h_edit.h>
+#include <api/script/objects/c_script/c_edit.h>
+
+#define COMBOBOX_PARENT DropDownList
+
+class XmlObject;
+class HEBKeysCallback;
+
+class ComboBox : public COMBOBOX_PARENT {
+
+ public:
+
+ ComboBox();
+ virtual ~ComboBox();
+
+ virtual int wantTrapButton() { return 1; }
+ virtual int wantTrapText() { return 0; }
+ virtual int wantTrapEdit() { return 1; }
+
+ virtual void abstract_onNewContent();
+ virtual void trapControls();
+
+ virtual const wchar_t *dropdownlist_getMainGroupId() { return L"wasabi.combobox.main.group"; }
+ virtual const wchar_t *dropdownlist_getListGroupId() { return L"wasabi.combobox.list.group"; }
+ virtual const wchar_t *dropdownlist_getButtonId() { return L"combobox.button"; }
+ virtual const wchar_t *dropdownlist_getListId() { return L"combobox.list"; }
+
+ virtual const wchar_t *combobox_getEditId() { return L"combobox.edit"; }
+
+ virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return combobox_getEditId(); }
+
+ virtual void dropdownlist_onCloseList();
+ virtual void dropdownlist_onOpenList();
+
+ virtual void setText(const wchar_t *text, int hover=0); // use this to set the content of the edit box
+ virtual const wchar_t *getText(int fromcontrol=0); // use this one to ask for the currently displayed entry
+
+ virtual const wchar_t *getCustomText() { return NULL; }
+
+ virtual void dropdownlist_onConfigureList(GuiObject *o);
+ virtual void onSelect(int id, int hover);
+ virtual void enter();
+
+ void selectEditor();
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+ virtual void onEditKeyDown(int vk);
+ virtual void onEditKeyUp(int vk);
+ virtual void onEditEnter(const wchar_t *txt);
+ virtual void onEditChar(int c);
+
+ virtual int wantTransferDownToList() { return 1; }
+ virtual int wantTransferUpToList() { return 1; }
+ virtual int wantTransferHomeToList() { return 1; }
+ virtual int wantTransferEndToList() { return 1; }
+ virtual int wantTransferPgUpToList() { return 1; }
+ virtual int wantTransferPgDnToList() { return 1; }
+ virtual int wantTransferEnterToList() { return 1; }
+ virtual int wantDownOpenList() { return 1; }
+ virtual int wantCloseListOnChar() { return 1; }
+ virtual int wantEnterOnSelect() { return 1; }
+
+ virtual void listDown();
+ virtual void listUp();
+ virtual void listHome();
+ virtual void listEnd();
+ virtual void listPageDown();
+ virtual void listPageUp();
+ virtual void listSelect();
+
+ virtual void onPreCloseList();
+
+ private:
+
+ virtual void updateTextInControl(const wchar_t *text);
+
+ HEBKeysCallback *keys_edit;
+ GuiObject *lastlist;
+ StringW curtxt;
+
+ int savedidle, savedautoenter;
+ int disable_getselection;
+};
+
+class HEBKeysCallback : public H_Edit {
+ public:
+
+ HEBKeysCallback(ScriptObject *trap, ComboBox *_callback) :
+ callback(_callback), H_Edit(trap), o(trap) {
+ }
+
+ virtual void hook_onKeyDown(int vk) {
+ callback->onEditKeyDown(vk);
+ }
+
+ virtual void hook_onKeyUp(int vk) {
+ callback->onEditKeyUp(vk);
+ }
+
+ virtual void hook_onEnter()
+ {
+ C_Edit e(o);
+ callback->onEditEnter(e.getText());
+ }
+
+
+ virtual void hook_onChar(wchar_t c) {
+ callback->onEditChar(c);
+ }
+
+ private:
+ ComboBox *callback;
+ ScriptObject *o;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/compbuck2.cpp b/Src/Wasabi/api/skin/widgets/compbuck2.cpp
new file mode 100644
index 00000000..68b147b2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/compbuck2.cpp
@@ -0,0 +1,611 @@
+#include "precomp.h"
+#include <bfc/std_math.h>
+#include "compbuck2.h"
+#include <api/wac/wac.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wndmgr/layout.h>
+#include <api/wnd/notifmsg.h>
+#include <api/service/service.h>
+#include <api/service/services.h>
+#include <api/wnd/wndclass/svcwndhold.h>
+
+#define TIMER_SCROLL (0x400+8879)
+#define TIMER_SCROLLPAGE (0x400+8880)
+
+#define TIMER_SPEED 10
+#define SCROLL_STEPS 10
+#define SCROLL_SPEED 20
+
+#define SCROLL_LEFT -2
+#define SCROLL_RIGHT +2
+
+#ifndef PI
+#define PI 3.1415926536
+#endif
+
+const wchar_t componentBucketXuiObjectStr[] = L"ComponentBucket"; // This is the xml tag
+char componentBucketXuiSvcName[] = "ComponentBucket xui object"; // this is the name of the xuiservice
+
+XMLParamPair ComponentBucket2::params[] =
+{
+ {COMPBUCK_LEFTMARGIN, L"LEFTMARGIN"},
+ {COMPBUCK_RIGHTMARGIN, L"RIGHTMARGIN"},
+ {COMPBUCK_SPACING, L"SPACING"},
+ {COMPBUCK_VERTICAL, L"VERTICAL"},
+ {COMPBUCK_WNDTYPE, L"WNDTYPE"},
+};
+
+ComponentBucket2::ComponentBucket2() {
+ getScriptObject()->vcpu_setInterface(cbucketGuid, (void *)static_cast<ComponentBucket2 *>(this));
+ getScriptObject()->vcpu_setClassName(L"ComponentBucket");
+ getScriptObject()->vcpu_setController(cbucketController);
+ lastticcount=0;
+ wndtype = BUCKETITEM;
+ timeron = 0;
+ lmargin = 2;
+ rmargin = 2;
+ spacing = 2;
+ direction = 0;
+ xscroll = 0;
+ timerset = 0;
+ cblist.addItem(this);
+ vertical = 0;
+ scrollpage_timerset = 0;
+ scrollpage_starttime = 0;
+ scrollpage_start = 0;
+ scrollpage_target = 0;
+ scrollpage_speed = 250;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void ComponentBucket2::CreateXMLParameters(int master_handle)
+{
+ //COMPONENTBUCKET2_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ComponentBucket2::~ComponentBucket2() {
+ if (scrollpage_timerset) killTimer(TIMER_SCROLLPAGE);
+ myclients.deleteAll();
+ cblist.removeItem(this);
+ if (cblist.getNumItems() == 0) cblist.removeAll();
+}
+
+int ComponentBucket2::onInit() {
+ COMPONENTBUCKET2_PARENT::onInit();
+ load();
+ return 1;
+}
+
+int ComponentBucket2::setXuiParam(int _xuihandle, int id, const wchar_t *name, const wchar_t *strval) {
+ if (xuihandle == _xuihandle) {
+ switch (id) {
+ case COMPBUCK_LEFTMARGIN: setLMargin(WTOI(strval)); return 1;
+ case COMPBUCK_RIGHTMARGIN: setRMargin(WTOI(strval)); return 1;
+ case COMPBUCK_SPACING: setSpacing(WTOI(strval)); return 1;
+ case COMPBUCK_VERTICAL: setVertical(WTOI(strval)); return 1;
+ case COMPBUCK_WNDTYPE: wndtype = strval; return 1;
+ }
+ }
+ return COMPONENTBUCKET2_PARENT::setXuiParam(_xuihandle, id, name, strval);
+}
+
+void ComponentBucket2::setScroll(int v) {
+ xscroll = v;
+ if (isInited())
+ onResize();
+ invalidate();
+}
+
+int ComponentBucket2::getScroll() {
+ return xscroll;
+}
+
+void ComponentBucket2::timerCallback(int id) {
+ switch (id) {
+ case TIMER_SCROLL: {
+ RECT r;
+ getClientRect(&r);
+ do {
+ xscroll += direction;
+ lastticcount += TIMER_SPEED;
+ } while (lastticcount < Wasabi::Std::getTickCount() - TIMER_SPEED);
+ if (!vertical)
+ xscroll = MIN((int)(getMaxWidth()-(r.right-r.left)), xscroll);
+ else
+ xscroll = MIN((int)(getMaxHeight()-(r.bottom-r.top)), xscroll);
+ xscroll = MAX(0, xscroll);
+ if (isInited())
+ onResize();
+ invalidate();
+ return;
+ }
+ case TIMER_SCROLLPAGE: {
+ int n = MulDiv(Wasabi::Std::getTickCount()-scrollpage_starttime,256,scrollpage_speed);
+ if (n > 255) n = 255; if (n < 0) n = 0;
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5);
+ xscroll = (int)(((float)(scrollpage_target - scrollpage_start) * sintrans) + scrollpage_start);
+ if (n == 255) {
+ killTimer(TIMER_SCROLLPAGE);
+ scrollpage_timerset = 0;
+ }
+ if (isInited())
+ onResize();
+ invalidate();
+ return;
+ }
+ default:
+ COMPONENTBUCKET2_PARENT::timerCallback(id);
+ return;
+ }
+}
+
+int ComponentBucket2::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) {
+ switch (msg) {
+ case ChildNotify::COMPONENTBUCKET_SETTEXT:
+ setText((const wchar_t *)p1);
+ return 1;
+ }
+ return COMPONENTBUCKET2_PARENT::childNotify(child, msg, p1, p2);
+}
+
+void ComponentBucket2::prev_down(Group *l) {
+ if (!l) return;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer())
+ cblist[i]->prev_down();
+ }
+}
+
+void ComponentBucket2::next_down(Group *l) {
+ if (!l) return;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer())
+ cblist[i]->next_down();
+ }
+}
+
+void ComponentBucket2::prev_up(Group *l) {
+ if (!l) return;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer())
+ cblist[i]->prev_up();
+ }
+}
+
+void ComponentBucket2::next_up(Group *l) {
+ if (!l) return;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer())
+ cblist[i]->next_up();
+ }
+}
+
+void ComponentBucket2::prev_page(Group *l) {
+ if (!l) return;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer())
+ cblist[i]->prev_page();
+ }
+}
+
+void ComponentBucket2::next_page(Group *l) {
+ if (!l) return;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist[i]->getGuiObject()->guiobject_getParentGroup()->getParentContainer() == l->getParentContainer())
+ cblist[i]->next_page();
+ }
+}
+
+void ComponentBucket2::prev_down() {
+ direction = SCROLL_LEFT;
+ startScrollTimer();
+}
+
+void ComponentBucket2::prev_up() {
+ stopScrollTimer();
+}
+
+void ComponentBucket2::next_down() {
+ direction = SCROLL_RIGHT;
+ startScrollTimer();
+}
+
+void ComponentBucket2::next_up() {
+ stopScrollTimer();
+}
+
+void ComponentBucket2::prev_page() {
+ scrollpage_starttime = Wasabi::Std::getTickCount();
+ scrollpage_start = xscroll;
+ RECT r;
+ getClientRect(&r);
+ int nx = 0;
+ if (vertical)
+ nx = r.bottom - r.top;
+ else
+ nx = r.right - r.left;
+ nx = xscroll - nx;
+ if (nx < 0) nx = 0;
+ scrollpage_target = nx;
+ if (!scrollpage_timerset) {
+ setTimer(TIMER_SCROLLPAGE, 20);
+ scrollpage_timerset = 1;
+ }
+}
+
+void ComponentBucket2::next_page() {
+ scrollpage_starttime = Wasabi::Std::getTickCount();
+ scrollpage_start = xscroll;
+ RECT r;
+ getClientRect(&r);
+ int nx = 0;
+ if (vertical)
+ nx = r.bottom - r.top;
+ else
+ nx = r.right - r.left;
+ nx += xscroll;
+ if (!vertical)
+ nx = MIN((int)(getMaxWidth()-(r.right-r.left)), nx);
+ else
+ nx = MIN((int)(getMaxHeight()-(r.bottom-r.top)), nx);
+ scrollpage_target = nx;
+ if (!scrollpage_timerset) {
+ setTimer(TIMER_SCROLLPAGE, 20);
+ scrollpage_timerset = 1;
+ }
+}
+
+void ComponentBucket2::startScrollTimer() {
+ if (timerset) return;
+ timerset=1;
+ lastticcount = Wasabi::Std::getTickCount();
+ setTimer(TIMER_SCROLL, TIMER_SPEED);
+}
+
+void ComponentBucket2::stopScrollTimer() {
+ if (!timerset) return;
+ killTimer(TIMER_SCROLL);
+ timerset=0;
+}
+
+void ComponentBucket2::setText(const wchar_t *t)
+{
+ for (int i=0;i<txtlist.getNumItems();i++) {
+ if (txtlist.enumItem(i)->getRootParent() == getRootParent()) {
+ txtlist.enumItem(i)->setName(t);
+ txtlist.enumItem(i)->invalidate();
+ }
+ }
+}
+
+void ComponentBucket2::setText(ifc_window *cb , const wchar_t *txt) {
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (static_cast<ifc_window *>(cblist.enumItem(i)) == cb)
+ cblist.enumItem(i)->setText(txt);
+ }
+}
+
+void ComponentBucket2::registerText(Text *t, const wchar_t *id)
+{
+ ComponentBucket2 *cb = getComponentBucket(id);
+ if (cb) {
+ cb->doRegisterText(t);
+ return;
+ }
+ ifc_window *p = t->getDesktopParent();
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist.enumItem(i)->getDesktopParent() == p)
+ cblist.enumItem(i)->doRegisterText(t);
+ }
+}
+
+void ComponentBucket2::unRegisterText(Text *t, const wchar_t *id) {
+ ComponentBucket2 *cb = getComponentBucket(id);
+ if (cb) {
+ cb->doUnregisterText(t);
+ return;
+ }
+ ifc_window *p = t->getDesktopParent();
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist.enumItem(i)->getDesktopParent() == p)
+ cblist.enumItem(i)->doUnregisterText(t);
+ }
+}
+
+ComponentBucket2 *ComponentBucket2::getComponentBucket(const wchar_t *cb) {
+ if (!cb) return NULL;
+ for (int i=0;i<cblist.getNumItems();i++) {
+ if (cblist.enumItem(i)->getGuiObject()->guiobject_getId()
+ && !WCSICMP(cblist.enumItem(i)->getGuiObject()->guiobject_getId(), cb))
+ return cblist.enumItem(i);
+ }
+ return NULL;
+}
+
+void ComponentBucket2::setLMargin(int i) {
+ lmargin = i;
+ invalidate();
+}
+
+void ComponentBucket2::setRMargin(int i) {
+ rmargin = i;
+ invalidate();
+}
+
+void ComponentBucket2::setSpacing(int i) {
+ spacing = i;
+ invalidate();
+}
+
+int ComponentBucket2::getLMargin(void) {
+ return lmargin;
+}
+
+int ComponentBucket2::getRMargin(void) {
+ return rmargin;
+}
+
+int ComponentBucket2::getSpacing(void) {
+ return spacing;
+}
+
+void ComponentBucket2::load() {
+ WindowCreateByTypeEnum wce(wndtype);
+ svc_windowCreate *obj;
+ while ((obj = wce.getNext()) != NULL) {
+ addItems(obj);
+ }
+ if (isPostOnInit())
+ onResize();
+}
+
+void ComponentBucket2::doRegisterText(Text *t) {
+ txtlist.addItem(t);
+}
+
+void ComponentBucket2::doUnregisterText(Text *t) {
+ txtlist.delItem(t);
+}
+
+
+void ComponentBucket2::addItems(svc_windowCreate *svc) {
+
+ for (int i = 0; ; i++) {
+ ASSERTPR(i < 1336, "someone is lame-o");
+ ServiceWndHolder *svcwnd = new ServiceWndHolder;
+ ifc_window *wnd = svc->createWindowOfType(wndtype, svcwnd, i);
+ if (wnd == NULL) {
+ delete svcwnd;
+ if (i==0) SvcEnum::release(svc);
+ break;
+ }
+ svcwnd->setChild(wnd, svc);
+ myclients.addItem(svcwnd);
+ svcwnd->setStartHidden(1);
+ svcwnd->init(this);
+ }
+}
+
+int ComponentBucket2::getMaxWidth() {
+ if (!vertical) {
+ int p = getLMargin();
+
+ for (int j=0;j<myclients.getNumItems();j++) {
+ //CUT for (int i=0;i<myclients.enumItem(j)->wnds.getNumItems();i++) {
+ RECT r;
+ myclients[j]->getClientRect(&r);
+ p+=(r.right-r.left)+getSpacing();
+ //CUT }
+ }
+
+ return p+getRMargin();
+ }
+ RECT r;
+ getClientRect(&r);
+ return r.right-r.left;
+}
+
+int ComponentBucket2::getMaxHeight() {
+ if (vertical) {
+ int p = getLMargin();
+
+ for (int j=0;j<myclients.getNumItems();j++) {
+ //CUT for (int i=0;i<myclients.enumItem(j)->wnds.getNumItems();i++) {
+ RECT r;
+ myclients[j]->getClientRect(&r);
+ p+=(r.bottom-r.top)+getSpacing();
+ //CUT }
+ }
+
+ return p+getLMargin();
+ }
+ RECT r;
+ getClientRect(&r);
+ return r.right-r.left;
+}
+
+int ComponentBucket2::onResize() {
+ COMPONENTBUCKET2_PARENT::onResize();
+
+ RECT r;
+ getClientRect(&r);
+
+ int sh;
+ int myh;
+ if (!vertical) {
+ sh = r.bottom - r.top;
+ } else {
+ sh = r.right - r.left;
+ }
+ myh = sh;
+
+
+ int p = getLMargin() - xscroll;
+
+ for (int j=0;j<myclients.getNumItems();j++) {
+//CUT for (int i=0;i<myclients.enumItem(j)->wnds.getNumItems();i++) {
+//CUT api_window *c = myclients.enumItem(j)->wnds.enumItem(i);
+ifc_window *c = myclients[j];
+ int w = c->getPreferences(SUGGESTED_W);
+ int h = c->getPreferences(SUGGESTED_H);
+
+ if (!vertical) {
+ float rt = (float)myh / (float)h;
+ if (ABS(rt-1.0f) > 0.1) {
+ w = (int)((float)w*rt);
+ h = (int)((float)h*rt);
+ }
+ } else {
+ float rt = (float)myh / (float)w;
+ if (ABS(rt-1.0f) > 0.1) {
+ w = (int)((float)w*rt);
+ h = (int)((float)h*rt);
+ }
+ }
+
+ if (!vertical)
+ c->resize(p+r.left, r.top+(sh - h) / 2, w, h);
+ else
+ c->resize(r.left+(sh - w) / 2, p+r.top, w, h);
+
+ if (!vertical)
+ p+=w+getSpacing();
+ else
+ p+=h+getSpacing();
+
+ if (!c->isVisible()) c->setVisible(1);
+//CUT }
+ }
+
+ return 1;
+}
+
+void ComponentBucket2::setVertical(int v) {
+ if (v == vertical) return;
+ vertical = v;
+ if (isInited()) invalidate();
+}
+
+int ComponentBucket2::getNumChildren() {
+ return myclients.getNumItems();
+}
+
+GuiObject *ComponentBucket2::enumChildren(int i) {
+ ServiceWndHolder *w = myclients.enumItem(i);
+ if (!w) return NULL;
+ ifc_window *_w = w->rootwndholder_getRootWnd();
+ if (!_w) return NULL;
+ return _w->getGuiObject();
+}
+
+PtrList<ComponentBucket2> ComponentBucket2::cblist;
+
+CompBucketScriptController _cbucketController;
+CompBucketScriptController *cbucketController = &_cbucketController;
+
+
+// -- Functions table -------------------------------------
+function_descriptor_struct CompBucketScriptController ::exportedFunction[] = {
+ {L"getMaxWidth", 0, (void*)ComponentBucket2::script_vcpu_getMaxWidth},
+ {L"getMaxHeight", 0, (void*)ComponentBucket2::script_vcpu_getMaxHeight},
+ {L"getScroll", 0, (void*)ComponentBucket2::script_vcpu_getScroll},
+ {L"setScroll", 1, (void*)ComponentBucket2::script_vcpu_setScroll},
+ {L"getNumChildren", 0, (void*)ComponentBucket2::script_vcpu_getNumChildren},
+ {L"enumChildren", 1, (void*)ComponentBucket2::script_vcpu_enumChildren},
+ {L"fake", 0, (void*)ComponentBucket2::script_vcpu_fake },
+};
+
+const wchar_t *CompBucketScriptController ::getClassName() {
+ return L"ComponentBucket";
+}
+
+const wchar_t *CompBucketScriptController ::getAncestorClassName() {
+ return L"GuiObject";
+}
+
+ScriptObject *CompBucketScriptController::instantiate() {
+ ComponentBucket2 *cb = new ComponentBucket2;
+ ASSERT(cb != NULL);
+ return cb->getScriptObject();
+}
+
+void CompBucketScriptController::destroy(ScriptObject *o) {
+ ComponentBucket2 *cb = static_cast<ComponentBucket2 *>(o->vcpu_getInterface(cbucketGuid));
+ ASSERT(cb != NULL);
+ delete cb;
+}
+
+void *CompBucketScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for componentbucket yet
+}
+
+void CompBucketScriptController::deencapsulate(void *o) {
+}
+
+int CompBucketScriptController ::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *CompBucketScriptController ::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID CompBucketScriptController ::getClassGuid() {
+ return cbucketGuid;
+}
+
+scriptVar ComponentBucket2::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ComponentBucket2::script_vcpu_getMaxWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid));
+ if (cb) return MAKE_SCRIPT_INT(cb->getMaxWidth());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar ComponentBucket2::script_vcpu_getMaxHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid));
+ if (cb) return MAKE_SCRIPT_INT(cb->getMaxHeight());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar ComponentBucket2::script_vcpu_getScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid));
+ if (cb) return MAKE_SCRIPT_INT(cb->getScroll());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar ComponentBucket2::script_vcpu_setScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid));
+ if (cb) cb->setScroll(GET_SCRIPT_INT(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ComponentBucket2::script_vcpu_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid));
+ if (cb) return MAKE_SCRIPT_INT(cb->getNumChildren());
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ComponentBucket2::script_vcpu_enumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
+ SCRIPT_FUNCTION_INIT
+ ComponentBucket2 *cb = static_cast<ComponentBucket2*>(o->vcpu_getInterface(cbucketGuid));
+ if (cb) {
+ GuiObject *o = cb->enumChildren(GET_SCRIPT_INT(v));
+ if (o) return MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject());
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/compbuck2.h b/Src/Wasabi/api/skin/widgets/compbuck2.h
new file mode 100644
index 00000000..e08c8aa0
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/compbuck2.h
@@ -0,0 +1,156 @@
+//PORTABLE
+#ifndef _COMPBUCK_H
+#define _COMPBUCK_H
+
+#include <api/wnd/wndclass/clickwnd.h>
+#include <api/skin/widgets/text.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/service/svc_enum.h>
+#include <api/script/objects/guiobj.h>
+#include <api/service/svcs/svc_wndcreate.h>
+
+// {97AA3E4D-F4D0-4fa8-817B-0AF22A454983}
+static const GUID cbucketGuid =
+{ 0x97aa3e4d, 0xf4d0, 0x4fa8, { 0x81, 0x7b, 0xa, 0xf2, 0x2a, 0x45, 0x49, 0x83 } };
+
+#define COMPONENTBUCKET2_PARENT GuiObjectWnd
+#define COMPONENTBUCKET2_XMLPARENT GuiObjectWnd
+
+class CompBucketScriptController: public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern CompBucketScriptController *cbucketController;
+
+class Layout;
+
+class ServiceWndHolder;
+
+class ComponentBucket2 : public COMPONENTBUCKET2_PARENT {
+public:
+ ComponentBucket2();
+ virtual ~ComponentBucket2();
+
+ virtual int onInit();
+ virtual int setXuiParam(int _xuihandle, int id, const wchar_t *name, const wchar_t *strval);
+
+/* virtual int getAutoHeight();
+ virtual int getAutoWidth();*/
+
+ virtual void timerCallback(int id);
+ virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2);
+
+ virtual int onResize();
+ virtual void setLMargin(int i);
+ virtual void setRMargin(int i);
+ virtual void setSpacing(int i);
+ virtual int getLMargin(void);
+ virtual int getRMargin(void);
+ virtual int getSpacing(void);
+
+ void next_page();
+ void prev_page();
+ void next_down();
+ void next_up();
+ void prev_down();
+ void prev_up();
+ static void next_down(Group *l); // next_down on all compbucks in this group
+ static void next_up(Group *l); // next_up on all compbucks in this group
+ static void prev_down(Group *l); // prev_down on all compbucks in this group
+ static void prev_up(Group *l); // prev_up on all compbucks in this group
+ static void prev_page(Group *l); // prev_down on all compbucks in this group
+ static void next_page(Group *l); // prev_up on all compbucks in this group
+
+ void setText(const wchar_t *txt);
+ static void setText(ifc_window *cb , const wchar_t *txt); // set this text for this compbuck's rootwnd
+
+ static void registerText(Text *t, const wchar_t *id=NULL); // id=NULL => register for all compbucks in this group
+ static void unRegisterText(Text *t, const wchar_t *id=NULL); // id=NULL => unregister for all compbucks in this group
+
+ static ComponentBucket2 *getComponentBucket(const wchar_t *cb);
+
+ int getMaxWidth();
+ int getMaxHeight();
+ void setVertical(int v);
+ void setScroll(int v);
+ int getScroll();
+ int getNumChildren();
+ GuiObject *enumChildren(int i);
+
+protected:
+/*static */void CreateXMLParameters(int master_handle);
+ enum {
+ COMPBUCK_LEFTMARGIN=0,
+ COMPBUCK_RIGHTMARGIN,
+ COMPBUCK_SPACING,
+ COMPBUCK_VERTICAL,
+ COMPBUCK_WNDTYPE,
+ };
+
+private:
+
+ void load();
+ void addItems(svc_windowCreate *wc);
+ void doRegisterText(Text *t);
+ void doUnregisterText(Text *t);
+
+ int timeron;
+ static PtrList<ComponentBucket2> cblist;
+ PtrList<Text> txtlist;
+ StringW id;
+ PtrList<ServiceWndHolder> myclients;
+ int lmargin;
+ int rmargin;
+ int spacing;
+
+ int xscroll;
+ int direction;
+ int timerset;
+
+ void startScrollTimer();
+ void stopScrollTimer();
+ uint32_t lastticcount;
+ int vertical;
+ int xuihandle;
+ static XMLParamPair params[];
+ StringW wndtype;
+
+ uint32_t scrollpage_starttime;
+ int scrollpage_timerset;
+ int scrollpage_start;
+ int scrollpage_target;
+ int scrollpage_speed;
+
+public:
+
+ static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getMaxWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getMaxHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setScroll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_enumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+};
+
+extern const wchar_t componentBucketXuiObjectStr[];
+extern char componentBucketXuiSvcName[];
+class ComponentBucketXuiSvc : public XuiObjectSvc<ComponentBucket2, componentBucketXuiObjectStr, componentBucketXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/customobject.cpp b/Src/Wasabi/api/skin/widgets/customobject.cpp
new file mode 100644
index 00000000..bfe0066f
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/customobject.cpp
@@ -0,0 +1,8 @@
+#include <precomp.h>
+#include "customobject.h"
+
+#define CBCLASS CustomObjectI
+START_DISPATCH;
+ VCB(CUSTOMOBJECT_SETROOTWND, customobject_setRootWnd);
+END_DISPATCH;
+
diff --git a/Src/Wasabi/api/skin/widgets/customobject.h b/Src/Wasabi/api/skin/widgets/customobject.h
new file mode 100644
index 00000000..5cd6a3f3
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/customobject.h
@@ -0,0 +1,78 @@
+#ifndef __CUSTOMOBJECT_H
+#define __CUSTOMOBJECT_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+class ifc_window;
+
+// {F5527A4F-C910-48c2-A80B-98A60D317F35}
+const GUID customObjectGuid =
+{ 0xf5527a4f, 0xc910, 0x48c2, { 0xa8, 0xb, 0x98, 0xa6, 0xd, 0x31, 0x7f, 0x35 } };
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class CustomObject : public Dispatchable {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void customobject_setRootWnd(ifc_window *w);
+
+ enum {
+ CUSTOMOBJECT_SETROOTWND=10,
+ CUSTOMOBJECT_GETROOTWND=20,
+ };
+};
+
+inline void CustomObject::customobject_setRootWnd(ifc_window *w) {
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ _voidcall(CUSTOMOBJECT_SETROOTWND, w);
+}
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class CustomObjectI : public CustomObject {
+public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void customobject_setRootWnd(ifc_window *w)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp b/Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp
new file mode 100644
index 00000000..513d8c44
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp
@@ -0,0 +1,406 @@
+#include <precomp.h>
+#include "autofilterlist.h"
+#include <api/db/subqueryserver.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/objects/c_script/h_button.h>
+#include <api/wnd/popup.h>
+#include <bfc/file/filename.h>
+
+#define TIMER_SCANNERDEL 0x6891
+
+class ButtHooker : public H_Button {
+public:
+ ButtHooker(AutoFilterList *hangout, ScriptObject *butt) : afl(hangout), H_Button(butt) { }
+ void hook_onLeftClick() {
+ afl->doFieldPopup();
+ }
+
+private:
+ AutoFilterList *afl;
+};
+
+FilterListItem::FilterListItem(void *_data, int _datalen, int _datatype) {
+ data_len = _datalen;
+ data_type = _datatype;
+ data.setSize(data_len+1);
+ MEMCPY(data.getMemory(), _data, data_len);
+}
+
+AutoFilterList::AutoFilterList() {
+ showColumnsHeaders = FALSE;
+ local_scanner = NULL;
+ order = -1;
+ viscount = 0;
+ grab_playstrings = 0;
+ linked = 1;
+ hooker = NULL;
+ needrestart = 0;
+ querydirection = SetQuery::FORWARD;
+ last_populate_flag = -1;
+ setContent("wasabi.buttonbar.stack");
+ fn = NULL;
+ data_type = NULL;
+}
+
+AutoFilterList::~AutoFilterList() {
+ delete local_scanner;
+ delete hooker;
+}
+
+int AutoFilterList::onInit() {
+ AUTOFILTERLIST_PARENT::onInit();
+ //scannerserver_newScanner();
+
+ return 1;
+}
+
+void AutoFilterList::scannerserver_onNewScanner(SharedDbScannerI *scanner) {
+ AUTOFILTERLIST_DBPARENTSRV::scannerserver_onNewScanner(scanner);
+ delete local_scanner;
+ local_scanner = new dbScanner(scannerserver_getTable());
+ local_scanner->setQuery(sqs_getQuery());
+}
+
+void AutoFilterList::mqc_onNewMultiQuery(SubQueryServer *modifier, int flag) {
+ AUTOFILTERLIST_DBPARENTCLIENT::mqc_onNewMultiQuery(modifier);
+ if (!isInited()) return;
+ if (modifier == this && !needrestart) return;
+ if (local_scanner == NULL) return;
+ int id = sqs_getCooperativeId();
+ int need_reset = (modifier == NULL || needrestart);
+ if (!need_reset) switch (flag) {//glag!
+ default:
+ case SetQuery::FORWARD:
+ need_reset = (id >= modifier->sqs_getCooperativeId());
+ break;
+ case SetQuery::REVERSE:
+ need_reset = (id <= modifier->sqs_getCooperativeId());
+ break;
+ case SetQuery::GLOBAL:
+ need_reset = (id != modifier->sqs_getCooperativeId());
+ break;
+ }
+
+ if (need_reset) {
+ needrestart = 0;
+
+ last_populate_flag = flag;
+
+ int optimized = sqs_getMultiQueryServer() && sqs_getMultiQueryServer()->mqs_isQueryEmpty();
+
+ uniques.deleteAll();
+ deleteAllItems();
+
+ const char *allstr = getAllString();
+ FilterListItem *fli = new FilterListItem((void *)allstr, STRLEN(allstr)+1, MDT_STRINGZ);
+ insertItem(0, NULL, reinterpret_cast<LPARAM>(fli));
+ setSelected(0, 1);
+
+ SharedDbScannerI *shs = scannerserver_getScanner();
+ if (shs != NULL) {
+ dbSvcScanner *sc = shs->getScanner();
+ if (sc != NULL) sc->cancelQuery();
+ }
+ dbSvcScanner *lc= local_scanner->getScanner();
+ if (lc != NULL) lc->cancelQuery();
+
+ if (optimized) {
+ grab_playstrings = 0;
+ setRedraw(0);
+ dbScanner *unique_scanner = new dbScanner(sqs_getTable(), field);
+ while (!unique_scanner->eof()) {
+ char data[4096]="";
+ unique_scanner->getData("Value", data, 4095, MDT_STRINGZ);
+ data[4095]=0;
+ insertData(data, STRLEN(data)+1, MDT_STRINGZ);
+ unique_scanner->next();
+ }
+ setRedraw(1);
+ delete unique_scanner;
+ } else {
+ grab_playstrings = 1;
+ lc->cancelQuery();
+ }
+
+ return;
+ }
+}
+
+void AutoFilterList::mqc_onCompleteMultiQuery() {
+ grab_playstrings = 0;
+}
+
+void AutoFilterList::mqc_onAddPlaystring(const char *playstring, int nitems, int thispos) {
+ AUTOFILTERLIST_DBPARENTCLIENT::mqc_onAddPlaystring(playstring, nitems, thispos);
+ if (grab_playstrings)
+ filterEntry(playstring, local_scanner, field);
+}
+
+void AutoFilterList::setMetadataField(const char *_field) {
+ if (!field.isempty() && STRCASEEQL(field, _field)) return;
+ field = _field;
+ delColumnByPos(0);
+ addColumn(field, 100);
+ data_type = api->metadb_getMetaDataType(field);
+ sqs_setTable(api->metadb_getMetaDataTable(field));
+ if (isPostOnInit())
+ setLabelName();
+ sqs_setQuery("");
+ needrestart = 1;
+ scannerserver_newScanner();
+}
+
+int AutoFilterList::onResize() {
+ AUTOFILTERLIST_PARENT::onResize();
+ RECT r = clientRect();
+ ListColumn *c = enumListColumn(0);
+ if (!c) return 1;
+ c->setWidth(r.right-r.left-4);
+ recalcHeaders();
+
+ return 1;
+}
+
+void AutoFilterList::getClientRect(RECT *r) {
+ AUTOFILTERLIST_PARENT::getClientRect(r);
+ api_window *rw = getContentRootWnd();
+ if (rw) r->top += rw->getPreferences(SUGGESTED_H);
+// else r->top += 16;
+}
+
+void AutoFilterList::rootwndholder_getRect(RECT *r) {
+ getClientRect(r);
+ r->bottom = r->top;
+ api_window *rw = getContentRootWnd();
+ if (rw) r->top -= rw->getPreferences(SUGGESTED_H);
+// else r->top += 16;
+}
+
+void AutoFilterList::onNewContent() {
+ setLabelName();
+ // hook the clicks
+ delete hooker;
+ ScriptObject *mousetrap = findScriptObject("mousetrap");
+ hooker = new ButtHooker(this, mousetrap);
+}
+
+int AutoFilterList::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) {
+ COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam);
+ COLORREF fgcolor = getTextColor(lParam);
+
+ RECT box;
+ canvas->getClipBox(&box);
+
+ if (!getBgBitmap()) {
+ RECT r2 = *r;
+ r2.left = box.left;
+ new RegionI reg(&r2);
+ canvas->selectClipRgn(&reg);
+ canvas->fillRect(r, getBgColor());
+ }
+
+ canvas->setTextColor(fgcolor);
+
+ if (isselected) {
+ RECT mr = *r;
+ canvas->fillRect(&mr, bgcolor);
+ }
+
+ if (isfocused)
+ canvas->drawRect(r, 0, getFocusColor(lParam));
+
+ canvas->pushTextSize(getFontSize());
+
+ int x = 1+r->left;
+ for (int i = 0; i < getNumColumns(); i++) {
+ RECT ir;
+ ir.left = x;
+ ir.right = x + getColumnWidth(i);
+ ir.top = r->top;
+ ir.bottom = r->bottom;
+ if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) {
+ FilterListItem *fli = reinterpret_cast<FilterListItem *>(lParam);
+ api->metadb_renderData(canvas, ir, (void *)fli->getData(), fli->getDatatype(), 0);
+ }
+ x = ir.right;
+ }
+ canvas->popTextSize();
+ return 1;
+}
+
+void AutoFilterList::filterEntry(const char *playstring, dbScanner *scanner, const char *field) {
+ dbSvcScanner *sp = scanner->getScanner();
+ if (sp != NULL) sp->push();
+ scanner->setIndexName(MT_PLAYSTRING);
+ scanner->setIndexValue(playstring);
+ scanner->first();
+
+ if (scanner->eof()) return;
+
+ char data[4096]="";
+ scanner->getData((char *)field, data, 4095, data_type);
+ data[4095]=0;
+
+ sp->pop();
+
+ switch (data_type) {
+ case MDT_INT:
+ case MDT_TIME:
+ case MDT_BOOLEAN:
+ case MDT_TIMESTAMP:
+ filterInt(*(int *)data);
+ break;
+ case MDT_STRINGZ:
+ filterString((const char *)data);
+ break;
+ }
+}
+
+void AutoFilterList::filterInt(int data) {
+ int pos=0;
+ if (uniques.findItem((const char *)&data, &pos)) return;
+ insertData(&data, 4, data_type);
+}
+
+void AutoFilterList::insertData(void *data, int len, int type) {
+ int pos=0;
+ FilterListItem *fli = new FilterListItem(data, len, type);
+ uniques.addItem(fli);
+ pos = uniques.searchItem(fli);
+ insertItem(pos+1/*+1 for item ALL at the top*/, NULL, reinterpret_cast<LPARAM>(fli));
+}
+
+void AutoFilterList::filterString(const char *data) {
+ if (!data || !*data) return;
+ int pos=0;
+ if (uniques.findItem(data, &pos)) return;
+ insertData((void *)data, STRLEN(data)+1, data_type);
+}
+
+void AutoFilterList::onLeftClick(int itemnum) {
+
+ if (itemnum == 0 && last_populate_flag != lastflag) {
+ needrestart = 1;
+ }
+ String query;
+ if (itemnum > 0) {
+ for (int i=0;i<getNumItems();i++) {
+ if (getItemSelected(i)) {
+ if (!query.isempty())
+ query += " || ";
+ query += field;
+ query += " == ";
+ FilterListItem *fli = reinterpret_cast<FilterListItem *>(getItemData(i));
+ switch (fli->getDatatype()) {
+ case MDT_INT:
+ case MDT_TIME:
+ case MDT_BOOLEAN:
+ case MDT_TIMESTAMP:
+ query += StringPrintf("%d", *(int *)fli->getData());
+ break;
+ case MDT_STRINGZ:
+ query += "\"";
+ query += fli->getData();
+ query += "\"";
+ break;
+ }
+ }
+ }
+ }
+ sqs_setQuery(query, querydirection);
+ if (local_scanner != NULL) local_scanner->setQuery(query);
+}
+
+void AutoFilterList::onDoubleClick(int itemnum) {
+ int sav = querydirection;
+ querydirection = SetQuery::GLOBAL;
+ onLeftClick(itemnum);
+ querydirection = sav;
+}
+
+void AutoFilterList::sqs_onAttachServer(MultiQueryServer *s) {
+ s->mqs_registerClient(this);
+}
+
+void AutoFilterList::sqs_onDetachServer(MultiQueryServer *s) {
+ s->mqs_unregisterClient(this);
+}
+
+void AutoFilterList::sqs_reset() {
+ postDeferredCallback(7873, 3245);
+}
+
+int AutoFilterList::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == 7873 && p2 == 3245) {
+ deselectAll();
+ setItemFocused(0);
+ setSelected(0, TRUE);
+ needrestart=1; last_populate_flag = -1;
+ onLeftClick(0);
+ ensureItemVisible(0);
+ return 1;
+ }
+ return AUTOFILTERLIST_PARENT::onDeferredCallback(p1, p2);
+}
+
+void AutoFilterList::setLabelName() {
+ ScriptObject *tx = findScriptObject("buttonbar.text");
+ if (tx == NULL) return;
+ C_Text(tx).setText(field);
+}
+
+void AutoFilterList::setQueryDirection(int glag) {
+ querydirection = glag;
+}
+
+void AutoFilterList::doFieldPopup() {
+ PopupMenu popup;
+ dbSvcScanner *scanner = api->metadb_newScanner(sqs_getTable());
+ if (scanner == NULL) return;
+ int n = scanner->getNumCols();
+ PtrListQuickSorted<String, StringComparator> fields;
+ for (int i = 0; i < n; i++) {
+ dbSvcColInfo *info = scanner->enumCol(i);
+ if (!info->uniques_indexed) continue;
+ fields.addItem(new String(info->name));
+ }
+ fields.sort();
+ foreach(fields)
+ const char *name = fields.getfor()->getValue();
+ int checked = STRCASEEQLSAFE(name, field);
+ popup.addCommand(name, foreach_index, checked);
+ endfor
+ RECT cr = clientRect();
+ clientToScreen((int *)&cr.left, (int *)&cr.top);
+ int r = popup.popAtXY(cr.left, cr.top);
+ if (r >= 0) {
+ const char *col = fields.enumItem(r)->getValue();
+ dbSvcColInfo *info = scanner->getColByName(col);
+ setMetadataField(info->name);
+ }
+ fields.deleteAll();
+ api->metadb_deleteScanner(scanner);
+}
+
+void AutoFilterList::onVScrollToggle(BOOL set) {
+ AUTOFILTERLIST_PARENT::onVScrollToggle(set);
+ if (getContentRootWnd() && isPostOnInit())
+ onResize();
+}
+
+int AutoFilterList::onBeginDrag(int iItem) {
+ String query;
+ FilterListItem *fli = reinterpret_cast<FilterListItem *>(getItemData(iItem));
+ if (fli == NULL) return 0; // BU added in response to talkback data we'll see if it helps
+ String val = (fli->getDatatype() == MDT_STRINGZ) ? fli->getData() : StringPrintf(*(int *)fli->getData()).getValue();
+ fn = new FilenameI(StringPrintf("query://%s;\"%s\" == \"%s\"", StringPrintf(scannerserver_getTable()).getValue(), field.getValue(), val.getValue()));
+ addDragItem(Filename::dragitem_getDatatype(), static_cast<Filename*>(fn));
+ handleDrag();
+ return 1;
+}
+
+int AutoFilterList::dragComplete(int success) {
+ delete fn; fn = NULL;
+ return 1;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/db/autofilterlist.h b/Src/Wasabi/api/skin/widgets/db/autofilterlist.h
new file mode 100644
index 00000000..df998465
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/autofilterlist.h
@@ -0,0 +1,447 @@
+#ifndef __AUTOFILTERLIST_H
+#define __AUTOFILTERLIST_H
+
+#include "../std.h"
+#include "listwnd.h"
+#include "../db/scanner.h"
+#include "../timeslicer.h"
+#include "../db/subqueryserver.h"
+#include "../db/multiqueryclient.h"
+#include "autoquerylist.h"
+
+/**
+ A filter list item is a data item of any type or
+ size to put on a FilterList. The type and size are accessible
+ for memory management purposes.
+
+ @short Items for FilterLists
+ @author Nullsoft
+ @ver 1.0
+ @see FilterListItemSort, MultiQueryServer
+*/
+class FilterListItem {
+ public:
+
+ /**
+ Allocates memory for copying a data
+ object, and then copies the object into newly allocated memory.
+
+ @see MemBlock
+ @see VoidMemblock
+ @param _data Pointer to a data object
+ @param _datalen Length of data object
+ @param _datatype Type of data object
+ */
+ FilterListItem(void *_data, int _datalen, int _datatype);
+
+ /**
+ Does nothing.
+ */
+ virtual ~FilterListItem() { }
+
+ /**
+ Get the data associated with the filter
+ list item.
+
+ @see getDatatype()
+ @see getDataLen()
+ @ret A pointer to the data.
+ */
+ const char *getData() { return data.getMemory(); }
+
+ /**
+ Get the type of the data associated with the
+ filter list item.
+
+ @see getData()
+ @see getDataLen()
+ @see metatags.h
+ @ret Data type of item.
+ */
+ int getDatatype() { return data_type; }
+
+ /**
+ Get the length of the data (in bytes).
+
+ @see getDatatype()
+ @see getData()
+ @ret Length of data (in bytes).
+ */
+ int getDataLen() { return data_len; }
+
+ private:
+
+ MemBlock<char> data;
+ int data_type;
+ int data_len;
+};
+
+/**
+ Provides methods for sorting a FilterList.
+
+ @short FilterList sorting.
+ @author Nullsoft
+ @ver 1.0
+ @see FilterListItem
+*/
+class FilterListItemSort {
+ public:
+ /**
+ Determines the data types of two objects and
+ calls an appropriate comparison function to compare them.
+
+ @assert The two objects to be compared have the same data type.
+ @see compareAttrib()
+ @ret -1, _p1 < _p2; 0, _p1 = _p2; 1, _p1 > _p2
+ @param _p1 Object to compare
+ @param _p2 Object to compare
+ */
+ static int compareItem(void *_p1, void *_p2) {
+ FilterListItem *p1 = ((FilterListItem *)_p1);
+ FilterListItem *p2 = ((FilterListItem *)_p2);
+ ASSERT(p1->getDatatype() == p2->getDatatype());
+ switch (p1->getDatatype()) {
+ case MDT_INT:
+ case MDT_TIME:
+ case MDT_BOOLEAN:
+ case MDT_TIMESTAMP: {
+ int a = *(int *)p1->getData();
+ int b = *(int *)p2->getData();
+ if (a < b) return -1;
+ if (a > b) return 1;
+ return 0; }
+ case MDT_STRINGZ:
+ return STRICMP(p1->getData(), p2->getData());
+ }
+ return 0;
+ }
+
+ /**
+ Compares the value of an item to an attribute string,
+ or to the value of the attribute string cast to an
+ appropriate data type.
+
+ @see compareItem()
+ @ret -1, _p1 < _p2; 0, _p1 = _p2; 1, _p1 > _p2
+ @param attrib
+ @param _item
+ */
+ static int compareAttrib(const wchar_t *attrib, void *_item) {
+ FilterListItem *item = ((FilterListItem *)_item);
+ switch (item->getDatatype()) {
+ case MDT_INT:
+ case MDT_TIME:
+ case MDT_BOOLEAN:
+ case MDT_TIMESTAMP: {
+ int a = *(int *)attrib;
+ int b = *(int *)item->getData();
+ if (a < b) return -1;
+ if (a > b) return 1;
+ return 0; }
+ case MDT_STRINGZ:
+ return STRICMP(attrib, item->getData());
+ }
+ return 0;
+ }
+};
+
+class ButtHooker;
+class FilenameI;
+
+#define AUTOFILTERLIST_PARENT ListWnd
+#define AUTOFILTERLIST_DBPARENTSRV SubQueryServerI
+#define AUTOFILTERLIST_DBPARENTCLIENT MultiQueryClientI
+
+/**
+ A list of items to filter on.
+
+ @short A list of items to filter on.
+ @author Nullsoft
+ @ver 1.0
+ @see FilterListItemSort
+ @see FilterListItem
+*/
+class AutoFilterList : public AUTOFILTERLIST_PARENT,
+ public AUTOFILTERLIST_DBPARENTSRV,
+ public AUTOFILTERLIST_DBPARENTCLIENT {
+ public:
+
+ /**
+ Creates an empty filter list with a NULL local scanner.
+
+ @see ~AutoFilterList()
+ */
+ AutoFilterList();
+
+ /**
+ Deletes the local scanner.
+
+ @see AutoFilterList()
+ */
+ virtual ~AutoFilterList();
+
+ /**
+ Sets the field name and sets the scanner to NULL.
+
+ @param field The name of the field.
+ */
+ void setMetadataField(const char *field);
+
+ /**
+ Creates and populates the list.
+
+ @ret 1
+ */
+ virtual int onInit();
+
+ /**
+ Prepares a window for repainting in a new size.
+
+ @ret 1
+ */
+ virtual int onResize();
+
+ virtual void getClientRect(RECT *);
+ virtual void rootwndholder_getRect(RECT *r);
+ virtual void onNewContent();
+
+ /**
+ Displays a window in a specified position and state.
+
+ @ret 1
+ @param canvas
+ @param pos
+ @param r
+ @param lParam
+ @param isselected
+ @param isfocused
+ */
+ virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused);
+
+ /**
+ Event is triggered when the user clicks (with the left mouse
+ button) on an item in the auto filter list.
+
+ @param itemnum The number of the item that was clicked.
+ */
+ virtual void onLeftClick(int itemnum);
+
+ /**
+ Event is triggered when the user double-clicks (with the left mouse
+ button) on an item in the auto filter list.
+
+ @param itemnum The number of the item that was double-clicked.
+ */
+ virtual void onDoubleClick(int itemnum); // double-click on an item
+
+ /**
+ Gets the dependency pointer.
+
+ @ret The dependency pointer.
+ */
+ virtual api_dependent *timeslicer_getDependencyPtr() { return rootwnd_getDependencyPtr(); }
+
+ /**
+ Returns the proper query string for "all items"
+ present in the list.
+
+ @ret Query string for "all items".
+ */
+ virtual const char *getAllString() { return "All"; }
+
+
+ /**
+ Deletes the current scanner and sets up a new one.
+
+ @param A shared database scanner
+ */
+ virtual void scannerserver_onNewScanner(SharedDbScannerI *scanner);
+
+ /**
+ Makes the necessary preparations for running a new query.
+
+ @see SetQuery
+ @see MultiQueryServer, SubQueryServer
+ @param modifier refers to a SubQueryServer, which implements a simple filter.
+ @param flag The type of query that will be performed.
+ */
+ virtual void mqc_onNewMultiQuery(SubQueryServer *modifier, int flag);
+
+ /**
+ Gets the dependency pointer.
+
+ @see api_dependent
+ @ret Dependency Dependency pointer
+ */
+ virtual api_dependent *mqc_getDependencyPtr() { return rootwnd_getDependencyPtr(); }
+
+ /**
+ Sets the order of the result list.
+ <b>Not currently implemented!</b>
+
+ @param order order desired for the result list.
+ */
+ void setOrder(int n) { order = n; }
+
+ /**
+ Gets the order number.
+
+ @see setOrder()
+ @ret Order number if linked, otherwise -1
+ @param None
+ */
+ virtual int sqs_getCooperativeId() { return linked ? order : -1; }
+
+ /**
+ Event is triggered when a multi query has completed.
+ Has no external effect.
+ */
+ virtual void mqc_onCompleteMultiQuery();
+
+ /**
+ Tests whether to enter a playstring in a filter entry, and does it if
+ necessary.
+
+ @param playstring The playstring being added.
+ @param nitems HELP
+ @param thispos HELP
+ */
+ virtual void mqc_onAddPlaystring(const char *playstring, int nitems, int thispos);
+
+
+ /**
+ Registers a client with a query server.
+
+ @see sqs_onDetachServer()
+ @param s The server we will register to.
+ */
+ virtual void sqs_onAttachServer(MultiQueryServer *s);
+
+ /**
+ Unregisters a client with a query server.
+
+ @see sqs_onAttachServer()
+ @param s The server we will unregister from.
+ */
+ virtual void sqs_onDetachServer(MultiQueryServer *s);
+
+ /**
+ Resets the query.
+ */
+ virtual void sqs_reset();
+
+ /**
+ Generic deferred callback interface.
+ */
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ /**
+ Sets the linking status according to the value v.
+
+ @param v linking status to set
+ */
+ virtual void setLinked(int v) { linked = v; }
+
+ /**
+ Set the direction of the query.
+
+ @see SetQuery
+ @param glag The direction of the query.
+ */
+ void setQueryDirection(int glag);
+
+ /**
+ HELP
+ */
+ void doFieldPopup();
+
+ /**
+ HELP
+ */
+ virtual void onVScrollToggle(BOOL set);
+
+ /**
+ HELP
+ */
+ virtual int wantRenderBaseTexture() { return 1; }
+
+ /**
+ Event is triggered when an item is
+ being dragged.
+
+ @param iItem The item being dragged.
+ @ret 0, Drag not handled; 1, Drag handled;
+ */
+ virtual int onBeginDrag(int iItem);
+
+ /**
+ Gets called when the API thinks the drag and drop
+ was successful.
+
+ @param success Drag and Drop succeeded? (According to API).
+ @ret 0, Drag and Drop not sucessful; 1, Drop and Drop completed successfully;
+ */
+ virtual int dragComplete(int success);
+
+ private:
+ /**
+ HELP
+ */
+ void populate();
+
+ /**
+ Finds a specific entry in the database.
+
+ @param playstring The playstring for the item.
+ @param scanner The db scanner to use.
+ @param field The field to be read.
+ */
+ void filterEntry(const char *playstring, dbScanner *scanner, const char *field);
+
+ /**
+ Filters and formats integer type data
+ and inserts it into the list to be displayed.
+ */
+ void filterInt(int data);
+
+ /**
+ Filters and formats string type data
+ and inserts it into the list to be displayed.
+ */
+ void filterString(const char *data);
+
+ /**
+ Inserts data into the list so that it may be
+ displayed.
+
+ @see metatags.h
+ @param data The data to insert.
+ @param len The length of the data to insert.
+ @param type The type of the data to insert.
+ */
+ void insertData(void *data, int len, int type);
+
+ /**
+ Sets the filter label to the meta data field we are
+ currently sorting on.
+
+ @see filterEntry()
+ */
+ void setLabelName();
+
+ String field;
+ dbScanner *local_scanner;
+ PtrListInsertSorted<FilterListItem, FilterListItemSort> uniques;
+ int data_type;
+ int order;
+ int grab_playstrings;
+ int viscount;
+ int linked;
+ int needrestart;
+ int querydirection;
+ int last_populate_flag;
+ ButtHooker *hooker;
+ FilenameI *fn;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp b/Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp
new file mode 100644
index 00000000..5513cb34
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp
@@ -0,0 +1,111 @@
+#include <precomp.h>
+#include "autoquerylist.h"
+#include <api/db/subqueryserver.h>
+#include <api/db/multiqueryclient.h>
+#include <api/db/sharedscanner.h>
+#include <bfc/string/playstring.h>
+#include <api/db/metatags.h>
+#include <api/wnd/fakedrag.h>
+#include <bfc/util/profiler.h>
+#include <bfc/file/filename.h>
+#include <api/api.h>
+#include <api/service/svcs/svc_droptarget.h>
+#include <api/service/svc_enum.h>
+
+#include "../../pledit/svc_pldir.h"
+#include "../../pledit/playlist.h"
+#include "../../pledit/editor.h"
+
+#define TIMER_SCANNERDEL 0x6879
+#define DC_REFRESH 0x6880
+
+AutoQueryList::AutoQueryList() :
+ playlist(NULL)
+{
+ lastpc = -1;
+ last_status_update = 0;
+ pldir = NULL;
+ nFound = 0;
+}
+
+AutoQueryList::~AutoQueryList() {
+ getGuiObject()->guiobject_removeAppCmds(this);
+ SvcEnum::release(pldir);
+}
+
+int AutoQueryList::onInit() {
+ AUTOQUERYLIST_PARENT::onInit();
+
+ pldir = SvcEnumByGuid<svc_plDir>();
+ if (pldir != NULL) {
+ PlaylistHandle hand = pldir->insertPlaylist(NULL, "Media library query results", NULL, TRUE);
+ pldir->setAutoSave(hand, FALSE);
+ playlist = pldir->getPlaylist(hand);
+ playlist->lock(TRUE);
+ }
+
+ appcmds_addCmd("Reset", 0, AppCmds::SIDE_RIGHT);
+ getGuiObject()->guiobject_addAppCmds(this);
+
+ postDeferredCallback(DC_REFRESH, 0);
+
+ return 1;
+}
+
+int AutoQueryList::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == DC_REFRESH) {
+ mqs_refresh();
+ return 0;
+ }
+ return AUTOQUERYLIST_PARENT::onDeferredCallback(p1, p2);
+}
+
+void AutoQueryList::mqs_onAddPlaystring(const char *playstring, int nitems, int thispos) {
+ nfound++;
+ stdtimevalms now = Std::getTimeStampMS();
+// if (n > lastpc) {
+ if (now - last_status_update > 0.100) {
+ int n = (int)(thispos / (float)nitems * 100.0f);
+ getGuiObject()->guiobject_setCompleted(n);
+ getGuiObject()->guiobject_setStatusText(StringPrintf("%d%c, %d item%s found", n, '%', nfound, (nfound > 1) ? "s" : ""), TRUE);
+// lastpc = n;
+// }
+ last_status_update = now;
+ }
+ if (playlist != NULL)
+ playlist->addPlaylistItem(playstring, Playlist::APPEND, FALSE);
+}
+
+void AutoQueryList::mqs_onCompleteMultiQuery() {
+ getGuiObject()->guiobject_setStatusText(StringPrintf("100%c, %d item%s found", '%', nfound, (nfound > 1) ? "s" : ""), TRUE);
+ lastpc = -1;
+ getGuiObject()->guiobject_popCompleted();
+}
+
+void AutoQueryList::mqs_onNewMultiQuery() {
+ nfound = 0;
+ getGuiObject()->guiobject_setStatusText("0%", TRUE);
+ getGuiObject()->guiobject_pushCompleted();
+ if (playlist != NULL) {
+ playlist->deleteAll();
+
+ GuiObject *ed = getGuiObject()->guiobject_findObjectByInterface(Editor::getInterfaceGuid());
+ if (ed != NULL) {
+ Editor *e = static_cast<Editor*>(ed->guiobject_getRootWnd()->getInterface(Editor::getInterfaceGuid()));
+ e->setPlaylistByHandle(playlist->getHandle());
+ }
+ }
+}
+
+void AutoQueryList::appcmds_onCommand(int id, const RECT *buttonRect, int which_btn) {
+ switch (id) {
+ case 0:
+ resetSubQueries();
+ break;
+ }
+}
+
+void AutoQueryList::onSetVisible(int v) {
+ AUTOQUERYLIST_PARENT::onSetVisible(v);
+ if (!v) mqs_abort();
+}
diff --git a/Src/Wasabi/api/skin/widgets/db/autoquerylist.h b/Src/Wasabi/api/skin/widgets/db/autoquerylist.h
new file mode 100644
index 00000000..2ed7cd55
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/autoquerylist.h
@@ -0,0 +1,109 @@
+#ifndef __AUTOQUERYLIST_H
+#define __AUTOQUERYLIST_H
+
+#include "itemlistwnd.h"
+#include "../db/multiqueryserver.h"
+#include "../ptrlist.h"
+#include "../string.h"
+#include "../timeslicer.h"
+#include "../appcmds.h"
+#include "../../pledit/plhand.h"
+#include "../nakedobject.h"
+
+class svc_plDir;
+class Playlist;
+
+#define AUTOQUERYLIST_PARENT NakedObject
+#define AUTOQUERYLIST_DBPARENTSRV MultiQueryServerI
+
+/**
+ Automates the display of the result set of
+ a query.
+
+ Simply create an AutoQueryList instance,
+ set it's query with setQuery().
+
+ Can send results to the playlist directory
+ for automatic playlist creation based on
+ the result of the query.
+
+ @short Automated query result display window.
+ @author Nullsoft
+ @ver 1.0
+ @see AutoFilterList
+*/
+class AutoQueryList : public AUTOQUERYLIST_PARENT,
+ public AUTOQUERYLIST_DBPARENTSRV, AppCmdsI {
+
+ public:
+ /**
+ Initializes member data.
+ */
+ AutoQueryList();
+
+ /**
+ Releases playlist directory service and removes
+ the AppCmd button.
+ */
+ virtual ~AutoQueryList();
+
+ /**
+ Initializes the auto query list.
+
+ ret 1
+ */
+ virtual int onInit();
+
+ /**
+ Event is triggered when a playstring is added to the result list.
+
+ Updates the progress bar at the bottom of the window (from 0 to 100%).
+
+ @param playstring The playstring to being added to the result list.
+ @param nitems The number of items (total) in the result list.
+ @param thispos The current position in the list of items.
+ */
+ virtual void mqs_onAddPlaystring(const char *playstring, int nitems, int thispos);
+
+ /**
+ Event is triggered when a new query is set.
+
+ Updates the progress bar to 0%, resets the playlist associated
+ with this auto query list and resets the number of items found
+ for the query to zero.
+ */
+ virtual void mqs_onNewMultiQuery();
+
+ /**
+ Event is triggered when a query completes.
+
+ Updates the progress bar to 100% and resets the last
+ known progress count.
+ */
+ virtual void mqs_onCompleteMultiQuery();
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+protected:
+ /**
+ Event is triggered when an AppCmd button (which belongs to this
+ auto query list) is pushed.
+
+ Only one command is handled by the auto query list which causes the query
+ to be reset. The id of the command is 0.
+
+ @param id The id of the command associated with the button that was pressed.
+ @param rect The RECT of the button that was pushed.
+ */
+ virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_btn);
+ virtual void onSetVisible(int v);
+
+private:
+
+ int lastpc;
+ int nfound;
+ Playlist *playlist;
+ svc_plDir *pldir;
+ stdtimevalms last_status_update;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/db/queryline.cpp b/Src/Wasabi/api/skin/widgets/db/queryline.cpp
new file mode 100644
index 00000000..4f844508
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/queryline.cpp
@@ -0,0 +1,32 @@
+#include <precomp.h>
+
+#include "queryline.h"
+
+#include <api/api.h>
+#include <api/db/metatags.h>
+#include <bfc/string/string.h>
+#include <bfc/parse/pathparse.h>
+
+QueryLine::QueryLine(const char *query) : autoquery(FALSE), querytext(query), autofield(MT_NAME) {
+}
+
+void QueryLine::setQuery(const char *query) {
+ querytext = query;
+ String sp = querytext;
+ if (autoquery && !querytext.isempty()) {
+ sp = "";
+ PathParser pp(querytext, " ");
+ if (pp.getNumStrings() <= 0) return;
+ for (int i = 0; i < pp.getNumStrings(); i++) {
+ if (i != 0) sp += " and ";
+ sp += StringPrintf("(\"%s\" has \"%s\")", autofield.getValue(), pp.enumString(i));
+ }
+ }
+ sqs_setQuery(sp);
+}
+
+int QueryLine::setAuto(int bv) {
+ autoquery = !!bv;
+ setQuery(querytext);
+ return 1;
+}
diff --git a/Src/Wasabi/api/skin/widgets/db/queryline.h b/Src/Wasabi/api/skin/widgets/db/queryline.h
new file mode 100644
index 00000000..4743e731
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/queryline.h
@@ -0,0 +1,64 @@
+#ifndef _QUERYLINE_H
+#define _QUERYLINE_H
+
+#include <api/skin/nakedobject.h>
+#include <api/db/subqueryserver.h>
+
+#define QUERYLINE_PARENT NakedObject
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class QueryLine : public QUERYLINE_PARENT, public SubQueryServerI {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ QueryLine(const char *query=NULL);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~QueryLine() { }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void setQuery(const char *query);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int setAuto(int bv);
+
+protected:
+ int autoquery;
+
+private:
+ String querytext, autofield;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp
new file mode 100644
index 00000000..c1981774
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp
@@ -0,0 +1,103 @@
+#include <precomp.h>
+#include "xuiquerydrag.h"
+#include <tataki/canvas/ifc_canvas.h>
+#include <api/db/multiqueryserver.h>
+#include <bfc/file/filename.h>
+
+char QueryDragXuiObjectStr[] = "QueryDrag"; // This is the xml tag
+char QueryDragXuiSvcName[] = "QueryDrag xui object"; // and this is the name of the service
+
+XMLParamPair QueryDrag::params[] = {
+ {QUERYDRAG_SETIMAGE, "image"},
+ {QUERYDRAG_SETSOURCE, "source"},
+ };
+QueryDrag::QueryDrag() {
+ setVirtual(0); // fucko
+ myxuihandle = newXuiHandle();
+
+
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+ fn = NULL;
+}
+
+QueryDrag::~QueryDrag() {
+}
+
+int QueryDrag::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return QUERYDRAG_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case QUERYDRAG_SETIMAGE:
+ setImage(value);
+ break;
+ case QUERYDRAG_SETSOURCE:
+ setSource(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int QueryDrag::onPaint(Canvas *canvas) {
+ QUERYDRAG_PARENT::onPaint(canvas);
+
+ RECT r;
+ getClientRect(&r);
+
+ RenderBaseTexture(canvas, r, 255);
+
+ if (image.getBitmap())
+ image.getBitmap()->stretchToRectAlpha(canvas, &r, getPaintingAlpha());
+
+ return 1;
+}
+
+void QueryDrag::setImage(const char *elementname) {
+ image = elementname;
+ if (isInited()) invalidate();
+}
+
+void QueryDrag::setSource(const char *elementname) {
+ source = elementname;
+}
+
+int QueryDrag::getPreferences(int what) {
+ switch (what) {
+ case SUGGESTED_W:
+ if (image.getBitmap()) return image.getBitmap()->getWidth();
+ case SUGGESTED_H:
+ if (image.getBitmap()) return image.getBitmap()->getHeight();
+ }
+ return QUERYDRAG_PARENT::getPreferences(what);
+}
+
+int QueryDrag::onMouseMove(int x, int y) {
+ QUERYDRAG_PARENT::onMouseMove(x,y);
+ if (isInClick())
+ onBeginDrag();
+ return 1;
+}
+
+void QueryDrag::onBeginDrag() {
+ api_window *mqsw = NULL;
+ if (source.isempty()) mqsw = findWindowByInterface(multiQueryServerGuid);
+ else mqsw = findWindow(source);
+ if (!mqsw) return;
+ MultiQueryServer *mqs = static_cast<MultiQueryServer *>(mqsw->getInterface(multiQueryServerGuid));
+
+ // multiquery is now available in mqs->mqs_getMultiQuery(); using format "table guid;query;table guid;query;etc..."
+ fn = new FilenameI(StringPrintf("query://%s.nsq", mqs->mqs_getMultiQuery()));
+ addDragItem(Filename::dragitem_getDatatype(), static_cast<Filename*>(fn));
+ handleDrag();
+}
+
+int QueryDrag::dragComplete(int success) {
+ ASSERT(fn != NULL);
+ delete fn; fn = NULL;
+ return 1;
+}
diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h
new file mode 100644
index 00000000..6dad07ae
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h
@@ -0,0 +1,53 @@
+#ifndef __QUERYDRAG_H
+#define __QUERYDRAG_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <tataki/bitmap/autobitmap.h>
+
+class FilenameI;
+
+#define QUERYDRAG_PARENT GuiObjectWnd
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+
+class QueryDrag : public QUERYDRAG_PARENT {
+
+ public:
+
+ QueryDrag();
+ virtual ~QueryDrag();
+
+ virtual int onPaint(Canvas *c);
+ virtual int getPreferences(int what);
+ virtual int onMouseMove(int x, int y);
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setImage(const char *elementname);
+ void setSource(const char *elementname);
+ void onBeginDrag();
+ virtual int dragComplete(int success);
+
+ private:
+
+ AutoSkinBitmap image;
+ String source;
+
+ FilenameI *fn;
+
+ enum {
+ QUERYDRAG_SETIMAGE = 0,
+ QUERYDRAG_SETSOURCE,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+};
+
+
+// -----------------------------------------------------------------------
+extern char QueryDragXuiObjectStr[];
+extern char QueryDragXuiSvcName[];
+class QueryDragXuiSvc : public XuiObjectSvc<QueryDrag, QueryDragXuiObjectStr, QueryDragXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp
new file mode 100644
index 00000000..2de3c918
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp
@@ -0,0 +1,73 @@
+#include <precomp.h>
+
+#include "xuiqueryline.h"
+#include <api/skin/widgets/db/xuiquerylist.h>
+
+#define CB_SETQUERYLIST 0x1978
+
+char QueryLineXuiObjectStr[] = "QueryLine"; // This is the xml tag
+char QueryLineXuiSvcName[] = "QueryLine xui object";
+
+ScriptQueryLine::ScriptQueryLine() {
+ myxuihandle = newXuiHandle();
+ addParam(myxuihandle, "querylist", QUERYLINE_SETQUERYLIST, XUI_ATTRIBUTE_IMPLIED);
+ addParam(myxuihandle, "query", QUERYLINE_SETQUERY, XUI_ATTRIBUTE_IMPLIED);
+ addParam(myxuihandle, "auto", QUERYLINE_SETAUTO, XUI_ATTRIBUTE_IMPLIED);
+}
+
+ScriptQueryLine::~ScriptQueryLine() { }
+
+/*int ScriptQueryLine::onInit() {
+ SCRIPTQUERYLINE_PARENT::onInit();
+ if (!querylist_id.isempty())
+ postDeferredCallback(CB_SETQUERYLIST, 0, 500);
+ return 1;
+}*/
+
+int ScriptQueryLine::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return SCRIPTQUERYLINE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case QUERYLINE_SETQUERYLIST:
+ setXuiQueryList(value);
+ break;
+ case QUERYLINE_SETQUERY:
+ ql_setQuery(value);
+ break;
+ case QUERYLINE_SETAUTO:
+ setAuto(WTOI(value));
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void ScriptQueryLine::ql_setQuery(const char *q) {
+ ensureConnected();
+ setQuery(q);
+}
+
+void ScriptQueryLine::ensureConnected() {
+ api_window *o = findWindow(querylist_id);
+ if (!o) return;
+ ScriptQueryList *querylist = static_cast<ScriptQueryList *>(o->getInterface(queryListGuid));
+ if (!querylist) return;
+ sqs_setMultiQueryServer(querylist);
+}
+
+void ScriptQueryLine::setXuiQueryList(const char *v) {
+ querylist_id = v;
+}
+
+/*int ScriptQueryLine::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ switch (p1) {
+ case CB_SETQUERYLIST:
+ break;
+ default:
+ return SCRIPTQUERYLINE_PARENT::onDeferredCallback(p1, p2);
+ }
+ return 1;
+}
+*/ \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/db/xuiqueryline.h b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.h
new file mode 100644
index 00000000..a65554e6
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/xuiqueryline.h
@@ -0,0 +1,35 @@
+#ifndef _XUIQUERYLINE_H
+#define _XUIQUERYLINE_H
+
+#include <api/skin/widgets/db/queryline.h>
+
+#define SCRIPTQUERYLINE_PARENT QueryLine
+class ScriptQueryLine : public SCRIPTQUERYLINE_PARENT {
+public:
+ ScriptQueryLine();
+ virtual ~ScriptQueryLine();
+
+ //virtual int onInit();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+ void setXuiQueryList(const char *v);
+
+ //virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+private:
+ enum {
+ QUERYLINE_SETQUERYLIST=1,
+ QUERYLINE_SETQUERY,
+ QUERYLINE_SETAUTO,
+ };
+ void ql_setQuery(const char *);
+ void ensureConnected();
+ int myxuihandle;
+ String querylist_id;
+};
+
+extern char QueryLineXuiObjectStr[];
+extern char QueryLineXuiSvcName[];
+class QueryLineXuiSvc : public XuiObjectSvc<ScriptQueryLine, QueryLineXuiObjectStr, QueryLineXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp
new file mode 100644
index 00000000..b5ff10bd
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp
@@ -0,0 +1,119 @@
+#include <precomp.h>
+#include "xuiquerylist.h"
+#include <tataki/canvas/ifc_canvas.h>
+
+#include <api/service/svcs/svc_objectdir.h>
+
+// -----------------------------------------------------------------------
+char QueryListXuiObjectStr[] = "QueryResults"; // This is the xml tag
+char QueryListXuiSvcName[] = "ScriptQueryResults xui object";
+XMLParamPair ScriptQueryList::params[] = {
+{QUERYLIST_SETTITLE, "TITLE"},
+};
+// -----------------------------------------------------------------------
+ScriptQueryList::ScriptQueryList() {
+ getScriptObject()->vcpu_setInterface(queryListGuid, (void *)static_cast<ScriptQueryList *>(this));
+#ifdef WASABI_COMPILE_METADB
+ getScriptObject()->vcpu_setInterface(multiQueryServerGuid, (void *)static_cast<MultiQueryServer *>(this));
+#endif
+ getScriptObject()->vcpu_setClassName("QueryList"); // this is the script class name
+ getScriptObject()->vcpu_setController(queryListController);
+
+ myxuihandle = newXuiHandle();
+
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ScriptQueryList::~ScriptQueryList() {
+}
+
+// -----------------------------------------------------------------------
+int ScriptQueryList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return QUERYLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case QUERYLIST_SETTITLE: setTitle(value); break;
+ default: return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ScriptQueryList::setTitle(const char *name) {
+ setName(name);
+//CUT if (!name || !*name) showLabel(0); else showLabel(1);
+}
+
+#ifdef WASABI_COMPILE_METADB
+// -----------------------------------------------------------------------
+void ScriptQueryList::onResetSubqueries() {
+ QUERYLIST_PARENT::onResetSubqueries();
+ QueryListScriptController::querylist_onResetQuery(SCRIPT_CALL, getScriptObject());
+}
+#endif
+
+#ifdef WASABI_COMPILE_METADB
+int ScriptQueryList::onAction(const char *action, const char *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, api_window *source) {
+ if (STRCASEEQLSAFE(action, "SAVEQUERY")) {
+ String q = mqs_getMultiQuery();
+ if (!q.isempty()) {
+ svc_objectDir *qd = ObjectDirEnum("querydir").getNext();
+ if (qd != NULL) {
+ qd->insertObject(q, "gay", "user is gay");
+ }
+ }
+ return 1;
+ }
+ return QUERYLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+#endif
+
+// -----------------------------------------------------------------------
+// Script Object
+
+QueryListScriptController _queryListController;
+QueryListScriptController *queryListController = &_queryListController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct QueryListScriptController::exportedFunction[] = {
+ {"onResetQuery", 0, (void*)QueryListScriptController::querylist_onResetQuery},
+};
+
+ScriptObject *QueryListScriptController::instantiate() {
+ ScriptQueryList *sql = new ScriptQueryList;
+ ASSERT(sql != NULL);
+ return sql->getScriptObject();
+}
+
+void QueryListScriptController::destroy(ScriptObject *o) {
+ ScriptQueryList *sql = static_cast<ScriptQueryList *>(o->vcpu_getInterface(queryListGuid));
+ ASSERT(sql != NULL);
+ delete sql;
+}
+
+void *QueryListScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for querylist yet
+}
+
+void QueryListScriptController::deencapsulate(void *o) {
+}
+
+int QueryListScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *QueryListScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar QueryListScriptController::querylist_onResetQuery(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, queryListController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
diff --git a/Src/Wasabi/api/skin/widgets/db/xuiquerylist.h b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.h
new file mode 100644
index 00000000..a278afcb
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/db/xuiquerylist.h
@@ -0,0 +1,72 @@
+#ifndef __QUERYLIST_H
+#define __QUERYLIST_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#ifdef WASABI_COMPILE_METADB
+#include <api/skin/widgets/db/autoquerylist.h>
+#endif
+#include <api/script/objcontroller.h>
+
+#ifdef WASABI_COMPILE_METADB
+#define QUERYLIST_PARENT AutoQueryList
+#else
+#define QUERYLIST_PARENT GuiObjectWnd
+#endif
+
+// -----------------------------------------------------------------------
+class ScriptQueryList : public QUERYLIST_PARENT {
+
+ public:
+
+ ScriptQueryList();
+ virtual ~ScriptQueryList();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setTitle(const char *name);
+
+#ifdef WASABI_COMPILE_METADB
+ void onResetSubqueries();
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, api_window *source=NULL);
+#endif
+
+ private:
+
+ enum {
+ QUERYLIST_SETTITLE = 0,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+};
+
+// -----------------------------------------------------------------------
+class QueryListScriptController: public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"QueryList"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return queryListGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ static scriptVar querylist_onResetQuery(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern QueryListScriptController *queryListController;
+
+// -----------------------------------------------------------------------
+extern char QueryListXuiObjectStr[];
+extern char QueryListXuiSvcName[];
+class QueryListXuiSvc : public XuiObjectSvc<ScriptQueryList, QueryListXuiObjectStr, QueryListXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/dropdownlist.cpp b/Src/Wasabi/api/skin/widgets/dropdownlist.cpp
new file mode 100644
index 00000000..2a399550
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/dropdownlist.cpp
@@ -0,0 +1,747 @@
+#include <precomp.h>
+#include "dropdownlist.h"
+#include <api/wnd/wndclass/listwnd.h>
+#include <api/script/objects/guiobject.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/wnd/popexitcb.h>
+#include <api/wnd/notifmsg.h>
+#include <api/service/svc_enum.h>
+#include <bfc/parse/paramparser.h>
+#include <api/service/svcs/svc_textfeed.h>
+
+#define DDL_CLOSELISTCB 0x0721
+
+XMLParamPair DropDownList::params[] =
+{
+ {DROPDOWNLIST_SETFEED, L"FEED"},
+ {DROPDOWNLIST_SETITEMS, L"ITEMS"},
+ {DROPDOWNLIST_LISTHEIGHT, L"LISTHEIGHT"},
+ {DROPDOWNLIST_MAXITEMS, L"MAXITEMS"},
+ {DROPDOWNLIST_SELECT, L"SELECT"},
+ {DROPDOWNLIST_SETLISTANTIALIAS, L"ANTIALIAS"},
+};
+// -----------------------------------------------------------------------
+DropDownList::DropDownList() {
+ selected = -1;
+ //abstract_setAllowDeferredContent(1);
+ clicks_button = NULL;
+ clicks_text = NULL;
+ list_key = NULL;
+ height = 128;
+ maxitems = 0;
+ noitemtext = L"";
+ list_group = NULL;
+ trap_click = 0;
+ disable_cfg_event = 0;
+
+ GuiObjectWnd::getScriptObject()->vcpu_setInterface(dropDownListGuid, (void *)static_cast<DropDownList *>(this));
+ GuiObjectWnd::getScriptObject()->vcpu_setClassName(L"DropDownList"); // this is the script class name
+ GuiObjectWnd::getScriptObject()->vcpu_setController(dropDownListController);
+
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ registerAcceleratorSection(L"popup", 1);
+}
+
+void DropDownList::CreateXMLParameters(int master_handle)
+{
+ //DROPDOWNLIST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+// -----------------------------------------------------------------------
+DropDownList::~DropDownList() {
+ doCloseList(0);
+ delete clicks_text;
+ delete clicks_button;
+ delete list_key;
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::onAcceleratorEvent(const wchar_t *name) {
+ int r = DROPDOWNLIST_PARENT::onAcceleratorEvent(name);
+ if (WCSCASEEQLSAFE(name, L"exit")) {
+ escapeCallback();
+ return 1;
+ }
+ return r;
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return DROPDOWNLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case DROPDOWNLIST_SETITEMS:
+ setItems(value);
+ break;
+ case DROPDOWNLIST_SETFEED:
+ setFeed(value);
+ break;
+ case DROPDOWNLIST_SELECT:
+ selectItem(findItem(value));
+ break;
+ case DROPDOWNLIST_LISTHEIGHT:
+ setListHeight(WTOI(value));
+ break;
+ case DROPDOWNLIST_MAXITEMS:
+ setMaxItems(WTOI(value));
+ break;
+ case DROPDOWNLIST_SETLISTANTIALIAS:
+ listAntialias = WTOI(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::onInit()
+{
+ int rt = DROPDOWNLIST_PARENT::onInit();
+ abstract_setContent(dropdownlist_getMainGroupId());
+ return rt;
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::abstract_onNewContent() {
+ DROPDOWNLIST_PARENT::abstract_onNewContent();
+ trapControls();
+ updateTextInControl(getSelectedText());
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+// -----------------------------------------------------------------------
+int DropDownList::onReloadConfig() {
+ int r = DROPDOWNLIST_PARENT::onReloadConfig();
+ disable_cfg_event = 1;
+ updateTextFromConfig(); // triggers onSelect
+ disable_cfg_event = 0;
+ return r;
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::updateTextFromConfig() {
+ const wchar_t *val = getGuiObject()->guiobject_getCfgString();
+ const wchar_t *old = getSelectedText();
+ if (old && val && !_wcsicmp(val, old)) return;
+
+ if (val != NULL) {
+ int id = findItem(val);
+ if (id != -1)
+ selectItem(id);
+ }
+}
+#endif
+
+// -----------------------------------------------------------------------
+void DropDownList::trapControls() {
+ delete clicks_button;
+ delete clicks_text;
+
+ clicks_button = NULL;
+ clicks_text = NULL;
+
+ if (wantTrapText()) {
+ GuiObject *textGuiObj = getGuiObject()->guiobject_findObject(dropdownlist_getTextId());
+ if (textGuiObj) clicks_text = new DDLClicksCallback(*textGuiObj, this);
+ }
+
+ if (wantTrapButton()) {
+ GuiObject *butGuiObj = getGuiObject()->guiobject_findObject(dropdownlist_getButtonId());
+ if (butGuiObj) clicks_button = new DDLClicksCallback(*butGuiObj, this);
+ }
+}
+
+
+// -----------------------------------------------------------------------
+void DropDownList::clickCallback() {
+ if (list_group != NULL)
+ closeList();
+ else
+ openList();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::escapeCallback() {
+ if (isListOpen())
+ closeList();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::openList() {
+ onPreOpenList();
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+#ifdef WASABI_COMPILE_WNDMGR
+ list_group = WASABI_API_SKIN->group_create_layout(dropdownlist_getListGroupId());
+#else
+ list_group = WASABI_API_SKIN->group_create(dropdownlist_getListGroupId());
+#endif
+ group_dep = list_group->getDependencyPtr();
+ viewer_addViewItem(group_dep);
+ if (list_group == NULL) return;
+ list_group->setStartHidden(1);
+ list_group->setParent(WASABI_API_WND->main_getRootWnd());
+ trap_click = 0;
+ list_group->init(this, TRUE);
+ setListParams();
+
+ // At this point, the list should be good. Calc for max-items size
+ int calc_height = 0;
+ if (maxitems) {
+ ifc_window *listroot = list_group->findWindowByInterface(listGuid);
+ ListWnd *listwnd = static_cast<ListWnd *>(listroot->getInterface(guilistGuid));
+ GuiObject *listobj = listroot->getGuiObject();
+ if (listwnd) {
+ int numitems = 0;
+ if (maxitems == -1) {
+ numitems = listwnd->getNumItems();
+ } else {
+ numitems = MIN(maxitems, listwnd->getNumItems());
+ }
+ int offset_h = 0;
+ if (listobj) {
+ const wchar_t *y_param = listobj->guiobject_getXmlParam(L"y");
+ const wchar_t *h_param = listobj->guiobject_getXmlParam(L"h");
+ const wchar_t *ry_param = listobj->guiobject_getXmlParam(L"relaty");
+ const wchar_t *rh_param = listobj->guiobject_getXmlParam(L"relath");
+ int h_val = (h_param)?WTOI(h_param):0;
+ int y_val = (y_param)?WTOI(y_param):0;
+ if (ry_param && (wcscmp(ry_param, L"1") == 0)) {
+ if (y_val < 0) y_val = -y_val;
+ else y_val = 0;
+ }
+ if (rh_param && (wcscmp(rh_param, L"1") == 0)) {
+ if (h_val < 0) h_val = -h_val;
+ }
+ offset_h = h_val + y_val;
+ }
+ calc_height = (numitems * listwnd->getItemHeight()) + offset_h;
+ }
+ } else {
+ calc_height = height;
+ }
+
+ RECT r;
+ getWindowRect(&r);
+ r.top = r.bottom;
+ r.bottom = r.top + calc_height;
+ divRatio(&r);
+ list_group->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ list_group->setVisible(1);
+ WASABI_API_WND->popupexit_register(this, list_group); // this will call us back whenever someone clicks outside us
+ trap_click = 1;
+ listif = list_group->findWindowByInterface(listGuid);
+ if (listif != NULL)
+ list_key = new DDLKeyCallback(listif->getGuiObject()->guiobject_getScriptObject(), this);
+ dropdownlist_onOpenList();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::dropdownlist_onOpenList()
+{
+#ifdef _WIN32
+ SetCapture(NULL); // NONPORTABLE, the goal is to cancel any capture some of our content guiobject might have so as to let the click down + slide in list transfer mouse capture
+#else
+#warning port me?
+#endif
+ setFocus();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::dropdownlist_onCloseList() {
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::closeList() {
+ if (list_group != NULL) {
+ onPreCloseList();
+ postDeferredCallback(DDL_CLOSELISTCB, 0);
+ }
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::doCloseList(int cb) {
+ if (cb) dropdownlist_onCloseList();
+ if (list_group) {
+ trap_click = 0;
+ WASABI_API_WND->popupexit_deregister(this);
+ WASABI_API_SKIN->group_destroy(list_group);
+ list_group = NULL;
+ group_dep = NULL;
+ action_list = NULL;
+ delete list_key;
+ list_key = NULL;
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+ }
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::setListParams() {
+ ASSERT(list_group != NULL);
+ GuiObject *go = static_cast<GuiObject *>(list_group->getInterface(guiObjectGuid));
+ if (go != NULL) {
+ dropdownlist_onConfigureList(go);
+ }
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::dropdownlist_onConfigureList(GuiObject *go) {
+ XmlObject *o = NULL;
+ if (go != NULL) {
+ GuiObject *list = go->guiobject_findObject(dropdownlist_getListId());
+ if (list != NULL) {
+ action_list = list->guiobject_getRootWnd();
+ o = static_cast<XmlObject *>(list->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ }
+ }
+ StringW s;
+ foreach(items)
+ if (foreach_index > 0)
+ s += L";";
+ s += items.getfor()->getText();
+ endfor;
+ o->setXmlParam(L"multiselect", L"0");
+ o->setXmlParam(L"hoverselect", L"1");
+ o->setXmlParam(L"selectonupdown", L"0");
+ o->setXmlParam(L"sort", StringPrintfW(L"%d", wantAutoSort()));
+ o->setXmlParam(L"items", s);
+ o->setXmlParam(L"antialias", listAntialias ? L"1" : L"0");
+ if (selected != -1)
+ o->setXmlParam(L"select", getSelectedText());
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (WCSCASEEQLSAFE(action, L"set_selection")) {
+ int p = findItem(param);
+ selectItem(p);
+ return p;
+ }
+ if (WCSCASEEQLSAFE(action, L"get_selection")) {
+ if (source)
+ sendAction(source, L"set_selection", getSelectedText());
+ }
+ return DROPDOWNLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::addItem(const wchar_t *text) {
+ DDLEntry *e = new DDLEntry(text);
+ items.setSorted(wantAutoSort());
+ items.addItem(e);
+ return e->getId();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::selectDefault() {
+#ifdef WASABI_COMPILE_CONFIG
+ onReloadConfig();
+#endif
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::delItem(int id) {
+ foreach(items)
+ if (items.getfor()->getId() == id) {
+ delete items.getfor();
+ items.removeByPos(foreach_index);
+ break;
+ }
+ endfor;
+ if (list_group != NULL)
+ setListParams();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::selectItem(int id, int hover) {
+ //FG> DO NOT PUT THIS TEST BACK: if (selected == id) return;
+ selected = id;
+ onSelect(selected, hover);
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::onSelect(int id, int hover) {
+ updateTextInControl(getSelectedText());
+ if (!disable_cfg_event && !hover) {
+#ifdef WASABI_COMPILE_CONFIG
+ if (selected == -1)
+ getGuiObject()->guiobject_setCfgString(L"");
+ else
+ getGuiObject()->guiobject_setCfgString(getSelectedText());
+#endif
+ }
+
+ // Let the script have the callback, too.
+ DropDownListScriptController::DropDownList_onSelect(SCRIPT_CALL, GuiObjectWnd::getScriptObject(), MAKE_SCRIPT_INT(id), MAKE_SCRIPT_INT(hover));
+
+}
+
+// -----------------------------------------------------------------------
+const wchar_t *DropDownList::getItemText(int id) {
+ foreach(items)
+ if (items.getfor()->getId() == id)
+ return items.getfor()->getText();
+ endfor;
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::findItem(const wchar_t *text) {
+ int pos=-1;
+ items.findItem(text, &pos);
+ if (pos < 0) return -1;
+ return items[pos]->getId();
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::updateTextInControl(const wchar_t *txt)
+{
+ GuiObject *content = getContent();
+ if (content != NULL) {
+ if (wantTrapText()) {
+ GuiObject *text = content->guiobject_findObject(dropdownlist_getTextId());
+ if (text != NULL) {
+ C_Text t(*text);
+ t.setText(txt);
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::setNoItemText(const wchar_t *txt)
+{
+ noitemtext = txt;
+ if (selected == -1)
+ updateTextInControl(getSelectedText());
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::popupexitcb_onExitPopup() {
+ closeList();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+ if (msg == ChildNotify::LISTWND_ITEMSELCHANGED && param2 && trap_click) {
+ sendAction(action_list, L"get_selection");
+ closeList();
+ }
+ return DROPDOWNLIST_PARENT::childNotify(child, msg, param1, param2);
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == DDL_CLOSELISTCB)
+ doCloseList();
+ return DROPDOWNLIST_PARENT::onDeferredCallback(p1, p2);
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::viewer_onItemDeleted(ifc_dependent *item) {
+ if (item == group_dep) {
+ WASABI_API_WND->popupexit_deregister(this);
+ trap_click = 0;
+ list_group = NULL;
+ group_dep = NULL;
+ action_list = NULL;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void DropDownList::feedwatcher_onSetFeed(svc_textFeed *svc)
+{
+ StringW a = getRootWndName();
+ if (a.isempty())
+ setName(svc->getFeedDescription(getFeedId()));
+}
+
+void DropDownList::feedwatcher_onFeedChange(const wchar_t *data)
+{
+ setItems(data);
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::deleteAllItems() {
+ items.deleteAll();
+ selected = -1;
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::onKeyDown(int keyCode) {
+#ifdef _WIN32
+ if (isListOpen()) {
+ switch (keyCode) {
+ case VK_ESCAPE:
+ closeList();
+ break;
+ }
+ if (listif != NULL) {
+ listif->onKeyDown(keyCode);
+ }
+ } else {
+ switch (keyCode) {
+ case VK_SPACE:
+ case VK_RETURN:
+ openList();
+ break;
+ }
+ }
+#else
+#warning port me
+#endif
+ return DROPDOWNLIST_PARENT::onKeyDown(keyCode);
+}
+
+// -----------------------------------------------------------------------
+int DropDownList::onKeyUp(int keyCode) {
+ if (isListOpen()) {
+ if (listif != NULL) {
+ listif->onKeyUp(keyCode);
+ return 1;
+ }
+ }
+ return DROPDOWNLIST_PARENT::onKeyDown(keyCode);
+}
+
+// -----------------------------------------------------------------------
+void DropDownList::setItems(const wchar_t *value) {
+ deleteAllItems();
+ ParamParser pp(value);
+ for (int i=0;i<pp.getNumItems();i++) {
+ addItem(pp.enumItem(i));
+ }
+ selectDefault();
+}
+
+// -----------------------------------------------------------------------
+
+int DDLEntry::id_gen=0;
+
+
+// -----------------------------------------------------------------------
+// Script Object
+
+DropDownListScriptController _dropDownListController;
+DropDownListScriptController *dropDownListController = &_dropDownListController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct DropDownListScriptController::exportedFunction[] = {
+ {L"getItemSelected", 0, (void*)DropDownListScriptController::DropDownList_getItemSelected},
+ {L"onSelect", 2, (void*)DropDownListScriptController::DropDownList_onSelect},
+
+ {L"setListHeight", 1, (void*)DropDownListScriptController::DropDownList_setListHeight},
+ {L"openList", 0, (void*)DropDownListScriptController::DropDownList_openList},
+ {L"closeList", 0, (void*)DropDownListScriptController::DropDownList_closeList},
+ {L"setItems", 1, (void*)DropDownListScriptController::DropDownList_setItems},
+ {L"addItem", 1, (void*)DropDownListScriptController::DropDownList_addItem},
+ {L"delItem", 1, (void*)DropDownListScriptController::DropDownList_delItem},
+ {L"findItem", 1, (void*)DropDownListScriptController::DropDownList_findItem},
+ {L"getNumItems", 0, (void*)DropDownListScriptController::DropDownList_getNumItems},
+ {L"selectItem", 2, (void*)DropDownListScriptController::DropDownList_selectItem},
+ {L"getItemText", 1, (void*)DropDownListScriptController::DropDownList_getItemText},
+ {L"getSelected", 0, (void*)DropDownListScriptController::DropDownList_getSelected},
+ {L"getSelectedText", 0, (void*)DropDownListScriptController::DropDownList_getSelectedText},
+ {L"getCustomText", 0, (void*)DropDownListScriptController::DropDownList_getCustomText},
+ {L"deleteAllItems", 0, (void*)DropDownListScriptController::DropDownList_deleteAllItems},
+ {L"setNoItemText", 1, (void*)DropDownListScriptController::DropDownList_setNoItemText},
+};
+
+ScriptObject *DropDownListScriptController::instantiate() {
+ DropDownList *ddl = new DropDownList;
+ ASSERT(ddl != NULL);
+ return ddl->GuiObjectWnd::getScriptObject();
+}
+
+void DropDownListScriptController::destroy(ScriptObject *o) {
+ DropDownList *ddl= static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ ASSERT(ddl != NULL);
+ delete ddl;
+}
+
+void *DropDownListScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for DropDownlist yet
+}
+
+void DropDownListScriptController::deencapsulate(void *o) {
+}
+
+int DropDownListScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *DropDownListScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar DropDownListScriptController::DropDownList_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList*>(o->vcpu_getInterface(dropDownListGuid));
+ const wchar_t *p=L"";
+ if (ddl) p = ddl->getSelectedText();
+
+
+ return MAKE_SCRIPT_STRING(p);
+}
+
+scriptVar DropDownListScriptController::DropDownList_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar hover) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, dropDownListController, id, hover);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, id, hover);
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_setListHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar h) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->setListHeight(GET_SCRIPT_INT(h));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_openList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->openList();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_closeList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->closeList();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_setItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar lotsofitems) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->setItems(GET_SCRIPT_STRING(lotsofitems));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar DropDownListScriptController::DropDownList_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ int retval = 0;
+ if (ddl)
+ {
+ retval = ddl->addItem(GET_SCRIPT_STRING(text));
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_delItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->delItem(GET_SCRIPT_INT(id));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar DropDownListScriptController::DropDownList_findItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ int retval = 0;
+ if (ddl) {
+ retval = ddl->findItem(GET_SCRIPT_STRING(text));
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar DropDownListScriptController::DropDownList_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ int retval = 0;
+ if (ddl) {
+ retval = ddl->getNumItems();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id, /*int*/ scriptVar hover) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->selectItem(GET_SCRIPT_INT(id), GET_SCRIPT_INT(hover));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*String*/ scriptVar DropDownListScriptController::DropDownList_getItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ const wchar_t *retval = L"";
+ if (ddl) {
+ retval = ddl->getItemText(GET_SCRIPT_INT(id));
+ }
+ return MAKE_SCRIPT_STRING(retval);
+}
+
+/*int*/ scriptVar DropDownListScriptController::DropDownList_getSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ int retval = 0;
+ if (ddl) {
+ retval = ddl->getSelected();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*String*/ scriptVar DropDownListScriptController::DropDownList_getSelectedText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ const wchar_t *retval = L"";
+ if (ddl) {
+ retval = ddl->getSelectedText();
+ }
+ return MAKE_SCRIPT_STRING(retval);
+}
+
+/*String*/ scriptVar DropDownListScriptController::DropDownList_getCustomText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ const wchar_t *retval=L"";
+ if (ddl) {
+ retval = ddl->getCustomText();
+ }
+ return MAKE_SCRIPT_STRING(retval);
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->deleteAllItems();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar DropDownListScriptController::DropDownList_setNoItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar txt) {
+ SCRIPT_FUNCTION_INIT
+ DropDownList *ddl = static_cast<DropDownList *>(o->vcpu_getInterface(dropDownListGuid));
+ if (ddl) {
+ ddl->setNoItemText(GET_SCRIPT_STRING(txt));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/dropdownlist.h b/Src/Wasabi/api/skin/widgets/dropdownlist.h
new file mode 100644
index 00000000..0b3ef247
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/dropdownlist.h
@@ -0,0 +1,531 @@
+#ifndef __DROPDOWNLIST_H
+#define __DROPDOWNLIST_H
+
+#include <api/wnd/popexitcb.h>
+#include <api/wnd/wndclass/embeddedxui.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+#include <api/script/objects/c_script/h_button.h>
+#include <api/skin/feeds/feedwatch.h>
+#include <api/script/objcontroller.h>
+
+#define DROPDOWNLIST_PARENT EmbeddedXuiObject
+
+class DDLClicksCallback;
+class DDLKeyCallback;
+class svc_textFeed;
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class DDLEntry {
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ DDLEntry(const wchar_t *txt) : text(txt), id(id_gen++) { }
+ const wchar_t *getText() { return text; }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getId() { return id; }
+
+ private:
+ StringW text;
+ int id;
+ static int id_gen;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class SortDDLEntries{
+public:
+
+ static int compareItem(DDLEntry *p1, DDLEntry *p2) {
+
+ return WCSICMP(p1->getText(), p2->getText());
+ }
+
+ static int compareAttrib(const wchar_t *attrib, DDLEntry *item)
+ {
+ return WCSICMP(attrib, item->getText());
+ }
+};
+
+
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class DropDownList : public DROPDOWNLIST_PARENT, public PopupExitCallbackI, public FeedWatcher, public DependentViewerI {
+
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ DropDownList();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~DropDownList();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void clickCallback();
+ void escapeCallback();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+#ifdef WASABI_COMPILE_CONFIG
+ virtual int onReloadConfig();
+#endif
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void abstract_onNewContent();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void setListHeight(int h) { height = h; }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int popupexitcb_onExitPopup();
+ virtual api_dependent *popupexit_getDependencyPtr() { return rootwnd_getDependencyPtr(); }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void openList();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void closeList();
+
+
+ void setItems(const wchar_t *lotsofitems);
+
+ int addItem(const wchar_t *text);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void delItem(int id);
+
+
+ int findItem(const wchar_t *text);
+
+ int getNumItems() { return items.getNumItems(); }
+ DDLEntry *enumItem(int i) { return items.enumItem(i); }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void selectItem(int id, int hover=0);
+ const wchar_t *getItemText(int id);
+
+ int getSelected() { return selected; }
+ const wchar_t *getSelectedText() { int a = getSelected(); if (a == -1) return getCustomText(); return getItemText(a); }
+ virtual const wchar_t *getCustomText() { return noitemtext; }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void deleteAllItems();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onSelect(int id, int hover=0);
+
+ virtual void setNoItemText(const wchar_t *txt);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int viewer_onItemDeleted(api_dependent *item);
+
+ virtual void feedwatcher_onSetFeed(svc_textFeed *svc);
+ virtual void feedwatcher_onFeedChange(const wchar_t *data);
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void selectDefault();
+
+ virtual void setMaxItems(int _maxitems) { maxitems = _maxitems; }
+ virtual int getMaxItems() { return maxitems; }
+
+ virtual int wantTrapButton() { return 1; }
+ virtual int wantTrapText() { return 1; }
+ virtual int wantFocus() { return 1; }
+
+ virtual const wchar_t *dropdownlist_getMainGroupId() { return L"wasabi.dropdownlist.main.group"; }
+ virtual const wchar_t *dropdownlist_getListGroupId() { return L"wasabi.dropdownlist.list.group"; }
+ virtual const wchar_t *dropdownlist_getTextId() { return L"dropdownlist.text"; }
+ virtual const wchar_t *dropdownlist_getButtonId() { return L"dropdownlist.button"; }
+ virtual const wchar_t *dropdownlist_getListId() { return L"dropdownlist.list"; }
+
+ virtual void updateTextInControl(const wchar_t *txt);
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual const wchar_t *embeddedxui_getContentId() { return dropdownlist_getMainGroupId(); }
+ virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return dropdownlist_getTextId(); }
+
+ int isListOpen() { return list_group != NULL; };
+ virtual int wantAutoSort() { return 1; }
+
+ virtual void dropdownlist_onCloseList();
+ virtual void dropdownlist_onOpenList();
+
+ virtual void dropdownlist_onConfigureList(GuiObject *o);
+ virtual int onKeyDown(int keyCode);
+ virtual int onKeyUp(int keyCode);
+ virtual int onAcceleratorEvent(const wchar_t *name);
+
+ virtual void onPreCloseList() {}
+ virtual void onPreOpenList() {}
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ enum {
+ DROPDOWNLIST_SETITEMS = 0,
+ DROPDOWNLIST_SETFEED,
+ DROPDOWNLIST_SELECT,
+ DROPDOWNLIST_LISTHEIGHT,
+ DROPDOWNLIST_MAXITEMS,
+ DROPDOWNLIST_SETLISTANTIALIAS,
+ };
+ int myxuihandle;
+ static XMLParamPair params[];
+
+ private:
+
+#ifdef WASABI_COMPILE_CONFIG
+ void updateTextFromConfig();
+#endif
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void trapControls();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setListParams();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void doCloseList(int cb=1);
+
+ DDLClicksCallback *clicks_button;
+ DDLClicksCallback *clicks_text;
+ DDLKeyCallback *list_key;
+ ifc_window *list_group;
+ PtrListInsertSorted<DDLEntry, SortDDLEntries> items;
+ int selected;
+
+ int height;
+ int maxitems;
+ StringW noitemtext;
+ int trap_click;
+ api_dependent *group_dep;
+ ifc_window *action_list;
+ int disable_cfg_event;
+ ifc_window *listif;
+ int listAntialias;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class DDLClicksCallback : public H_GuiObject {
+ public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ DDLClicksCallback(ScriptObject *trap, DropDownList *_callback) :
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ callback(_callback), H_GuiObject(trap) {
+ }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onLeftButtonDown(int x, int y) {
+ callback->clickCallback();
+ }
+ virtual void hook_onChar(wchar_t c)
+ {
+#ifdef _WIN32
+ if (c == VK_SPACE || c == VK_RETURN)
+ callback->clickCallback();
+#else
+#warning port me
+#endif
+ }
+ private:
+ DropDownList *callback;
+};
+
+class DDLKeyCallback : public H_GuiObject {
+ public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ DDLKeyCallback(ScriptObject *trap, DropDownList *_callback) :
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ callback(_callback), H_GuiObject(trap) {
+ }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+
+ virtual void hook_onChar(wchar_t c)
+ {
+#ifdef _WIN32
+ if (c == VK_ESCAPE)
+ callback->escapeCallback();
+#else
+#warning port me
+#endif
+ }
+ private:
+ DropDownList *callback;
+};
+
+// -----------------------------------------------------------------------
+class DropDownListScriptController: public ScriptObjectControllerI {
+public:
+ virtual const wchar_t *getClassName() { return L"DropDownList"; }
+ virtual const wchar_t *getAncestorClassName() { return L"ObjectEmbedder"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(embeddedXuiGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return dropDownListGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ // public cause it's called by the xui object.
+ static scriptVar DropDownList_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar hover);
+
+private:
+
+ static function_descriptor_struct exportedFunction[];
+ static scriptVar DropDownList_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static /*void*/ scriptVar DropDownList_setListHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar h);
+ static /*void*/ scriptVar DropDownList_openList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar DropDownList_closeList(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar DropDownList_setItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar lotsofitems);
+ static /*int*/ scriptVar DropDownList_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text);
+ static /*void*/ scriptVar DropDownList_delItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id);
+ static /*int*/ scriptVar DropDownList_findItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar text);
+ static /*int*/ scriptVar DropDownList_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar DropDownList_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id, /*int*/ scriptVar hover);
+ static /*String*/ scriptVar DropDownList_getItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar id);
+ static /*int*/ scriptVar DropDownList_getSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*String*/ scriptVar DropDownList_getSelectedText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*String*/ scriptVar DropDownList_getCustomText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar DropDownList_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar DropDownList_setNoItemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar txt);
+
+
+};
+
+extern COMEXP DropDownListScriptController *dropDownListController;
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/edit.cpp b/Src/Wasabi/api/skin/widgets/edit.cpp
new file mode 100644
index 00000000..b7b9fe7c
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/edit.cpp
@@ -0,0 +1,312 @@
+#include <precomp.h>
+#include <bfc/wasabi_std.h>
+#include <api/skin/skinparse.h>
+#include "edit.h"
+#include <api/script/scriptmgr.h>
+#include <api/skin/widgets/mb/xuibrowser.h>
+#include <api/skin/widgets/mb/mainminibrowser.h>
+
+#define BUFSIZE 0x7ffe
+
+const wchar_t editXuiObjectStr[] = L"Edit"; // This is the xml tag
+char editXuiSvcName[] = "Edit xui object"; // this is the name of the xuiservice
+
+
+EditScriptController _editController;
+EditScriptController *editController = &_editController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct EditScriptController::exportedFunction[] = {
+ {L"setText", 1, (void*)Edit::script_vcpu_setText },
+ {L"setAutoEnter", 1, (void*)Edit::script_vcpu_setAutoEnter },
+ {L"getAutoEnter", 0, (void*)Edit::script_vcpu_getAutoEnter },
+ {L"getText", 0, (void*)Edit::script_vcpu_getText },
+ {L"onEnter", 0, (void*)Edit::script_vcpu_onEnter },
+ {L"onAbort", 0, (void*)Edit::script_vcpu_onAbort },
+ {L"onIdleEditUpdate", 0, (void*)Edit::script_vcpu_onIdleEditUpdate },
+ {L"onEditUpdate", 0, (void*)Edit::script_vcpu_onEditUpdate },
+ {L"selectAll", 0, (void*)Edit::script_vcpu_selectAll },
+ {L"enter", 0, (void*)Edit::script_vcpu_enter },
+ {L"setIdleEnabled", 1, (void*)Edit::script_vcpu_setIdleEnabled},
+ {L"getIdleEnabled", 0, (void*)Edit::script_vcpu_getIdleEnabled},
+ };
+// --------------------------------------------------------
+
+const wchar_t *EditScriptController::getClassName()
+{
+ return L"Edit";
+}
+
+const wchar_t *EditScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *EditScriptController::instantiate()
+{
+ Edit *e = new Edit;
+ ASSERT(e != NULL);
+ return e->getScriptObject();
+}
+
+void EditScriptController::destroy(ScriptObject *o)
+{
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ ASSERT(e != NULL);
+ delete e;
+}
+
+void *EditScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for edit yet
+}
+
+void EditScriptController::deencapsulate(void *o)
+{}
+
+int EditScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *EditScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID EditScriptController::getClassGuid()
+{
+ return editGuid;
+}
+
+// -----------------------------------------------------------------------------
+
+XMLParamPair Edit::params[] = {
+ {EDIT_ACTION, L"ACTION"},
+ {EDIT_AUTOENTER, L"AUTOENTER"},
+ {EDIT_AUTOHSCROLL, L"AUTOHSCROLL"},
+ {EDIT_AUTOSELECT, L"AUTOSELECT"},
+ {EDIT_MULTILINE, L"MULTILINE"},
+ {EDIT_PASSWORD, L"PASSWORD"},
+ {EDIT_TEXT, L"TEXT"},
+ {EDIT_VSCROLL, L"VSCROLL"},
+ };
+Edit::Edit()
+{
+ getScriptObject()->vcpu_setInterface(editGuid, (void *)static_cast<Edit *>(this));
+ getScriptObject()->vcpu_setClassName(L"Edit");
+ getScriptObject()->vcpu_setController(editController);
+ my_buffer = WMALLOC(BUFSIZE);
+ *my_buffer = 0;
+ autourl = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void Edit::CreateXMLParameters(int master_handle)
+{
+ //EDIT_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Edit::~Edit()
+{
+ FREE(my_buffer);
+}
+
+int Edit::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value)
+{
+ if (xuihandle == _xuihandle)
+ {
+ switch (xmlattrid)
+ {
+ case EDIT_TEXT: setText(value); return 1;
+ case EDIT_ACTION: if (SkinParser::getAction(value) == ACTION_MB_URL) setAutoUrl(1); return 1;
+ case EDIT_MULTILINE: setMultiline(WTOI(value)); return 1;
+ case EDIT_VSCROLL: setVScroll(WTOI(value)); return 1;
+ case EDIT_AUTOHSCROLL: setAutoHScroll(WTOI(value)); return 1;
+ case EDIT_AUTOENTER: setAutoEnter(WTOI(value)); return 1;
+ case EDIT_PASSWORD: setPassword(WTOI(value)); return 1;
+ case EDIT_AUTOSELECT: setAutoSelect(WTOI(value)); return 1;
+ }
+ }
+ return EDIT_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value);
+}
+
+int Edit::onInit()
+{
+ int r = EDIT_PARENT::onInit();
+ setBuffer(my_buffer, BUFSIZE - 1);
+ my_buffer[BUFSIZE - 1] = 0;
+ return r;
+}
+
+void Edit::onEditUpdate()
+{
+ EDIT_PARENT::onEditUpdate();
+ script_vcpu_onEditUpdate(SCRIPT_CALL, getScriptObject());
+}
+
+void Edit::onIdleEditUpdate()
+{
+ EDIT_PARENT::onIdleEditUpdate();
+ script_vcpu_onIdleEditUpdate(SCRIPT_CALL, getScriptObject());
+}
+
+int Edit::onEnter()
+{
+ if (autourl)
+ {
+ MainMiniBrowser::navigateUrl(my_buffer);
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgString(my_buffer);
+#endif
+ int r = EDIT_PARENT::onEnter();
+#ifdef WASABI_COMPILE_CONFIG
+ script_vcpu_onEnter(SCRIPT_CALL, getScriptObject());
+#endif
+ return r;
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+int Edit::onReloadConfig()
+{
+ EDIT_PARENT::onReloadConfig();
+ setText(getGuiObject()->guiobject_getCfgString());
+ return 1;
+}
+#endif
+
+int Edit::onAbort()
+{
+ if (autourl)
+ {
+ ScriptObject *so = MainMiniBrowser::getScriptObject();
+ if (so)
+ {
+ ScriptBrowserWnd *sbw = static_cast<ScriptBrowserWnd *>(so->vcpu_getInterface(browserGuid));
+ if (sbw)
+ setText(sbw->getCurrentUrl());
+ }
+ }
+ int r = EDIT_PARENT::onAbort();
+ script_vcpu_onAbort(SCRIPT_CALL, getScriptObject());
+ return r;
+}
+
+void Edit::setText(const wchar_t *t)
+{
+ wcsncpy(my_buffer, t, BUFSIZE - 1);
+ setBuffer(my_buffer, BUFSIZE - 1);
+ my_buffer[BUFSIZE - 1] = 0;
+}
+
+void Edit::setAutoUrl(int a)
+{
+ autourl = a;
+}
+
+// -----------------------------------------------------------------------------
+
+scriptVar Edit::script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(t.type == SCRIPT_STRING);
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) e->setText(t.data.sdata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Edit::script_vcpu_setAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t)
+{
+ SCRIPT_FUNCTION_INIT
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) e->setAutoEnter(t.data.idata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Edit::script_vcpu_getAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ int a = 0;
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) a = e->getAutoEnter();
+ return MAKE_SCRIPT_INT(a);
+}
+
+scriptVar Edit::script_vcpu_setIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t)
+{
+ SCRIPT_FUNCTION_INIT
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) e->setIdleEnabled(t.data.idata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Edit::script_vcpu_getIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ int a = 0;
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) a = e->getIdleEnabled();
+ return MAKE_SCRIPT_INT(a);
+}
+
+scriptVar Edit::script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) return MAKE_SCRIPT_STRING(e->getBufferPtr());
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Edit::script_vcpu_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) e->selectAll();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Edit::script_vcpu_enter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Edit *e = static_cast<Edit *>(o->vcpu_getInterface(editGuid));
+ if (e) e->enter();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Edit::script_vcpu_onEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, editController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Edit::script_vcpu_onIdleEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, editController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Edit::script_vcpu_onEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, editController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Edit::script_vcpu_onAbort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, editController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/edit.h b/Src/Wasabi/api/skin/widgets/edit.h
new file mode 100644
index 00000000..82b81776
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/edit.h
@@ -0,0 +1,100 @@
+#ifndef __EDIT_H
+#define __EDIT_H
+
+#include <api/script/script.h>
+#include <api/script/objects/guiobj.h>
+
+#define EDIT_PARENT EditWnd
+
+class EditScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern EditScriptController *editController;
+
+#ifndef _NOSTUDIO
+
+#include <api/wnd/wndclass/editwnd.h>
+
+class Edit : public EDIT_PARENT {
+public:
+ Edit();
+ ~Edit();
+
+ virtual void onEditUpdate();
+ virtual void onIdleEditUpdate();
+ virtual int onEnter(); // user hit enter.. return 1 to close window
+ virtual int onAbort(); // user hit escape.. return 1 to close window
+ virtual int onInit();
+#ifdef WASABI_COMPILE_CONFIG
+ virtual int onReloadConfig();
+#endif
+
+ virtual int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value);
+
+ void setText(const wchar_t *t);
+ void setAutoUrl(int a);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ wchar_t *my_buffer;
+ int autourl;
+ int xuihandle;
+
+#else
+class Edit : public EDIT_SCRIPTPARENT {
+#endif
+
+public:
+
+ static scriptVar script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t);
+ static scriptVar script_vcpu_setAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t);
+ static scriptVar script_vcpu_getAutoEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t);
+ static scriptVar script_vcpu_getIdleEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onEnter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onAbort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onIdleEditUpdate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_enter(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+protected:
+ enum {
+ EDIT_TEXT=0,
+ EDIT_ACTION,
+ EDIT_MULTILINE,
+ EDIT_VSCROLL,
+ EDIT_AUTOHSCROLL,
+ EDIT_AUTOENTER,
+ EDIT_PASSWORD,
+ EDIT_AUTOSELECT,
+};
+private:
+ static XMLParamPair params[];
+};
+
+extern const wchar_t editXuiObjectStr[];
+extern char editXuiSvcName[];
+class EditXuiSvc : public XuiObjectSvc<Edit, editXuiObjectStr, editXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/fx.h b/Src/Wasabi/api/skin/widgets/fx.h
new file mode 100644
index 00000000..7c8d318e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/fx.h
@@ -0,0 +1,12 @@
+#ifndef __FX_H
+#define __FX_H
+
+class Layer;
+
+class Fx {
+ public:
+ virtual int render(Layer *l, int _w, int _h, int *input, int tw, int th, int twpitch)=0;
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/fx_dmove.cpp b/Src/Wasabi/api/skin/widgets/fx_dmove.cpp
new file mode 100644
index 00000000..cb492260
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/fx_dmove.cpp
@@ -0,0 +1,409 @@
+#include <precomp.h>
+
+#include <tataki/blending/blending.h>
+#include "fx_dmove.h"
+
+#include <api/skin/widgets/layer.h>
+#include <math.h>
+
+#define M_PI 3.14159265358979323846
+
+
+FxDynamicMove::FxDynamicMove()
+: fx_canvas(4,4)
+{
+ need_flush=false;
+ cache_w=cache_h=4;
+ m_wmul=0;
+ m_tab=0;
+ last_m_tab=0;
+ m_lastxres=m_lastyres=m_lastpitch=0;
+ m_xres=16;
+ m_yres=16;
+ last_w=last_h=-1;
+ inited=0;
+ subpixel=1;
+ rectcoords=0;
+ blend=0;
+ wrap=0;
+ need_alpha = 1;
+ alpha_table = (double *)MALLOC((m_xres+1)*(m_yres+1)*sizeof(double));
+ alpha_once= 0;
+ can_cache = 1;
+ m_lastw = 0;
+ m_lasth = 0;
+ m_tab_size = 0;
+}
+
+FxDynamicMove::~FxDynamicMove()
+{
+ FREE(m_wmul);
+ FREE(m_tab);
+ FREE(last_m_tab);
+ FREE(alpha_table);
+}
+
+int FxDynamicMove::render(Layer *l, int _w, int _h, int *input, int tw, int th, int twpitch)
+{
+ double var_x;
+ double var_y;
+ double var_d;
+ double var_r;
+
+
+/*if (fx_canvas) {
+ HDC dc;
+ dc = GetDC(NULL);
+ BitBlt(dc, 0, 0, w, h, fx_canvas->getHDC(),0, 0, SRCCOPY);
+ ReleaseDC(NULL, dc);
+ }*/
+
+ prepareCanvas(_w, _h);
+
+ int w_adj=(tw-2)<<16;
+ int h_adj=(th-2)<<16;
+ int dowrap=wrap;
+ int XRES=m_xres+1;
+ int YRES=m_yres+1;
+ int ignore_last_compare=0;
+
+ if (XRES > _w) XRES=_w;
+ if (YRES > _h) YRES=_h;
+ if (XRES < 2) XRES=2;
+ if (XRES > 256) XRES=256;
+ if (YRES < 2) YRES=2;
+ if (YRES > 256) YRES=256;
+ if (need_flush || m_lasth != th || m_lastpitch != twpitch || m_lastw != tw || !m_tab || !m_wmul || m_lastxres != XRES || m_lastyres != YRES)
+ {
+ int y;
+ m_lastxres = XRES;
+ m_lastyres = YRES;
+ m_lastw=tw;
+ m_lasth=th;
+ m_lastpitch=twpitch;
+ FREE(m_wmul);
+ m_wmul=(int*)MALLOC(sizeof(int)*th);
+ for (y = 0; y < th; y ++) m_wmul[y]=y*twpitch;
+ FREE(m_tab);
+ FREE(last_m_tab);
+ m_tab_size = (XRES*YRES*3 + XRES*6 + 6)*sizeof(int);
+ m_tab=(int*)MALLOC(m_tab_size);
+ last_m_tab=(int*)MALLOC(m_tab_size);
+ ignore_last_compare=1;
+ }
+ need_flush=false;
+ int isblend=blend;
+
+ int issub=subpixel;
+ if (!issub)
+ {
+ w_adj=(tw-1)<<16;
+ h_adj=(th-1)<<16;
+ }
+ if (w_adj<0) w_adj=0;
+ if (h_adj<0) h_adj=0;
+
+ {
+ int x;
+ int y;
+ int *tabptr=m_tab;
+
+ double xsc=2.0/tw,ysc=2.0/th;
+ double dw2=((double)tw*32768.0);
+ double dh2=((double)th*32768.0);
+ double max_screen_d=sqrt((double)(tw*tw+th*th))*0.5;
+
+ double divmax_d=1.0/max_screen_d;
+
+ max_screen_d *= 65536.0;
+
+ double _var_alpha = 0.50;
+ int yc_pos, yc_dpos, xc_pos, xc_dpos;
+ yc_pos=0;
+ xc_dpos = (tw<<16)/(XRES-1);
+ yc_dpos = (th<<16)/(YRES-1);
+ for (y = 0; y < YRES; y ++)
+ {
+ xc_pos=0;
+ for (x = 0; x < XRES; x ++)
+ {
+ double xd,yd;
+
+ xd=((double)xc_pos-dw2)*(1.0/65536.0);
+ yd=((double)yc_pos-dh2)*(1.0/65536.0);
+
+ xc_pos+=xc_dpos;
+
+ var_x=xd*xsc;
+ var_y=yd*ysc;
+ var_d=sqrt(xd*xd+yd*yd)*divmax_d;
+ var_r=atan2(yd,xd) + M_PI*0.5;
+
+ double _var_r=var_r, _var_d=var_d;
+ if (isblend && need_alpha) {
+ _var_alpha = l->fx_onGetPixelA(var_r, var_d, var_x, var_y);
+ alpha_table[y*YRES+x] = _var_alpha;
+ } else if (isblend && !need_alpha) {
+ _var_alpha = alpha_table[y*YRES+x];
+ }
+ if (!rectcoords) {
+ double t_var_r = l->fx_onGetPixelR(var_r, var_d, var_x, var_y);
+ _var_d = l->fx_onGetPixelD(var_r, var_d, var_x, var_y);
+ _var_r = t_var_r;
+ }
+ double _var_x=var_x, _var_y=var_y;
+ if (rectcoords) {
+ double t_var_x = l->fx_onGetPixelX(var_r, var_d, var_x, var_y);
+ _var_y = l->fx_onGetPixelY(var_r, var_d, var_x, var_y);
+ _var_x = t_var_x;
+ }
+
+ int tmp1,tmp2,tmp3;
+ if (!rectcoords)
+ {
+ _var_d *= max_screen_d;
+ _var_r -= M_PI*0.5;
+ tmp1=(int) (dw2 + cos(_var_r) * _var_d);
+ tmp2=(int) (dh2 + sin(_var_r) * _var_d);
+ }
+ else
+ {
+ tmp1=(int) ((_var_x+1.0)*dw2);
+ tmp2=(int) ((_var_y+1.0)*dh2);
+ }
+ if (!dowrap)
+ {
+ if (tmp1 < 0) tmp1=0;
+ if (tmp1 > w_adj) tmp1=w_adj;
+ if (tmp2 < 0) tmp2=0;
+ if (tmp2 > h_adj) tmp2=h_adj;
+ }
+ *tabptr++ = tmp1;
+ *tabptr++ = tmp2;
+ tmp3 = (int)(_var_alpha*65536.0*256.0);
+ if (tmp3 < 0) tmp3=0;
+ if (tmp3 > 0xff0000) tmp3=0xff0000;
+ *tabptr++=tmp3;
+ }
+ yc_pos+=yc_dpos;
+ }
+ if (alpha_once)
+ need_alpha=0;
+ }
+
+ if (can_cache && !ignore_last_compare && !MEMCMP(m_tab, last_m_tab, m_tab_size)) {
+ // cached, do nothing
+ // DebugString("cache hit!\n");
+ } else {
+ MEMCPY(last_m_tab, m_tab, m_tab_size);
+
+ // yay, the table is generated. now we do a fixed point
+ // interpolation of the whole thing and pray.
+ {
+ int *interptab=m_tab+XRES*YRES*3;
+ int *rdtab=m_tab;
+ unsigned int *in=(unsigned int *)input;
+ unsigned int *blendin=(unsigned int *)input;
+ unsigned int *out=(unsigned int *)fx_canvas.getBits();
+ int yseek=1;
+ int xc_dpos, yc_pos=0, yc_dpos;
+ xc_dpos=(tw<<16)/(XRES-1);
+ yc_dpos=(th<<16)/(YRES-1);
+ int lypos=0;
+ int yl=_h;
+ while (yl>0)
+ {
+ yc_pos+=yc_dpos;
+ yseek=(yc_pos>>16)-lypos;
+ if (!yseek) return 0;
+ lypos=yc_pos>>16;
+ int l=XRES;
+ int *stab=interptab;
+ int xr3=XRES*3;
+ while (l--)
+ {
+ int tmp1, tmp2,tmp3;
+ tmp1=rdtab[0];
+ tmp2=rdtab[1];
+ tmp3=rdtab[2];
+ stab[0]=tmp1;
+ stab[1]=tmp2;
+ stab[2]=(rdtab[xr3]-tmp1)/yseek;
+ stab[3]=(rdtab[xr3+1]-tmp2)/yseek;
+ stab[4]=tmp3;
+ stab[5]=(rdtab[xr3+2]-tmp3)/yseek;
+ rdtab+=3;
+ stab+=6;
+ }
+
+ if (yseek > yl) yseek=yl;
+ yl-=yseek;
+
+ if (yseek > 0) while (yseek--)
+ {
+ int d_x;
+ int d_y;
+ int d_a;
+ int ap;
+ int seek;
+ int *seektab=interptab;
+ int xp,yp;
+ int l=_w;
+ int lpos=0;
+ int xc_pos=0;
+ while (l>0)
+ {
+ xc_pos+=xc_dpos;
+ seek=(xc_pos>>16)-lpos;
+ if (!seek)
+ {
+ #ifndef NO_MMX
+ Blenders::BLEND_MMX_END();
+ #endif
+ return 0;
+ }
+ lpos=xc_pos>>16;
+ xp=seektab[0];
+ yp=seektab[1];
+ ap=seektab[4];
+ d_a=(seektab[10]-ap)/(seek);
+ d_x=(seektab[6]-xp)/(seek);
+ d_y=(seektab[7]-yp)/(seek);
+ seektab[0] += seektab[2];
+ seektab[1] += seektab[3];
+ seektab[4] += seektab[5];
+ seektab+=6;
+
+ if (seek>l) seek=l;
+ l-=seek;
+ if (seek>0)
+ {
+ // normal loop
+ #define NORMAL_LOOP(Z) while (seek--) { Z; xp+=d_x; yp+=d_y; }
+
+ // wrapping loop
+ #define WRAPPING_LOOPS(Z) \
+ if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp < 0) yp += h_adj; Z) \
+ else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp >= h_adj) yp-=h_adj; Z) \
+ else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp < 0) yp += h_adj; Z) \
+ else NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp >= h_adj) yp-=h_adj; Z)
+
+
+ // this is uber gay. J1, D4, L or J1_MMX, D4_MMX, L_MMX
+ #define LOOPS(DO,J1,D4,L) \
+ if ((isblend&2) && issub) DO(*out++=Blenders::BLEND_AD##J1(Blenders::BLEN##D4(in+(xp>>16)+m_wmul[yp>>16],twpitch,xp,yp),*blendin++,ap>>16); ap+=d_a) \
+ else if (isblend&2) DO(*out++=Blenders::BLEND_AD##J1(in[(xp>>16)+m_wmul[yp>>16]],*blendin++,ap>>16); ap+=d_a) \
+ else if (isblend && issub) DO(*out++=Blenders::BLEND_MU##L(Blenders::BLEN##D4(in+(xp>>16)+m_wmul[yp>>16],twpitch,xp,yp),ap>>16); ap+=d_a) \
+ else if (isblend) DO(*out++=Blenders::BLEND_MU##L(in[(xp>>16)+m_wmul[yp>>16]],ap>>16); ap+=d_a) \
+ else if (issub) DO(*out++=Blenders::BLEN##D4(in+(xp>>16)+m_wmul[yp>>16],twpitch,xp,yp)) \
+ else DO(*out++=in[(xp>>16)+m_wmul[yp>>16]])
+
+ if (!dowrap)
+ {
+ #ifndef NO_MMX
+ if (Blenders::MMX_AVAILABLE())
+ {
+ LOOPS(NORMAL_LOOP,J1_MMX,D4_MMX,L_MMX)
+ }
+ else
+ #endif
+ {
+ LOOPS(NORMAL_LOOP,J1,D4,L)
+ }
+ }
+ else // dowrap
+ {
+ xp %= w_adj+1; yp %= h_adj+1;
+ if (xp < 0) xp+=w_adj; if (yp < 0) yp+=h_adj;
+
+ if (d_x < -w_adj || d_x > w_adj) d_x=0; if (d_y < -h_adj || d_y > h_adj) d_y=0;
+
+ #ifndef NO_MMX
+ if (Blenders::MMX_AVAILABLE())
+ {
+ LOOPS(WRAPPING_LOOPS,J1_MMX,D4_MMX,L_MMX)
+ }
+ else
+ #endif
+ {
+ LOOPS(WRAPPING_LOOPS,J1,D4,L)
+ }
+ }
+ }
+ }
+ blendin+=twpitch-_w;
+
+ // adjust final (rightmost elem) part of seektab
+ seektab[0] += seektab[2];
+ seektab[1] += seektab[3];
+ seektab[4] += seektab[5];
+ }
+ }
+ }
+ }
+
+/*HDC dc = GetDC(NULL);
+BitBlt(dc, 0, 0, w, h, fx_canvas->getHDC(),0, 0, SRCCOPY);
+ReleaseDC(NULL, dc);*/
+
+ #ifndef NO_MMX
+ Blenders::BLEND_MMX_END();
+ #endif
+ return 0;
+};
+
+void FxDynamicMove::setWrap(int i) {
+ wrap = i;
+}
+
+void FxDynamicMove::setRect(int i) {
+ rectcoords = i;
+
+}
+void FxDynamicMove::setBilinear(int i) {
+ subpixel = i;
+}
+
+void FxDynamicMove::setAlphaMode(int i) {
+ blend = i;
+}
+
+void FxDynamicMove::setAlphaOnce(int i) {
+ alpha_once = i;
+}
+
+void FxDynamicMove::setGridSize(int x, int y) {
+ m_xres = x;
+ m_yres = y;
+ FREE(alpha_table);
+ alpha_table = (double *)MALLOC((x+1)*(y+1)*sizeof(double));
+ need_alpha = 1;
+}
+
+BltCanvas *FxDynamicMove::getBltCanvas()
+{
+ return &fx_canvas;
+}
+
+void FxDynamicMove::prepareCanvas(int w, int h) {
+ if (w != last_w || h != last_h)
+ {
+ if (cache_w < w || cache_h < h)
+ {
+ cache_w = max(cache_w, w);
+ cache_h = max(cache_h, h);
+ fx_canvas.DestructiveResize(cache_w, cache_h, 32);
+ }
+ last_w = w;
+ last_h = h;
+ }
+}
+
+void FxDynamicMove::setCanCache(int i) {
+ can_cache = i;
+}
+
+void FxDynamicMove::flushCache()
+{
+ need_flush=true;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/fx_dmove.h b/Src/Wasabi/api/skin/widgets/fx_dmove.h
new file mode 100644
index 00000000..dc6356f5
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/fx_dmove.h
@@ -0,0 +1,48 @@
+#ifndef __FX_DMOVE_H
+#define __FX_DMOVE_H
+
+#include "fx.h"
+#include <tataki/canvas/bltcanvas.h>
+
+class Layer;
+
+class FxDynamicMove : public Fx {
+ public:
+
+ FxDynamicMove();
+ ~FxDynamicMove();
+
+ virtual int render(Layer *l, int _w, int _h, int *input, int tw, int th, int twpitch);
+ virtual void setWrap(int i);
+ virtual void setRect(int i);
+ virtual void setBilinear(int i);
+ virtual void setAlphaMode(int i);
+ virtual void setAlphaOnce(int i);
+ virtual void setCanCache(int i);
+ virtual void setGridSize(int x, int y);
+ virtual BltCanvas *getBltCanvas();
+ virtual void prepareCanvas(int w, int h);
+ virtual void flushCache();
+ private:
+
+ BltCanvas fx_canvas;
+ int last_w, last_h;
+ int cache_w, cache_h;
+
+ int m_lastw,m_lasth;
+ int m_lastxres, m_lastyres, m_xres, m_yres, m_lastpitch;
+ int *m_wmul;
+ int *m_tab;
+ int *last_m_tab;
+ int m_tab_size;
+ int subpixel,rectcoords,blend,wrap;
+ int inited;
+ int need_alpha;
+ int alpha_once;
+ int can_cache;
+ bool need_flush;
+ double *alpha_table;
+
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/group.cpp b/Src/Wasabi/api/skin/widgets/group.cpp
new file mode 100644
index 00000000..d0827ef5
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/group.cpp
@@ -0,0 +1,1753 @@
+#include <precomp.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/popup.h>
+#include <api/wndmgr/layout.h>
+#include <api/skin/skinparse.h>
+//#include <api/skin/widgets/button.h>
+//#include <api/core/buttons.h>
+#include <api/wnd/wndtrack.h>
+#include <api/wac/compon.h>
+#include <api/skin/skin.h>
+#include <api/wnd/notifmsg.h>
+#include <api/config/items/intarray.h>
+#include <api/config/items/cfgitem.h>
+#include <api/config/items/attribute.h>
+#include <api/wndmgr/layout.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <bfc/util/profiler.h>
+#include <api/wndmgr/resize.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <api/wnd/PaintCanvas.h>
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x20A
+#endif
+
+const wchar_t groupXuiObjectStr[] = L"Group"; // This is the xml tag
+char groupXuiSvcName[] = "Group xui object"; // this is the name of the xuiservice
+
+#ifdef WASABI_COMPILE_CONFIG
+const wchar_t cfgGroupXuiObjectStr[] = L"CfgGroup"; // This is the xml tag
+char cfgGroupXuiSvcName[] = "CfgGroup xui object"; // this is the name of the xuiservice
+#endif
+
+XMLParamPair Group::groupParams[] =
+ {
+ {XUIGROUP_AUTOHEIGHTSOURCE, L"AUTOHEIGHTSOURCE"},
+ {XUIGROUP_AUTOWIDTHSOURCE, L"AUTOWIDTHSOURCE"},
+ {XUIGROUP_BACKGROUND, L"BACKGROUND"},
+ {XUIGROUP_DRAWBACKGROUND, L"DRAWBACKGROUND"},
+ {XUIGROUP_DEFAULT_W, L"DEFAULT_W"},
+ {XUIGROUP_DEFAULT_H, L"DEFAULT_H"},
+ {XUIGROUP_DESIGN_H, L"DESIGN_H"},
+ {XUIGROUP_DESIGN_W, L"DESIGN_W"},
+ {XUIGROUP_EMBED_XUI, L"EMBED_XUI"},
+ {XUIGROUP_INHERIT_CONTENT, L"INHERIT_CONTENT"},
+ {XUIGROUP_INHERIT_GROUP, L"INHERIT_GROUP"},
+ {XUIGROUP_INSTANCEID, L"INSTANCEID"},
+ {XUIGROUP_LOCKMINMAX, L"LOCKMINMAX"},
+ {XUIGROUP_MAXIMUM_H, L"MAXIMUM_H"},
+ {XUIGROUP_MAXIMUM_W, L"MAXIMUM_W"},
+ {XUIGROUP_MINIMUM_H, L"MINIMUM_H"},
+ {XUIGROUP_MINIMUM_W, L"MINIMUM_W"},
+ {XUIGROUP_NAME, L"NAME"},
+ {XUIGROUP_PROPAGATESIZE, L"PROPAGATESIZE"},
+ {XUIGROUP_XUITAG, L"XUITAG"},
+ };
+
+Group::Group()
+{
+ scripts_enabled = 1;
+ getScriptObject()->vcpu_setInterface(groupGuid, (void *)static_cast<Group *>(this));
+ getScriptObject()->vcpu_setClassName(L"Group");
+ getScriptObject()->vcpu_setController(groupController);
+ background = NULL;
+ skinpart = 0;
+ captured = 0; resizing = 0;
+ x = 0; y = 0;
+ size_w = 0; size_h = 0;
+ lockminmax = 0;
+ propagatesize = 0;
+ reg = NULL;
+ default_h = AUTOWH;
+ default_w = AUTOWH;
+ // allreg = NULL;
+ // subregionlayers = new PtrList<api_window>;
+ // subregiongroups = new PtrList<api_window>;
+ deleting = 0;
+ moving = 0;
+ drawbackground = 0;
+ groupmaxheight = AUTOWH;
+ groupmaxwidth = AUTOWH;
+ groupminheight = AUTOWH;
+ groupminwidth = AUTOWH;
+ // regionop = 0;
+ // allsubreg = NULL;
+ groups.addItem(this);
+ scaledreg = NULL;
+ scaledregionvalid = 0;
+ autoregionop = 1;
+ setRectRgn(0);
+ disable_update_pos = 0;
+ no_init_on_addchild = 0;
+ lastheightsource = lastwidthsource = NULL;
+ lastgetwidthbasedon = lastgetheightbasedon = AUTOWH;
+ content_item = NULL;
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ design_w = AUTOWH;
+ design_h = AUTOWH;
+}
+
+void Group::CreateXMLParameters(int master_handle)
+{
+ //GROUP_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(groupParams) / sizeof(groupParams[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ {
+ addParam(xuihandle, groupParams[i], XUI_ATTRIBUTE_IMPLIED);
+ }
+}
+
+Group::~Group()
+{
+ deleteScripts();
+ deleting = 1;
+ WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+ while (gui_objects.getNumItems() > 0)
+ {
+ SkinParser::destroyGuiObject(gui_objects.enumItem(0));
+ gui_objects.removeByPos(0);
+ }
+ delete background;
+ delete reg;
+ delete scaledreg;
+ xuiparams.deleteAll();
+ /* subregionlayers->removeAll();
+ delete subregionlayers;
+ subregiongroups->removeAll();
+ delete subregiongroups;*/
+ groups.removeItem(this);
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
+}
+
+int Group::isGroup(Group *o)
+{
+ return groups.haveItem(o);
+}
+
+int Group::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (!WCSICMP(paramname, L"id") && !instanceid.isempty())
+ return GROUP_PARENT::setXmlParam(paramname, instanceid);
+ return GROUP_PARENT::setXmlParam(paramname, strvalue);
+}
+
+int Group::setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (xuihandle == _xuihandle)
+ {
+ switch (xuiid)
+ {
+ case XUIGROUP_INSTANCEID:
+ instanceid = strvalue;
+ getGuiObject()->guiobject_setId(instanceid);
+ return 1;
+ case XUIGROUP_BACKGROUND:
+ setBaseTexture(strvalue);
+ setDrawBackground(1);
+ return 1;
+ case XUIGROUP_DRAWBACKGROUND:
+ setDrawBackground(WTOI(strvalue));
+ return 1;
+ case XUIGROUP_DEFAULT_W:
+ {
+ int w = WTOI(strvalue);
+ //getGuiObject()->guiobject_setGuiPosition(NULL, NULL, &w, NULL, NULL, NULL, NULL, NULL);
+ default_w = w;
+ return 1;
+ }
+ case XUIGROUP_DEFAULT_H:
+ {
+ int h = WTOI(strvalue);
+ //getGuiObject()->guiobject_setGuiPosition(NULL, NULL, NULL, &h, NULL, NULL, NULL, NULL);
+ default_h = h;
+ return 1;
+ }
+
+ case XUIGROUP_MAXIMUM_H:
+ groupmaxheight = WTOI(strvalue);
+ return 1;
+ case XUIGROUP_MAXIMUM_W:
+ groupmaxwidth = WTOI(strvalue);
+ return 1;
+ case XUIGROUP_MINIMUM_H:
+ groupminheight = WTOI(strvalue);
+ return 1;
+ case XUIGROUP_MINIMUM_W:
+ groupminwidth = WTOI(strvalue);
+ return 1;
+ case XUIGROUP_PROPAGATESIZE:
+ propagatesize = WTOI(strvalue);
+ return 1;
+ case XUIGROUP_LOCKMINMAX:
+ lockminmax = WTOI(strvalue);
+ return 1;
+ case XUIGROUP_NAME:
+ setName(strvalue);
+ return 1;
+ case XUIGROUP_AUTOWIDTHSOURCE:
+ setAutoWidthSource(strvalue);
+ return 1;
+ case XUIGROUP_AUTOHEIGHTSOURCE:
+ setAutoHeightSource(strvalue);
+ return 1;
+ case XUIGROUP_EMBED_XUI:
+ xui_embedded_id = strvalue;
+ return 1;
+ case XUIGROUP_XUITAG:
+ return 1;
+ case XUIGROUP_INHERIT_GROUP:
+ return 1;
+ case XUIGROUP_INHERIT_CONTENT:
+ return 1;
+ case XUIGROUP_DESIGN_W:
+ setDesignWidth(WTOI(strvalue));
+ return 1;
+ case XUIGROUP_DESIGN_H:
+ setDesignHeight(WTOI(strvalue));
+ return 1;
+ }
+ }
+ return GROUP_PARENT::setXuiParam(_xuihandle, xuiid, paramname, strvalue);
+}
+
+void Group::setDesignWidth(int w)
+{
+ design_w = w;
+ if (isPostOnInit())
+ onResize();
+}
+
+void Group::setDesignHeight(int h)
+{
+ design_h = h;
+ if (isPostOnInit())
+ onResize();
+}
+
+int Group::getDesignWidth()
+{
+ return design_w;
+}
+
+int Group::getDesignHeight()
+{
+ return design_h;
+}
+
+int Group::onPostedMove()
+{
+ return GROUP_PARENT::onPostedMove();
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void Group::beginMove()
+{
+ if (getGuiObject()->guiobject_getParentGroup())
+ getGuiObject()->guiobject_getParentGroup()->beginMove();
+}
+
+void Group::beginScale()
+{
+ if (getGuiObject()->guiobject_getParentGroup())
+ getGuiObject()->guiobject_getParentGroup()->beginScale();
+}
+
+void Group::beginResize()
+{
+ if (getGuiObject()->guiobject_getParentGroup())
+ getGuiObject()->guiobject_getParentGroup()->beginResize();
+}
+
+void Group::endMove()
+{
+ if (getGuiObject()->guiobject_getParentGroup())
+ getGuiObject()->guiobject_getParentGroup()->endMove();
+}
+
+void Group::endScale()
+{
+ if (getGuiObject()->guiobject_getParentGroup())
+ getGuiObject()->guiobject_getParentGroup()->endScale();
+}
+
+void Group::endResize()
+{
+ if (getGuiObject()->guiobject_getParentGroup())
+ getGuiObject()->guiobject_getParentGroup()->endResize();
+}
+#endif
+
+void Group::onMinMaxEnforcerChanged()
+{
+ if (!isPostOnInit()) return ;
+ int min_x = getPreferences(MINIMUM_W);
+ int min_y = getPreferences(MINIMUM_H);
+ int max_x = getPreferences(MAXIMUM_W);
+ int max_y = getPreferences(MAXIMUM_H);
+ int sug_x = getPreferences(SUGGESTED_W);
+ int sug_y = getPreferences(SUGGESTED_H);
+ min_x = MAX(RESIZE_MINW, min_x);
+ min_y = MAX(RESIZE_MINH, min_y);
+
+ RECT r;
+ POINT pt;
+ getClientRect(&r);
+ int w = r.right - r.left;
+ int h = r.bottom - r.top;
+ getPosition(&pt);
+ if ((w < min_x || h < min_y || w > max_x || h > max_y) && (w != sug_x || h != sug_y))
+ {
+ //DebugString("reapplying minmax constraints\n");
+ resize(pt.x, pt.y, sug_x, sug_y);
+ }
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void Group::mouseResize(int x, int y, int resizeway)
+{ // screen coords!
+
+ int min_x = getPreferences(MINIMUM_W);
+ int min_y = getPreferences(MINIMUM_H);
+ int max_x = getPreferences(MAXIMUM_W);
+ int max_y = getPreferences(MAXIMUM_H);
+ int sug_x = getPreferences(SUGGESTED_W);
+ int sug_y = getPreferences(SUGGESTED_H);
+
+ if (max_x != AUTOWH && min_x != AUTOWH && max_x < min_x) max_x = min_x;
+ if (max_y != AUTOWH && min_y != AUTOWH && max_y < min_y) max_y = min_y;
+ if (min_x != AUTOWH && max_x != AUTOWH && min_x > max_x) min_x = max_x;
+ if (min_y != AUTOWH && max_y != AUTOWH && min_y > max_y) min_y = max_y;
+ if (sug_x != AUTOWH && min_x != AUTOWH && sug_x < min_x) sug_x = min_x;
+ if (sug_y != AUTOWH && min_y != AUTOWH && sug_y < min_y) sug_y = min_y;
+ if (sug_x != AUTOWH && max_x != AUTOWH && sug_x > max_x) sug_x = max_x;
+ if (sug_y != AUTOWH && max_y != AUTOWH && sug_y > max_y) sug_y = max_y;
+
+ beginResize();
+
+ int mask = 0;
+ if (resizeway & RESIZE_BOTTOM)
+ {
+ mask |= BOTTOM;
+ }
+ if (resizeway & RESIZE_RIGHT)
+ {
+ mask |= RIGHT;
+ }
+ if (resizeway & RESIZE_TOP)
+ {
+ mask |= TOP;
+ }
+ if (resizeway & RESIZE_LEFT)
+ {
+ mask |= LEFT;
+ }
+
+ min_x = MAX(RESIZE_MINW, min_x);
+ min_y = MAX(RESIZE_MINH, min_y);
+
+ if (renderRatioActive())
+ {
+ if (min_x != AUTOWH) multRatio(&min_x);
+ if (min_y != AUTOWH) multRatio(NULL, &min_y);
+ if (max_x != AUTOWH) multRatio(&max_x);
+ if (max_y != AUTOWH) multRatio(NULL, &max_y);
+ if (sug_x != AUTOWH) multRatio(&sug_x);
+ if (sug_y != AUTOWH) multRatio(NULL, &sug_y);
+ }
+
+ if (min_x == AUTOWH) min_x = -1;
+ if (max_x == AUTOWH) max_x = -1;
+ if (min_y == AUTOWH) min_y = -1;
+ if (max_y == AUTOWH) max_y = -1;
+ if (sug_x == AUTOWH) sug_x = -1;
+ if (sug_y == AUTOWH) sug_y = -1;
+
+ resizeClass rsize(this, min_x, min_y, max_x, max_y, sug_x, sug_y);
+ if (rsize.resizeWindow(this, mask | NOINTERSECT))
+ {
+ RECT r = rsize.getRect();
+
+ if (renderRatioActive())
+ {
+ r.right = (int)(((double)(r.right - r.left) / getRenderRatio()) + r.left + 0.5f);
+ r.bottom = (int)(((double)(r.bottom - r.top) / getRenderRatio()) + r.top + 0.5f);
+ }
+
+ int _min_x = getPreferences(MINIMUM_W);
+ int _min_y = getPreferences(MINIMUM_H);
+ int _max_x = getPreferences(MAXIMUM_W);
+ int _max_y = getPreferences(MAXIMUM_H);
+
+ if (_max_x != AUTOWH && _min_x != AUTOWH && _max_x < _min_x) _max_x = _min_x;
+ if (_max_y != AUTOWH && _min_y != AUTOWH && _max_y < _min_y) _max_y = _min_y;
+ if (_min_x != AUTOWH && _max_x != AUTOWH && _min_x > _max_x) _min_x = _max_x;
+ if (_min_y != AUTOWH && _max_y != AUTOWH && _min_y > _max_y) _min_y = _max_y;
+
+ if (r.right - r.left < _min_x) r.right = r.left + _min_x;
+ if (r.bottom - r.top < _min_y) r.bottom = r.top + _min_y;
+ if (r.right - r.left > _max_x) r.right = r.left + _max_x;
+ if (r.bottom - r.top > _max_y) r.bottom = r.top + _max_y;
+
+ resizeToRect(&r);
+ invalidate();
+ endResize();
+ }
+}
+#endif
+
+void Group::setAutoWidthSource(const wchar_t *obj)
+{
+ autowidthsource = obj;
+}
+
+void Group::setAutoHeightSource(const wchar_t *obj)
+{
+ autoheightsource = obj;
+}
+
+int Group::getAutoWidth()
+{
+ return default_w == AUTOWH ? GROUP_PARENT::getPreferences(SUGGESTED_W) : default_w;
+}
+
+int Group::getAutoHeight()
+{
+ return default_h == AUTOWH ? GROUP_PARENT::getPreferences(SUGGESTED_H) : default_h;
+}
+
+int Group::getWidthBasedOn(GuiObject *o)
+{
+ if (o == NULL)
+ {
+ if (lastwidthsource == NULL)
+ {
+ if (!autowidthsource.isempty())
+ {
+ lastwidthsource = getObject(autowidthsource);
+ }
+ }
+ o = lastwidthsource;
+ }
+ if (o == NULL) return AUTOWH;
+ if (lastgetwidthbasedon != AUTOWH) return lastgetwidthbasedon;
+ int x, rx, w, rw;
+ o->guiobject_getGuiPosition(&x, NULL, &w, NULL, &rx, NULL, &rw, NULL);
+ int p = o->guiobject_getAutoWidth();
+if (w == AUTOWH) { w = p; rw = 0; }
+ if (rx == 0 && rw == 1)
+ lastgetwidthbasedon = p - w;
+ else if (rx == 0 && rw == 0)
+ lastgetwidthbasedon = p + x;
+ else
+ lastgetwidthbasedon = AUTOWH;
+
+ return lastgetwidthbasedon;
+}
+
+int Group::getHeightBasedOn(GuiObject *o)
+{
+ if (o == NULL)
+ {
+ if (lastheightsource == NULL)
+ {
+ if (!autoheightsource.isempty())
+ {
+ lastheightsource = getObject(autoheightsource);
+ }
+ }
+ o = lastheightsource;
+ }
+ if (o == NULL) return AUTOWH;
+ if (lastgetheightbasedon != AUTOWH) return lastgetheightbasedon;
+ int y, ry, h, rh;
+ o->guiobject_getGuiPosition(NULL, &y, NULL, &h, NULL, &ry, NULL, &rh);
+ int p = o->guiobject_getAutoHeight();
+if (h == AUTOWH) { h = p; rh = 0; }
+ if (ry == 0 && rh == 1)
+ lastgetheightbasedon = p - h;
+ else if (ry == 0 && rh == 0)
+ lastgetheightbasedon = h + y;
+ else
+ lastgetheightbasedon = AUTOWH;
+
+ return lastgetheightbasedon;
+}
+
+int Group::getPreferences(int what)
+{
+ int _what = what;
+ if (lockminmax)
+ {
+ if (_what == MAXIMUM_W || _what == MINIMUM_W)
+ _what = SUGGESTED_W;
+ if (_what == MAXIMUM_H || _what == MINIMUM_H)
+ _what = SUGGESTED_H;
+ }
+ switch (_what)
+ {
+ case SUGGESTED_W:
+ {
+ int w, rw;
+ getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, NULL, NULL, NULL, &rw, NULL);
+
+ if (w == AUTOWH)
+ w = getWidthBasedOn();
+
+ if (w == AUTOWH || rw == 1)
+ w = getAutoWidth();
+
+ if (w == AUTOWH && getBaseTexture())
+ w = getBaseTexture()->getWidth();
+
+ if (groupmaxwidth != AUTOWH)
+ {
+ if (groupminwidth != AUTOWH)
+ {
+ return MIN(groupmaxwidth, MAX(groupminwidth, w));
+ }
+ else
+ {
+ return MIN(groupmaxwidth, w);
+ }
+ }
+ else if (groupminwidth != AUTOWH)
+ {
+ return MAX(groupminwidth, w);
+ }
+ return w;
+ }
+ case SUGGESTED_H:
+ {
+ int h, rh;
+ getGuiObject()->guiobject_getGuiPosition(NULL, NULL, NULL, &h, NULL, NULL, NULL, &rh);
+
+ if (h == AUTOWH)
+ h = getHeightBasedOn();
+
+ if (h == AUTOWH || rh == 1)
+ h = getAutoHeight();
+
+ if (h == AUTOWH && getBaseTexture())
+ h = getBaseTexture()->getHeight();
+
+ if (groupmaxheight != AUTOWH)
+ {
+ if (groupminheight != AUTOWH)
+ {
+ return MIN(groupmaxheight, MAX(groupminheight, h));
+ }
+ else
+ {
+ return MIN(groupmaxheight, h);
+ }
+ }
+ else if (groupminheight != AUTOWH)
+ {
+ return MAX(groupminheight, h);
+ }
+ return h;
+ }
+ case MAXIMUM_H:
+ {
+ int h = GROUP_PARENT::getPreferences(what);
+
+ if (h != AUTOWH)
+ return MIN(h, groupmaxheight);
+
+ return groupmaxheight;
+ }
+ case MAXIMUM_W:
+ {
+ int w = GROUP_PARENT::getPreferences(what);
+
+ if (w != AUTOWH)
+ return MIN(w, groupmaxwidth);
+
+ return groupmaxwidth;
+ }
+ case MINIMUM_H:
+ {
+ int h = GROUP_PARENT::getPreferences(what);
+
+ if (h != AUTOWH)
+ return MAX(h, groupminheight);
+
+ return groupminheight;
+ }
+ case MINIMUM_W:
+ {
+ int w = GROUP_PARENT::getPreferences(what);
+
+ if (w != AUTOWH)
+ return MAX(w, groupminwidth);
+
+ return groupminwidth;
+ }
+ }
+ return GROUP_PARENT::getPreferences(what);
+}
+
+void Group::updatePos(GuiObject *o, RECT *r2)
+{
+
+ if (disable_update_pos) return ;
+
+ RECT r;
+ if (r2 == NULL)
+ {
+ getClientRect(&r);
+ r2 = &r;
+ }
+
+
+ double d = getRenderRatio();
+ int w, h;
+ int ox, oy, ow, oh, orx, ory, orw, orh;
+ int ox1, ox2, oy1, oy2, oanchor;
+
+ if (o->guiobject_getAnchoragePosition(&ox1, &oy1, &ox2, &oy2, &oanchor))
+ {
+ // anchorage values have not been translated into native values yet, do it now
+ int x, y, w, h, rx, ry, rw, rh;
+ x = y = w = h = rx = ry = rw = rh = AUTOWH;
+ int lw = ox2 - ox1;
+ int lh = oy2 - oy1;
+ int iw = getDesignWidth();
+ int ih = getDesignHeight();
+ if (iw == AUTOWH || ih == AUTOWH)
+ {
+ Wasabi::Std::messageBox(L"anchor coordinate system used without design size for the parent group.\nYour parent group needs the design_w/design_h parameters if you are using x1/y1/x2/y2/anchor parameters on one of its children\nDefaulting to 320x200", L"XML Error", 0);
+ iw = 320;
+ ih = 200;
+ }
+ int right_m = iw - ox2;
+ int bottom_m = ih - oy2;
+
+ if ((oanchor & ANCHOR_LEFT) == 0 && (oanchor & ANCHOR_RIGHT) == 0) oanchor |= ANCHOR_LEFT;
+ if ((oanchor & ANCHOR_TOP) == 0 && (oanchor & ANCHOR_BOTTOM) == 0) oanchor |= ANCHOR_TOP;
+
+ if (oanchor & ANCHOR_LEFT)
+ {
+ x = ox1;
+ rx = 0;
+ if (oanchor & ANCHOR_RIGHT)
+ {
+ w = -((iw - ox2) + ox1);
+ rw = 1;
+ }
+ else
+ {
+ w = lw;
+ rw = 0;
+ }
+ }
+ else
+ {
+ if (oanchor & ANCHOR_RIGHT)
+ {
+ x = -(right_m + lw);
+ rx = 1;
+ w = lw;
+ rw = 0;
+ }
+ }
+ if (oanchor & ANCHOR_TOP)
+ {
+ y = oy1;
+ ry = 0;
+ if (oanchor & ANCHOR_BOTTOM)
+ {
+ h = -((ih - oy2) + oy1);
+ rh = 1;
+ }
+ else
+ {
+ h = lh;
+ rh = 0;
+ }
+ }
+ else
+ {
+ if (oanchor & ANCHOR_BOTTOM)
+ {
+ y = -(bottom_m + lh);
+ ry = 1;
+ h = lh;
+ rh = 0;
+ }
+ }
+ disable_update_pos = 1;
+ o->guiobject_setGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh);
+ o->guiobject_validateAnchorage();
+ disable_update_pos = 0;
+ }
+
+ o->guiobject_getGuiPosition(&ox, &oy, &ow, &oh, &orx, &ory, &orw, &orh);
+ if (ow == AUTOWH) { ow = o->guiobject_getAutoWidth(); orw = 0; }
+ if (oh == AUTOWH) { oh = o->guiobject_getAutoHeight(); orh = 0; }
+
+ TextInfoCanvas fontInfoCanvas(this);
+ double fontScale = fontInfoCanvas.getSystemFontScale();
+ if (o->guiobject_getAutoSysMetricsX())
+ ox = (int)((float)ox * fontScale);
+
+ if (o->guiobject_getAutoSysMetricsY())
+ oy = (int)((float)oy * fontScale);
+
+ if (o->guiobject_getAutoSysMetricsW())
+ ow = (int)((float)ow * fontScale);
+
+ if (o->guiobject_getAutoSysMetricsH())
+ oh = (int)((float)oh * fontScale);
+
+ if (!o->guiobject_getRootWnd()->handleRatio())
+ {
+ if (orw == 1)
+ w = (int)((float)(r2->right - r2->left + ow) * d);
+ else if (orw == 2)
+ w = (int)(((float)(r2->right - r2->left) * ((float)ow / 100.0f)) * d);
+ else
+ w = (int)((float)(ow) * d);
+ if (orh == 1)
+ h = (int)((float)(r2->bottom - r2->top + oh) * d);
+ else if (orh == 2)
+ h = (int)(((float)(r2->bottom - r2->top) * ((float)oh / 100.0f)) * d);
+ else
+ h = (int)((float)(oh) * d);
+ if (orx == 1)
+ x = (int)((float)(r2->right - r2->left + ox) * d);
+ else if (orx == 2)
+ x = (int)(((float)(r2->right - r2->left) * ((float)ox / 100.0f)) * d);
+ else
+ x = (int)((float)(ox) * d);
+ if (ory == 1)
+ y = (int)((float)(r2->bottom - r2->top + oy) * d);
+ else if (ory == 2)
+ y = (int)(((float)(r2->bottom - r2->top) * ((float)oy / 100.0f)) * d);
+ else
+ y = (int)((float)(oy) * d);
+ x += (int)((float)(r2->left) * d);
+ y += (int)((float)(r2->top) * d);
+ }
+ else
+ {
+ if (orw == 1)
+ w = r2->right - r2->left + ow;
+ else if (orw == 2)
+ w = (int)((float)(r2->right - r2->left) * ((float)ow / 100.0f));
+ else
+ w = ow;
+ if (orh == 1)
+ h = r2->bottom - r2->top + oh;
+ else if (orh == 2)
+ h = (int)((float)(r2->bottom - r2->top) * ((float)oh / 100.0f));
+ else
+ h = oh;
+ if (orx == 1)
+ x = r2->right - r2->left + ox;
+ else if (orx == 2)
+ x = (int)((float)(r2->right - r2->left) * ((float)ox / 100.0f));
+ else
+ x = ox;
+ if (ory == 1)
+ y = r2->bottom - r2->top + oy;
+ else if (ory == 2)
+ y = (int)((float)(r2->bottom - r2->top) * ((float)oy / 100.0f));
+ else
+ y = oy;
+ x += r2->left;
+ y += r2->top;
+ }
+
+ o->guiobject_getRootWnd()->resize(x, y, w, h);
+}
+
+
+int Group::onResize()
+{
+ GROUP_PARENT::onResize();
+ if (!isInited()) return 1;
+
+ RECT wr;
+ getWindowRect(&wr);
+ RECT r2;
+ getClientRect(&r2);
+ size_w = r2.right - r2.left; size_h = r2.bottom - r2.top;
+ for (int i = 0;i < gui_objects.getNumItems();i++)
+ {
+ GuiObject *o = gui_objects.enumItem(i);
+ updatePos(o, &r2);
+ }
+ invalidateScaledReg();
+ return 1;
+}
+
+void Group::invalidateScaledReg()
+{
+ scaledregionvalid = 0;
+ invalidateWindowRegion();
+}
+
+int Group::onInit()
+{
+ GROUP_PARENT::onInit();
+
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
+
+ disable_update_pos = 1;
+ no_init_on_addchild = 1;
+
+ const wchar_t *id = getGroupContentId();
+ SkinItem *item = getGroupContentSkinItem();
+ if ((id && *id) || item != NULL)
+ {
+ SkinParser::fillGroup(this, id, item, 0, 1, scripts_enabled);
+ }
+
+ disable_update_pos = 0;
+ no_init_on_addchild = 0;
+
+ onFillGroup();
+
+ return 1;
+}
+
+void Group::onFillGroup()
+{
+ reloadDefaults();
+ if (xui_embedded_id.len() > 0)
+ embeddedxui_onNewEmbeddedContent();
+}
+
+int Group::onGroupChange(const wchar_t *id)
+{
+ GROUP_PARENT::onGroupChange(id);
+
+ if (!isInited()) return 1;
+ const wchar_t *cid = getGroupContentId();
+ SkinItem *item = getGroupContentSkinItem();
+ if (!(cid && *cid) || item != NULL) return 1;
+
+ if (!WCSICMP(id, cid)) return 1;
+
+ deleteScripts();
+
+ WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+ while (gui_objects.getNumItems() > 0)
+ {
+ SkinParser::destroyGuiObject(gui_objects.enumItem(0));
+ }
+
+ delete background; background = NULL;
+ delete reg; reg = NULL;
+ delete scaledreg; scaledreg = NULL;
+
+ disable_update_pos = 1;
+ no_init_on_addchild = 1;
+
+ SkinParser::fillGroup(this, cid, item, 0, 1, scripts_enabled);
+
+ disable_update_pos = 0;
+ no_init_on_addchild = 0;
+
+ onFillGroup();
+ if (isInited())
+ onResize();
+
+ getGuiObject()->guiobject_onStartup();
+
+ return 1;
+}
+
+void Group::reloadDefaults()
+{
+ getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &size_w, &size_h, NULL, NULL, NULL, NULL);
+ if (size_w == AUTOWH && size_h == AUTOWH)
+ {
+ /* if (!background) {
+ size_w = 250;
+ size_h = 100;
+ } else {
+ size_w = background->getWidth();
+ size_h = background->getHeight();
+ }*/
+ if (background)
+ {
+ setPreferences(SUGGESTED_W, background->getWidth());
+ setPreferences(SUGGESTED_H, background->getHeight());
+ }
+ size_w = GROUP_PARENT::getPreferences(SUGGESTED_W);
+ size_h = GROUP_PARENT::getPreferences(SUGGESTED_H);
+ }
+ //setName(getGuiObject()->guiobject_getId());
+
+ if (propagatesize)
+ {
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l) l->addMinMaxEnforcer(this);
+ }
+
+ int i;
+ for (i = 0;i < gui_objects.getNumItems();i++)
+ {
+
+ GuiObject *o = gui_objects.enumItem(i);
+
+ if (o->guiobject_getParentGroup())
+ {
+ o->guiobject_getRootWnd()->setParent(o->guiobject_getParentGroup());
+ if (!o->guiobject_getRootWnd()->isInited())
+ {
+ o->guiobject_getRootWnd()->init(o->guiobject_getParentGroup());
+ o->guiobject_getParentGroup()->onCreateObject(getGuiObject());
+ }
+ }
+ }
+
+ /* if (getGuiObject()->guiobject_getParentGroup() && regionop)
+ getGuiObject()->guiobject_getParentGroup()->addSubRegionGroup(this);*/
+
+ invalidateWindowRegion();
+
+ startScripts();
+
+ for (i = 0;i < gui_objects.getNumItems();i++)
+ {
+ GuiObject *o = gui_objects.enumItem(i);
+ o->guiobject_onStartup();
+ }
+
+ autoResize();
+
+ const wchar_t *name = getName();
+ if (name != NULL)
+ onSetName();
+}
+
+void Group::startScripts()
+{
+ for (int i = 0;i < getNumScripts();i++)
+ {
+ int vcpuid = enumScript(i);
+ SystemObject *o = SOM::getSystemObjectByScriptId(vcpuid);
+ if (o != NULL)
+ {
+ o->onLoad();
+ foreach(xuiparams)
+ XuiParam *p = xuiparams.getfor();
+ o->onSetXuiParam(p->param, p->value);
+ endfor;
+ }
+ }
+}
+
+int Group::onPaint(Canvas *canvas)
+{
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ GROUP_PARENT::onPaint(canvas);
+ RECT r;
+ if (!canvas->getClipBox(&r))
+ getClientRect(&r);
+
+
+ if (getDrawBackground()) RenderBaseTexture(canvas, r);
+ return 1;
+}
+
+ifc_window *Group::getBaseTextureWindow()
+{
+ if (reg && !reg->isEmpty()) return this;
+ if (getParent()) return getParent()->getBaseTextureWindow();
+ return this;
+}
+
+void Group::autoResize()
+{
+ int w = getWidthBasedOn();
+ int h = getHeightBasedOn();
+ if (h == AUTOWH && w == AUTOWH) return ;
+ resize(NOCHANGE, NOCHANGE, w == AUTOWH ? NOCHANGE : w, h == AUTOWH ? NOCHANGE : h);
+}
+
+int Group::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)
+{
+ if (msg == ChildNotify::AUTOWHCHANGED)
+ {
+ if (lastwidthsource && child == lastwidthsource->guiobject_getRootWnd() ||
+ lastheightsource && child == lastheightsource->guiobject_getRootWnd())
+ {
+ lastgetwidthbasedon = AUTOWH;
+ lastgetheightbasedon = AUTOWH;
+ autoResize();
+ }
+ }
+ if (!getParent())
+ return 0;
+ return getParent()->childNotify(child, msg, p1, p2);
+}
+
+
+void Group::sendNotifyToAllChildren(int notifymsg, intptr_t param1, intptr_t param2)
+{
+ for (int i = 0;i < gui_objects.getNumItems();i++)
+ gui_objects.enumItem(i)->guiobject_getRootWnd()->childNotify(this, notifymsg, param1, param2);
+}
+
+void Group::addScript(int scriptid)
+{
+ scripts.addItem(scriptid);
+}
+
+int Group::getNumScripts()
+{
+ return scripts.getNumItems();
+}
+
+int Group::enumScript(int n)
+{
+ return scripts.enumItem(n);
+}
+
+void Group::deleteScripts()
+{
+ for (int i = 0;i < scripts.getNumItems();i++)
+ Script::unloadScript(scripts.enumItem(i));
+ scripts.removeAll();
+}
+
+SkinBitmap *Group::getBaseTexture()
+{
+ if (!background) return NULL;
+ return background->getBitmap();
+}
+
+void Group::setBaseTexture(const wchar_t *b, int regis)
+{
+ backgroundstr = b;
+ if (regis) WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+ delete background;
+ background = NULL;
+ if (b != NULL && *b)
+ {
+ background = new AutoSkinBitmap();
+ background->setBitmap(b);
+#ifdef _WIN32
+ RegionI r(background->getBitmap());
+ setRegion(&r);
+#else
+#warning port me!
+#endif
+
+ if (regis) WASABI_API_WND->skin_registerBaseTextureWindow(this, b);
+ }
+ else
+ {
+ delete reg;
+ reg = NULL;
+ delete scaledreg;
+ scaledreg = NULL;
+ invalidateWindowRegion();
+ }
+
+}
+
+const wchar_t *Group::getBackgroundStr()
+{
+ return backgroundstr;
+}
+
+int Group::onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value)
+{
+ int r = GROUP_PARENT::onUnknownXuiParam(xmlattributename, value);
+ if (r == 0)
+ {
+ if (!isInited())
+ {
+ xuiparams.addItem(new XuiParam(xmlattributename, value));
+ }
+ else
+ {
+ for (int i = 0;i < getNumScripts();i++)
+ {
+ int vcpuid = enumScript(i);
+ SystemObject *o = SOM::getSystemObjectByScriptId(vcpuid);
+ if (o != NULL) o->onSetXuiParam(xmlattributename, value);
+ }
+ }
+ }
+ return r;
+}
+
+api_region *Group::getRegion()
+{
+ ensureScaledRegValid();
+ return scaledreg;
+}
+
+void Group::ensureScaledRegValid()
+{
+ if (!scaledregionvalid)
+ {
+ scaledregionvalid = 1;
+ if (!reg) return ;
+ if (!scaledreg) scaledreg = new RegionI;
+ scaledreg->empty();
+ scaledreg->addRegion(reg);
+ RECT rr;
+ getNonClientRect(&rr);
+ if (background)
+ {
+ float w = (float)(rr.right - rr.left) / (float)background->getWidth();
+ float h = (float)(rr.bottom - rr.top) / (float)background->getHeight();
+ if (w && h && (ABS(w - 1.0f) > 0.01f || ABS(h - 1.0f) > 0.01f))
+ scaledreg->scale(w, h, 1);
+ else if (w == 0 || h == 0)
+ {
+ RECT r = {0, 0, 0, 0};
+ scaledreg->setRect(&r);
+ }
+ }
+ }
+}
+
+void Group::setRegion(api_region *r)
+{
+ ASSERT(r != NULL);
+ if (!reg) reg = new RegionI;
+
+ reg->empty();
+ reg->addRegion(r); // background
+
+ invalidateWindowRegion();
+ invalidateScaledReg();
+}
+
+Container *Group::getParentContainer()
+{
+ if (!getGuiObject()->guiobject_getParentGroup())
+ {
+ ifc_window *r = getDesktopParent();
+ if (r != NULL)
+ {
+ //ASSERT(r != NULL);
+ Layout *l = static_cast<Layout *>(r->getInterface(layoutGuid));
+ if (!l) return NULL;
+ return l->getParentContainer();
+ }
+ }
+ Group *g = getGuiObject()->guiobject_getParentGroup();
+ if (g) return g->getParentContainer();
+ return NULL;
+}
+
+ifc_window *Group::enumObjects(int i)
+{
+ if (i >= gui_objects.getNumItems()) return NULL;
+ return gui_objects.enumItem(i)->guiobject_getRootWnd();
+}
+
+int Group::getNumObjects()
+{
+ return gui_objects.getNumItems();
+}
+
+void Group::addChild(GuiObject *g)
+{
+ gui_objects.addItem(g);
+ script_objects.addItem((ScriptObject *)g);
+ g->guiobject_setParentGroup(this);
+ g->guiobject_getRootWnd()->setParent(this);
+ if (!no_init_on_addchild && isInited()
+ && !g->guiobject_getRootWnd()->isInited())
+ g->guiobject_getRootWnd()->init(this);
+}
+
+void Group::removeChild(GuiObject *g)
+{
+ if (!deleting)
+ gui_objects.removeItem(g);
+ script_objects.removeItem((ScriptObject *)g);
+}
+
+void Group::onCreateObject(GuiObject *o)
+{
+ script_vcpu_onCreateObject(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject()));
+}
+
+int Group::getDrawBackground()
+{
+ return drawbackground;
+}
+
+void Group::setDrawBackground(int t)
+{
+ drawbackground = t;
+}
+
+int Group::isLayout()
+{
+ return 0;
+}
+
+int Group::isDesktopAlphaSafe()
+{
+ if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable()) return 0;
+ for (int i = 0;i < getNumObjects();i++)
+ {
+ ifc_window *w = enumObjects(i);
+ Group *cg = static_cast<Group *>(w);
+ if (Group::isGroup(cg))
+ if (!cg->isDesktopAlphaSafe()) return 0;
+ if (!w->handleDesktopAlpha()) return 0;
+ }
+ return 1;
+}
+
+int Group::isTransparencySafe(int excludeme)
+{
+ if (!Wasabi::Std::Wnd::isTransparencyAvailable()) return 0;
+ if (!excludeme && isTransparencyForcedOff()) return 0;
+ for (int i = 0;i < getNumObjects();i++)
+ {
+ ifc_window *w = enumObjects(i);
+ Group *cg = static_cast<Group *>(w);
+ if (Group::isGroup(cg))
+ if (!cg->isTransparencySafe()) return 0;
+ if (!w->handleTransparency()) return 0;
+ }
+ return 1;
+}
+
+GuiObject *Group::getObject(const wchar_t *id)
+{
+ for (int i = 0;i < script_objects.getNumItems();i++)
+ {
+ if (!WCSICMP(id, gui_objects.enumItem(i)->guiobject_getId()))
+ {
+ return gui_objects.enumItem(i);
+ }
+ }
+ return NULL;
+}
+
+void Group::setGroupContent(const wchar_t *id, SkinItem *item, int allowscripts)
+{
+ content_id = id;
+ content_item = item;
+ scripts_enabled = allowscripts;
+}
+
+const wchar_t *Group::getGroupContentId()
+{
+ return content_id;
+}
+
+SkinItem *Group::getGroupContentSkinItem()
+{
+ return content_item;
+}
+
+ScriptObject *Group::script_cast(GUID g)
+{
+ GuiObject *o = embeddedxui_getEmbeddedObject();
+ if (o != NULL)
+ {
+ void *r = o->guiobject_getScriptObject()->vcpu_getInterface(g);
+ if (r != NULL)
+ {
+ return o->guiobject_getScriptObject();
+ }
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+GroupScriptController _groupController;
+GroupScriptController *groupController = &_groupController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GroupScriptController::exportedFunction[] = {
+ {L"getObject", 1, (void*)Group::script_vcpu_getObject },
+ {L"enumObject", 1, (void*)Group::script_vcpu_enumObject },
+ {L"getNumObjects", 0, (void*)Group::script_vcpu_getNumObjects },
+ {L"onCreateObject", 1, (void*)Group::script_vcpu_onCreateObject },
+ {L"getMousePosX", 0, (void*)Group::script_vcpu_getMousePosX },
+ {L"getMousePosY", 0, (void*)Group::script_vcpu_getMousePosY },
+ {L"isLayout", 0, (void*)Group::script_vcpu_isLayout },
+ {L"autoResize", 0, (void*)Group::script_vcpu_autoResize},
+ };
+// --------------------------------------------------------
+
+ScriptObject *GroupScriptController::cast(ScriptObject *o, GUID g)
+{
+ Group *grp = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (grp != NULL)
+ return grp->script_cast(g);
+ return NULL;
+}
+
+const wchar_t *GroupScriptController::getClassName()
+{
+ return L"Group";
+}
+
+const wchar_t *GroupScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+int GroupScriptController::getInstantiable()
+{
+ return 1;
+}
+
+ScriptObject *GroupScriptController::instantiate()
+{
+ return NULL;
+}
+
+void GroupScriptController::destroy(ScriptObject *o)
+{}
+
+void *GroupScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void GroupScriptController::deencapsulate(void *o)
+{}
+
+int GroupScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GroupScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID GroupScriptController::getClassGuid()
+{
+ return groupGuid;
+}
+
+
+const wchar_t *Group::vcpu_getClassName()
+{
+ return L"Group";
+}
+
+
+void Group::addObject(GuiObject *o)
+{
+ addChild(o);
+}
+
+void Group::removeObject(GuiObject *o)
+{
+ removeChild(o);
+}
+
+void Group::setRegionOp(int o)
+{
+ GROUP_PARENT::setRegionOp(o);
+ autoregionop = 0;
+}
+
+void Group::invalidateWindowRegion()
+{
+ GROUP_PARENT::invalidateWindowRegion();
+ if (!isInited() || isLayout()) return ;
+ if (autoregionop)
+ {
+ int yes = 0;
+ for (int i = 0;i < gui_objects.getNumItems();i++)
+ {
+ if (gui_objects.enumItem(i)->guiobject_getRegionOp() != REGIONOP_NONE)
+ {
+ yes = 1;
+ break;
+ }
+ }
+ if (yes)
+ GROUP_PARENT::setRegionOp(REGIONOP_OR);
+ else
+ GROUP_PARENT::setRegionOp(REGIONOP_NONE);
+ }
+}
+
+// VCPU
+
+scriptVar Group::script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, groupController, ob);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, ob);
+}
+
+// Get an object from its ID
+scriptVar Group::script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(obj.type == SCRIPT_STRING); // compiler discarded
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ GuiObject *ob = NULL;
+ if (g)
+ ob = g->getObject(GET_SCRIPT_STRING(obj));
+ return MAKE_SCRIPT_OBJECT(ob ? ob->guiobject_getScriptObject() : NULL);
+}
+
+scriptVar Group::script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (g)
+ {
+ POINT pt;
+ Wasabi::Std::getMousePos(&pt);
+ g->screenToClient(&pt);
+ return MAKE_SCRIPT_INT(pt.x);
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Group::script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (g)
+ {
+ POINT pt;
+ Wasabi::Std::getMousePos(&pt);
+ g->screenToClient(&pt);
+ return MAKE_SCRIPT_INT(pt.y);
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Group::script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (g) return MAKE_SCRIPT_INT(g->getNumObjects());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Group::script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i)
+{
+ SCRIPT_FUNCTION_INIT
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ GuiObject *obj = NULL;
+ if (g)
+ obj = g->gui_objects.enumItem(GET_SCRIPT_INT(i));
+ return MAKE_SCRIPT_OBJECT(obj ? obj->guiobject_getScriptObject() : NULL);
+}
+
+scriptVar Group::script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ return MAKE_SCRIPT_BOOLEAN(g ? g->isLayout() : NULL);
+}
+
+scriptVar Group::script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (g != NULL) g->autoResize();
+ RETURN_SCRIPT_VOID
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+
+int Group::isCfgGroup(Group *ptr)
+{
+ CfgGroup *g = static_cast<CfgGroup *>(ptr);
+ return cfggrouplist.haveItem(g);
+}
+
+#endif
+
+PtrList<CfgGroup> Group::cfggrouplist;
+PtrList<Group> Group::groups;
+
+// ---------------------------------------------------------------
+// Config Groups
+
+
+#ifdef WASABI_COMPILE_CONFIG
+
+CfgGroup::CfgGroup()
+{
+ getScriptObject()->vcpu_setInterface(cfgGroupGuid, (void *)static_cast<CfgGroup *>(this));
+ getScriptObject()->vcpu_setClassName(L"CfgGroup");
+ getScriptObject()->vcpu_setController(cfgGroupController);
+ cfgitem = NULL;
+ cfggrouplist.addItem(this);
+}
+
+CfgGroup::~CfgGroup()
+{
+ if (cfgitem) viewer_delViewItem(cfgitem);
+ cfggrouplist.removeItem(this);
+}
+
+const wchar_t *CfgGroup::vcpu_getClassName()
+{
+ return L"CfgGroup";
+}
+
+void CfgGroup::setAttr(CfgItem *item, const wchar_t *name)
+{
+ if (cfgitem) viewer_delViewItem(cfgitem);
+ cfgitem = item;
+ attrname = name;
+ if (cfgitem != NULL)
+ {
+ wchar_t t[256] = L"";
+ nsGUID::toCharW(cfgitem->getGuid(), t);
+ cfgguid = t;
+ }
+ if (cfgitem) viewer_addViewItem(cfgitem);
+ dataChanged();
+}
+
+int CfgGroup::viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ dataChanged();
+ return 1;
+}
+
+int CfgGroup::onInit()
+{
+ int r = Group::onInit();
+ dataChanged();
+ return r;
+}
+
+void CfgGroup::dataChanged()
+{
+ script_vcpu_onCfgChanged(SCRIPT_CALL, getScriptObject());
+}
+
+CfgItem *CfgGroup::getCfgItem()
+{
+ return cfgitem;
+}
+
+const wchar_t *CfgGroup::getAttributeName()
+{
+ return attrname;
+}
+
+scriptVar CfgGroup::script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ {
+ CfgItem *i = cg->getCfgItem();
+ const wchar_t *attrname = cg->getAttributeName();
+ if (o != NULL && attrname != NULL)
+ return MAKE_SCRIPT_INT(i->getDataAsInt(attrname, 0));
+ }
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar CfgGroup::script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&v));
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ {
+ CfgItem *i = cg->getCfgItem();
+ const wchar_t *attrname = cg->getAttributeName();
+ if (o != NULL && attrname != NULL)
+ {
+ i->setDataAsInt(attrname, GET_SCRIPT_INT(v));
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar CfgGroup::script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ {
+ CfgItem *i = cg->getCfgItem();
+ const wchar_t *a = cg->getAttributeName();
+ *txt = 0;
+ if (!i || !a)
+ return MAKE_SCRIPT_STRING(txt);
+ if (o != NULL && a != NULL)
+ {
+ i->getData(a, txt, 512);
+ }
+ return MAKE_SCRIPT_STRING(txt);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar CfgGroup::script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(!SOM::isNumeric(&v));
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ {
+ CfgItem *i = cg->getCfgItem();
+ const wchar_t *a = cg->getAttributeName();
+ if (!i || !a) RETURN_SCRIPT_VOID;
+ if (o != NULL && a != NULL)
+ {
+ i->setData(a, GET_SCRIPT_STRING(v));
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar CfgGroup::script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ {
+ CfgItem *i = cg->getCfgItem();
+ const wchar_t *attrname = cg->getAttributeName();
+ if (o != NULL && attrname != NULL)
+ return MAKE_SCRIPT_FLOAT((float)i->getDataAsFloat(attrname, 0));
+ }
+ return MAKE_SCRIPT_FLOAT(0);
+}
+
+scriptVar CfgGroup::script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&v));
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ {
+ CfgItem *i = cg->getCfgItem();
+ const wchar_t *attrname = cg->getAttributeName();
+ if (o != NULL && attrname != NULL)
+ {
+ i->setDataAsFloat(attrname, GET_SCRIPT_FLOAT(v));
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar CfgGroup::script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+
+ if (cg)
+ {
+ return MAKE_SCRIPT_STRING(cg->getAttributeName());
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar CfgGroup::script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ CfgGroup *cg = static_cast<CfgGroup *>(o->vcpu_getInterface(cfgGroupGuid));
+ if (cg)
+ return MAKE_SCRIPT_STRING(cg->getCfgGuid());
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+
+scriptVar CfgGroup::script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, cfgGroupController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+CfgGroupScriptController _cfgGroupController;
+CfgGroupScriptController *cfgGroupController = &_cfgGroupController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct CfgGroupScriptController::exportedFunction[] = {
+ {L"cfgGetInt", 0, (void*)CfgGroup::script_vcpu_cfgGetInt },
+ {L"cfgSetInt", 1, (void*)CfgGroup::script_vcpu_cfgSetInt },
+ {L"cfgGetFloat", 0, (void*)CfgGroup::script_vcpu_cfgGetFloat },
+ {L"cfgSetFloat", 1, (void*)CfgGroup::script_vcpu_cfgSetFloat },
+ {L"cfgGetString", 0, (void*)CfgGroup::script_vcpu_cfgGetString },
+ {L"cfgSetString", 1, (void*)CfgGroup::script_vcpu_cfgSetString },
+ {L"onCfgChanged", 0, (void*)CfgGroup::script_vcpu_onCfgChanged },
+ {L"cfgGetName", 0, (void*)CfgGroup::script_vcpu_cfgGetName },
+ {L"cfgGetGuid", 0, (void*)CfgGroup::script_vcpu_cfgGetGuid},
+ };
+
+/*SET_HIERARCHY(Group, SCRIPT_LAYOUT);
+SET_HIERARCHY2(Group, SCRIPT_LAYOUT, LAYOUT_SCRIPTPARENT);*/
+
+const wchar_t *CfgGroupScriptController::getClassName()
+{
+ return L"CfgGroup";
+}
+
+const wchar_t *CfgGroupScriptController::getAncestorClassName()
+{
+ return L"Group";
+}
+
+int CfgGroupScriptController::getInstantiable()
+{
+ return 1;
+}
+
+ScriptObject *CfgGroupScriptController::instantiate()
+{
+ return NULL;
+}
+
+int CfgGroupScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *CfgGroupScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID CfgGroupScriptController::getClassGuid()
+{
+ return cfgGroupGuid;
+}
+
+wchar_t CfgGroup::txt[512] = L"";
+
+#endif // config
diff --git a/Src/Wasabi/api/skin/widgets/group.h b/Src/Wasabi/api/skin/widgets/group.h
new file mode 100644
index 00000000..186541f6
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/group.h
@@ -0,0 +1,365 @@
+#ifndef __GROUP_H
+#define __GROUP_H
+
+#ifndef _NOSTUDIO
+
+class Group;
+class Container;
+class Layout;
+class CfgItem;
+class CfgGroup;
+class SRegion;
+
+#include <bfc/tlist.h>
+#include <bfc/depview.h>
+#include <api/wnd/wndclass/embeddedxui.h>
+#include <api/wnd/wndclass/clickwnd.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <tataki/bitmap/bitmap.h>
+#include <tataki/region/region.h>
+#ifdef WASABI_COMPILE_CONFIG
+#include <api/config/items/cfgitem.h>
+#endif // wasabi_compile_config
+
+#include <api/wndmgr/container.h>
+
+#endif // _nostudio
+
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/script/objects/guiobj.h>
+
+// {80F0F8BD-1BA5-42a6-A093-3236A00C8D4A}
+static const GUID cfgGroupGuid =
+{ 0x80f0f8bd, 0x1ba5, 0x42a6, { 0xa0, 0x93, 0x32, 0x36, 0xa0, 0xc, 0x8d, 0x4a } };
+
+#define RESIZE_MINW 96
+#define RESIZE_MINH 24
+
+class XmlObject;
+
+class GroupScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual int getInstantiable();
+ virtual ScriptObject *cast(ScriptObject *, GUID g);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern GroupScriptController *groupController;
+
+class XuiParam
+{
+ public:
+ XuiParam(const wchar_t *_param, const wchar_t *_value) : param(_param), value(_value) {}
+ virtual ~XuiParam() {}
+ StringW param;
+ StringW value;
+};
+
+#define GROUP_PARENT EmbeddedXuiObject
+
+class Group : public GROUP_PARENT
+{
+public:
+ Group();
+ virtual ~Group();
+
+ int onPaint(Canvas *canvas);
+
+ virtual int onResize();
+ virtual int onPostedMove();
+ virtual int onInit();
+ virtual Container *getParentContainer();
+ virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2);
+
+ virtual void setBaseTexture(const wchar_t *b, int regis=1);
+ virtual SkinBitmap *getBaseTexture();
+ virtual ifc_window *getBaseTextureWindow();
+
+ virtual int setXmlParam(const wchar_t *paramname, const wchar_t *strvalue);
+ virtual int setXuiParam(int _xuihandle, int xuiid, const wchar_t *paramname, const wchar_t *strvalue);
+ virtual api_region *getRegion();
+ virtual void setRegion(api_region *r);
+ void reloadDefaults();
+ virtual int onGroupChange(const wchar_t *id);
+ virtual void autoResize();
+ virtual void startScripts();
+
+ void onCreateObject(GuiObject *o);
+ GuiObject *getObject(const wchar_t *id);
+
+ void sendNotifyToAllChildren(int notifymsg, intptr_t param1, intptr_t param2);
+
+ int isDeleting() { return deleting; }
+
+ void updatePos(GuiObject *o, RECT *r=NULL);
+
+ AutoSkinBitmap *background;
+ int x, y;
+#ifdef _WIN32
+ LPARAM wndHolder_getParentParam(int i=0);
+#endif
+
+ virtual void setDesignWidth(int w);
+ virtual void setDesignHeight(int h);
+ virtual int getDesignWidth();
+ virtual int getDesignHeight();
+
+ virtual void invalidateWindowRegion();
+ virtual void setRegionOp(int o);
+ virtual void setGroupContent(const wchar_t *id, SkinItem *specific_item, int scripts_enabled);
+ virtual const wchar_t *getGroupContentId();
+ virtual SkinItem *getGroupContentSkinItem();
+ virtual void setAutoWidthSource(const wchar_t *obj);
+ virtual void setAutoHeightSource(const wchar_t *obj);
+
+ virtual void cancelCapture() {};
+ virtual int getPreferences(int what);
+
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return groupController; }
+
+ int getNumObjects();
+ ifc_window *enumObjects(int i);
+
+ void addChild(GuiObject *g);
+ void removeChild(GuiObject *g);
+
+#ifdef WASABI_COMPILE_WNDMGR
+ virtual void mouseResize(int x, int y, int resizeway);// screen coords!
+ virtual void beginMove();
+ virtual void beginScale();
+ virtual void beginResize();
+ virtual void endMove();
+ virtual void endScale();
+ virtual void endResize();
+#endif
+
+ virtual int getAutoWidth(void);
+ virtual int getAutoHeight(void);
+
+ virtual int isLayout();
+
+ void setDrawBackground(int t);
+ int getDrawBackground(void);
+
+#ifdef WASABI_COMPILE_CONFIG
+ static int isCfgGroup(Group *ptr);
+#endif
+
+ void addScript(int scriptid);
+ void deleteScripts();
+ int enumScript(int n);
+ int getNumScripts();
+ virtual int isDesktopAlphaSafe();
+ virtual int isTransparencySafe(int excludeme=0);
+
+ static int isGroup(Group *o);
+ const wchar_t *getBackgroundStr();
+ int getWidthBasedOn(GuiObject *o=NULL);
+ int getHeightBasedOn(GuiObject *o=NULL);
+
+ void fixPosition();
+
+ const wchar_t *embeddedxui_getEmbeddedObjectId() { return xui_embedded_id; }
+ virtual void onFillGroup();
+ virtual int onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual ScriptObject *script_cast(GUID g);
+
+ virtual void onMinMaxEnforcerChanged();
+ virtual int isTransparencyForcedOff() { return 0; }
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ static PtrList<CfgGroup> cfggrouplist;
+
+private:
+ StringW basetextureStr;
+ StringW xui_embedded_id;
+
+ void invalidateScaledReg();
+ void ensureScaledRegValid();
+
+ int resizing;
+ int size_w,size_h;
+ int cX,cY;
+ int captured;
+ POINT mousepos;
+ int propagatesize;
+
+ PtrList<XuiParam> xuiparams;
+
+ int moving;
+ int mover;
+ int drawbackground;
+ RECT oldRect;
+ int groupmaxheight;
+ int groupmaxwidth;
+ int groupminheight;
+ int groupminwidth;
+ int lockminmax;
+// int regionop;
+ TList<int> scripts;
+ RegionI *subtractedreg;
+ static PtrList<Group> groups;
+ StringW backgroundstr;
+ StringW instanceid;
+ RegionI *reg;
+ RegionI *scaledreg;
+ int scaledregionvalid;
+ int autoregionop;
+ StringW content_id;
+ SkinItem *content_item;
+ int no_init_on_addchild;
+ StringW autoheightsource;
+ StringW autowidthsource;
+ GuiObject *lastheightsource;
+ GuiObject *lastwidthsource;
+ int lastgetwidthbasedon, lastgetheightbasedon;
+
+ int default_w, default_h;
+ int design_w, design_h;
+ int scripts_enabled;
+ int xuihandle;
+ static XMLParamPair groupParams[];
+protected:
+ enum {
+ XUIGROUP_INSTANCEID=0,
+ XUIGROUP_BACKGROUND,
+ XUIGROUP_DRAWBACKGROUND,
+ XUIGROUP_DEFAULT_W,
+ XUIGROUP_DEFAULT_H,
+ XUIGROUP_MAXIMUM_H,
+ XUIGROUP_MAXIMUM_W,
+ XUIGROUP_MINIMUM_H,
+ XUIGROUP_MINIMUM_W,
+ XUIGROUP_PROPAGATESIZE,
+ XUIGROUP_LOCKMINMAX,
+ XUIGROUP_NAME,
+ XUIGROUP_AUTOWIDTHSOURCE,
+ XUIGROUP_AUTOHEIGHTSOURCE,
+ XUIGROUP_EMBED_XUI,
+ XUIGROUP_XUITAG,
+ XUIGROUP_INHERIT_GROUP,
+ XUIGROUP_INHERIT_CONTENT,
+ XUIGROUP_DESIGN_W,
+ XUIGROUP_DESIGN_H,
+ XUIGROUP_NUMPARAMS,
+ };
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+private:
+ PtrList<ScriptObject> script_objects;
+ PtrList<GuiObject> gui_objects;
+ int deleting;
+ int skinpart;
+ int alpha;
+ int disable_update_pos;
+
+public:
+ void addObject(GuiObject *o);
+ void removeObject(GuiObject *o);
+ void setSkinPartId(int i) { skinpart = i; }
+ int getSkinPartId() { return skinpart; }
+
+ static scriptVar script_vcpu_getObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_vcpu_getNumObjects(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_enumObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar i);
+ static scriptVar script_vcpu_onCreateObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ob);
+ static scriptVar script_vcpu_getMousePosX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getMousePosY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_subtractRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg);
+ static scriptVar script_vcpu_isLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_autoResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static void instantiate(Layout *l);
+
+};
+
+extern const wchar_t groupXuiObjectStr[];
+extern char groupXuiSvcName[];
+class GroupXuiSvc : public XuiObjectSvc<Group, groupXuiObjectStr, groupXuiSvcName> {};
+
+
+#ifdef WASABI_COMPILE_CONFIG
+
+class CfgGroupScriptController : public GroupScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return groupController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual int getInstantiable();
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern CfgGroupScriptController *cfgGroupController;
+
+class CfgGroup : public Group, public DependentViewerTPtr<CfgItem> {
+ public:
+
+ CfgGroup();
+ virtual ~CfgGroup();
+
+ void setAttr(CfgItem *item, const wchar_t *name);
+ const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return cfgGroupController; }
+
+ virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual void dataChanged();
+
+ CfgItem *getCfgItem();
+ const wchar_t *getAttributeName();
+ const wchar_t *getCfgGuid() { return cfgguid; }
+ virtual int onInit();
+
+ static scriptVar script_vcpu_cfgGetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgSetInt(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_cfgGetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgSetFloat(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_cfgGetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgSetString(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_cfgGetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_cfgGetGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onCfgChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+
+ CfgItem *cfgitem;
+ StringW attrname;
+ StringW cfgguid;
+ static wchar_t txt[512];
+};
+
+extern const wchar_t cfgGroupXuiObjectStr[];
+extern char cfgGroupXuiSvcName[];
+class CfgGroupXuiSvc : public XuiObjectSvc<CfgGroup, cfgGroupXuiObjectStr, cfgGroupXuiSvcName> {};
+
+#endif // wasabi_compile_config
+
+
+#endif // group.h
diff --git a/Src/Wasabi/api/skin/widgets/groupclickwnd.cpp b/Src/Wasabi/api/skin/widgets/groupclickwnd.cpp
new file mode 100644
index 00000000..119885bb
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/groupclickwnd.cpp
@@ -0,0 +1,84 @@
+#include <precomp.h>
+#include "groupclickwnd.h"
+#include <api/script/objects//guiobject.h>
+#include <api/wnd/notifmsg.h>
+
+GroupClickWnd::GroupClickWnd() {
+ trap = NULL;
+ inarea = 0;
+}
+
+GroupClickWnd::~GroupClickWnd() {
+ delete trap;
+}
+
+void GroupClickWnd::abstract_onNewContent() {
+ delete trap;
+ trap = NULL;
+
+ if (!abstract_getContent()) return;
+
+ GuiObject *mousetrap = abstract_getContent()->guiobject_findObject(L"mousetrap");
+
+ if (mousetrap != NULL)
+ trap = new MouseTrap(this, mousetrap->guiobject_getScriptObject());
+}
+
+void GroupClickWnd::groupclick_onLeftPush() {
+ notifyParent(ChildNotify::BUTTON_LEFTPUSH);
+}
+
+void GroupClickWnd::groupclick_onRightPush() {
+ notifyParent(ChildNotify::BUTTON_RIGHTPUSH);
+}
+
+void GroupClickWnd::content_onLeftButtonDown() {
+ notifyParent(ChildNotify::CLICKWND_LEFTDOWN);
+}
+
+void GroupClickWnd::content_onLeftButtonUp() {
+ notifyParent(ChildNotify::CLICKWND_LEFTUP);
+ if (inarea) groupclick_onLeftPush();
+}
+
+void GroupClickWnd::content_onRightButtonDown() {
+ notifyParent(ChildNotify::CLICKWND_RIGHTDOWN);
+}
+
+void GroupClickWnd::content_onRightButtonUp() {
+ notifyParent(ChildNotify::CLICKWND_RIGHTUP);
+ if (inarea) groupclick_onRightPush();
+}
+
+void GroupClickWnd::content_onEnterArea() {
+ inarea = 1;
+}
+
+void GroupClickWnd::content_onLeaveArea() {
+ inarea = 0;
+}
+
+
+void MouseTrap::hook_onLeftButtonDown(int x, int y) {
+ window->content_onLeftButtonDown();
+}
+
+void MouseTrap::hook_onLeftButtonUp(int x, int y) {
+ window->content_onLeftButtonUp();
+}
+
+void MouseTrap::hook_onRightButtonDown(int x, int y) {
+ window->content_onRightButtonDown();
+}
+
+void MouseTrap::hook_onRightButtonUp(int x, int y) {
+ window->content_onRightButtonUp();
+}
+
+void MouseTrap::hook_onEnterArea() {
+ window->content_onEnterArea();
+}
+
+void MouseTrap::hook_onLeaveArea() {
+ window->content_onLeaveArea();
+}
diff --git a/Src/Wasabi/api/skin/widgets/groupclickwnd.h b/Src/Wasabi/api/skin/widgets/groupclickwnd.h
new file mode 100644
index 00000000..591f0c7c
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/groupclickwnd.h
@@ -0,0 +1,226 @@
+/* This class simulates a very basic button thru the use of a group. the group needs to have a guiobject (ie: a transparent layer)
+ with id "mousetrap" on top of the rest of its content. */
+
+#ifndef __GROUPCLICKWND_H
+#define __GROUPCLICKWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+
+class MouseTrap;
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class GroupClickWnd : public GuiObjectWnd {
+
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ GroupClickWnd();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~GroupClickWnd();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void content_onLeftButtonDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void content_onLeftButtonUp();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void content_onRightButtonDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void content_onRightButtonUp();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void content_onEnterArea();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void content_onLeaveArea();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void groupclick_onLeftPush();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void groupclick_onRightPush();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void abstract_onNewContent();
+
+ private:
+
+ int inarea;
+ MouseTrap *trap;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class MouseTrap : public H_GuiObject {
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ MouseTrap(GroupClickWnd *w, ScriptObject *obj) : H_GuiObject(obj), window(w) { }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~MouseTrap() {}
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onLeftButtonDown(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onLeftButtonUp(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onRightButtonDown(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onRightButtonUp(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onEnterArea();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onLeaveArea();
+
+ private:
+
+ GroupClickWnd *window;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/grouplist.cpp b/Src/Wasabi/api/skin/widgets/grouplist.cpp
new file mode 100644
index 00000000..c082abc5
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/grouplist.cpp
@@ -0,0 +1,228 @@
+#include <precomp.h>
+#include <api/skin/widgets/group.h>
+#include <api/skin/groupmgr.h>
+#include "grouplist.h"
+#include <api/config/items/cfgitem.h>
+#include <api/wnd/notifmsg.h>
+const wchar_t groupListXuiObjectStr[] = L"GroupList"; // This is the xml tag
+char groupListXuiSvcName[] = "GroupList xui object"; // this is the name of the xuiservice
+
+GroupList::GroupList() {
+ getScriptObject()->vcpu_setInterface(grouplistGuid, (void *)static_cast<GroupList *>(this));
+ getScriptObject()->vcpu_setClassName(L"GroupList");
+ getScriptObject()->vcpu_setController(grouplistController);
+ scrollY = 0;
+ maxheight = 0;
+ maxwidth = 0;
+ redraw=1;
+}
+
+GroupList::~GroupList() {
+ // todo: unload group scripts
+ for (int i=0;i<groups.getNumItems();i++)
+ GroupMgr::destroy(groups.enumItem(i));
+ groups.removeAll();
+}
+
+Group *GroupList::instantiate(const wchar_t *id, int n) {
+ Group *last=NULL;
+ RECT r;
+ getClientRect(&r);
+
+ for (int i=0;i<n;i++) {
+
+ last = GroupMgr::instantiate(id);
+ last->setParent(this);
+ last->init(this);
+
+ groups.addItem(last);
+ }
+
+ reposChildren();
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ invalidate();
+
+ return last;
+}
+
+int GroupList::onResize() {
+ int r = GROUPLIST_PARENT::onResize();
+ reposChildren();
+ return r;
+}
+
+Group *GroupList::enumItem(int n) {
+ return groups.enumItem(n);
+}
+
+void GroupList::removeAll() {
+ for (int i=0;i<groups.getNumItems();i++)
+ GroupMgr::destroy(groups.enumItem(i));
+ groups.removeAll();
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ if (!redraw) return;
+ invalidate();
+}
+
+int GroupList::getNumItems() {
+ return groups.getNumItems();
+}
+
+void GroupList::scrollToPercent(int p) {
+ RECT r;
+ getClientRect(&r);
+ int height = r.bottom - r.top;
+ if (height > maxheight) return;
+ scrollTo((int)((float)(maxheight - height) * (float)p / 100.0f));
+}
+
+void GroupList::scrollTo(int y) {
+ scrollY = y;
+ if (!redraw) return;
+ invalidate();
+}
+
+void GroupList::reposChildren() {
+ if (!redraw) return;
+
+ RECT r;
+ getClientRect(&r);
+
+ int ch = -scrollY+r.top;
+ maxheight = 0;
+
+ for (int i=0;i<getNumItems();i++) {
+
+ Group *g = enumItem(i);
+
+ int h = g->getPreferences(SUGGESTED_H);
+ int w = g->getPreferences(SUGGESTED_W);
+
+ RECT cr;
+ getClientRect(&cr);
+ cr.top = ch;
+ cr.bottom = cr.top + h;
+
+ g->resize(&cr);
+ maxheight += h;
+ if (maxwidth < w) maxwidth = w;
+ ch += h;
+ }
+
+}
+
+void GroupList::setRedraw(int i) {
+ if (redraw == i) return;
+ redraw=i;
+ if (redraw) {
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ reposChildren();
+ invalidate();
+ }
+}
+
+int GroupList::getPreferences(int what) {
+ if (what == SUGGESTED_H) { reposChildren(); return maxheight; }
+ if (what == SUGGESTED_W) { reposChildren(); return maxwidth; }
+ return GROUPLIST_PARENT::getPreferences(what);
+}
+
+
+GroupListScriptController _grouplistController;
+GroupListScriptController *grouplistController = &_grouplistController;
+
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GroupListScriptController ::exportedFunction[] = {
+ {L"instantiate", 2, (void*)GroupList::script_vcpu_instantiate },
+ {L"getNumItems", 0, (void*)GroupList::script_vcpu_getNumItems },
+ {L"enumItem", 1, (void*)GroupList::script_vcpu_enumItem },
+ {L"removeAll", 0, (void*)GroupList::script_vcpu_removeAll },
+ {L"scrollToPercent", 1, (void*)GroupList::script_vcpu_scrollToPercent },
+ {L"setRedraw", 1, (void*)GroupList::script_vcpu_setRedraw},
+};
+
+const wchar_t *GroupListScriptController ::getClassName() {
+ return L"GroupList";
+}
+
+const wchar_t *GroupListScriptController ::getAncestorClassName() {
+ return L"GuiObject";
+}
+
+ScriptObject *GroupListScriptController::instantiate() {
+ GroupList *gl = new GroupList;
+ ASSERT(gl != NULL);
+ return gl->getScriptObject();
+}
+
+void GroupListScriptController::destroy(ScriptObject *o) {
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ ASSERT(gl != NULL);
+ delete gl;
+}
+
+void *GroupListScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for grouplist yet
+}
+
+void GroupListScriptController::deencapsulate(void *o) {
+}
+
+
+int GroupListScriptController ::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GroupListScriptController ::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID GroupListScriptController ::getClassGuid() {
+ return grouplistGuid;
+}
+
+scriptVar GroupList::script_vcpu_instantiate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar n) {
+ SCRIPT_FUNCTION_INIT
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ Group *g = NULL;
+ if (gl) g = gl->instantiate(GET_SCRIPT_STRING(id), GET_SCRIPT_INT(n));
+ return MAKE_SCRIPT_OBJECT(g ? g->getScriptObject() : NULL);
+}
+
+scriptVar GroupList::script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ if (gl) return MAKE_SCRIPT_INT(gl->getNumItems());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar GroupList::script_vcpu_enumItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) {
+ SCRIPT_FUNCTION_INIT
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ Group *g = NULL;
+ if (gl) g = gl->enumItem(GET_SCRIPT_INT(n));
+ return MAKE_SCRIPT_OBJECT(g ? g->getScriptObject() : NULL);
+}
+
+scriptVar GroupList::script_vcpu_removeAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ if (gl) gl->removeAll();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GroupList::script_vcpu_scrollToPercent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) {
+ SCRIPT_FUNCTION_INIT
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ if (gl) gl->scrollToPercent(GET_SCRIPT_INT(n));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar GroupList::script_vcpu_setRedraw(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n) {
+ SCRIPT_FUNCTION_INIT
+ GroupList *gl = static_cast<GroupList *>(o->vcpu_getInterface(grouplistGuid));
+ if (gl) gl->setRedraw(GET_SCRIPT_INT(n));
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/grouplist.h b/Src/Wasabi/api/skin/widgets/grouplist.h
new file mode 100644
index 00000000..9eebf6d4
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/grouplist.h
@@ -0,0 +1,79 @@
+//PORTABLE
+#ifndef _GROUPLIST_H
+#define _GROUPLIST_H
+
+#include <api/script/objects/guiobj.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/ptrlist.h>
+
+// {01E28CE1-B059-11d5-979F-E4DE6F51760A}
+static const GUID grouplistGuid =
+{ 0x1e28ce1, 0xb059, 0x11d5, { 0x97, 0x9f, 0xe4, 0xde, 0x6f, 0x51, 0x76, 0xa } };
+
+#define GROUPLIST_PARENT GuiObjectWnd
+
+class GroupListScriptController: public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern GroupListScriptController *grouplistController;
+
+class GroupList : public GROUPLIST_PARENT {
+public:
+ GroupList();
+ virtual ~GroupList();
+
+ Group *instantiate(const wchar_t *id, int n);
+ void removeAll();
+ Group *enumItem(int n);
+ int getNumItems();
+ void scrollToPercent(int p);
+ void scrollTo(int y);
+ void setRedraw(int i);
+ void reposChildren();
+ virtual int onResize();
+
+ virtual int getPreferences(int what);
+
+private:
+
+ void insert(const wchar_t *id, int where);
+
+public:
+
+ static scriptVar script_vcpu_instantiate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar id, scriptVar n);
+ static scriptVar script_vcpu_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_enumItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_removeAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_scrollToPercent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_vcpu_setRedraw(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+
+ PtrList<Group> groups;
+ int scrollY;
+ int maxheight;
+ int maxwidth;
+ int redraw;
+};
+
+extern const wchar_t groupListXuiObjectStr[];
+extern char groupListXuiSvcName[];
+class GroupListXuiSvc : public XuiObjectSvc<GroupList, groupListXuiObjectStr, groupListXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/grouptgbutton.cpp b/Src/Wasabi/api/skin/widgets/grouptgbutton.cpp
new file mode 100644
index 00000000..b0f22430
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/grouptgbutton.cpp
@@ -0,0 +1,109 @@
+#include <precomp.h>
+#include "grouptgbutton.h"
+#include <api/script/objects/guiobject.h>
+#include <api/wnd/notifmsg.h>
+
+GroupToggleButton::GroupToggleButton() {
+ status = STATUS_OFF;
+}
+
+GroupToggleButton::~GroupToggleButton() {
+}
+
+void GroupToggleButton::setGroups(const wchar_t *_on, const wchar_t *_off) {
+ on_id = _on;
+ on.setContent(on_id);
+ off_id = _off;
+ off.setContent(off_id);
+}
+
+int GroupToggleButton::onInit() {
+ int rt = GROUPTOGGLEBUTTON_PARENT::onInit();
+ initGroups();
+ return rt;
+}
+
+void GroupToggleButton::initGroups() {
+ on.setStartHidden(status == STATUS_ON ? 0 : 1); off.setStartHidden(status == STATUS_ON ? 1 : 0);
+ on.setContent(on_id);
+ off.setContent(off_id);
+ on.setParent(this); off.setParent(this);
+ on.init(this); off.init(this);
+ rootwndholder_setRootWnd(status == STATUS_ON ? &on : &off);
+}
+
+int GroupToggleButton::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+ if (child == &on || child == &off) {
+ switch (msg) {
+ case ChildNotify::BUTTON_LEFTPUSH: {
+ if (wantFullClick()) grouptoggle_onLeftPush();
+ return 1;
+ }
+ case ChildNotify::BUTTON_RIGHTPUSH: {
+ if (wantFullClick()) grouptoggle_onRightPush();
+ return 1;
+ }
+ case ChildNotify::CLICKWND_LEFTDOWN: {
+ if (!wantFullClick()) grouptoggle_onLeftPush();
+ return 1;
+ }
+ case ChildNotify::CLICKWND_RIGHTDOWN: {
+ if (!wantFullClick()) grouptoggle_onRightPush();
+ return 1;
+ }
+ }
+ }
+ return GROUPTOGGLEBUTTON_PARENT::childNotify(child, msg, param1, param2);
+}
+
+void GroupToggleButton::toggle() {
+ if (status == STATUS_OFF) {
+ if (isInited()) {
+ off.setVisible(0);
+ on.setVisible(1);
+ rootwndholder_setRootWnd(&on);
+ }
+ status = STATUS_ON;
+ } else {
+ if (isInited()) {
+ on.setVisible(0);
+ off.setVisible(1);
+ rootwndholder_setRootWnd(&off);
+ }
+ status = STATUS_OFF;
+ }
+ notifyParent(ChildNotify::GROUPCLICKTGBUTTON_TOGGLE, status);
+}
+
+void GroupToggleButton::setStatus(int s) {
+ if (s != status)
+ toggle();
+}
+
+int GroupToggleButton::wantFullClick() {
+ return 0;
+}
+
+void GroupToggleButton::grouptoggle_onLeftPush() {
+ notifyParent(ChildNotify::GROUPCLICKTGBUTTON_CLICKED);
+ if (!wantAutoToggle()) return;
+ if (status == STATUS_ON && !off_id.isempty() || status == STATUS_OFF && !on_id.isempty())
+ toggle();
+}
+
+void GroupToggleButton::grouptoggle_onRightPush() {
+}
+
+GroupClickWnd *GroupToggleButton::enumGroups(int n) {
+ if (n == 0) return &on;
+ if (n == 1) return &off;
+ return NULL;
+}
+
+int GroupToggleButton::getNumGroups() {
+ int i=0;
+ i++;
+ i++;
+ return i;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/grouptgbutton.h b/Src/Wasabi/api/skin/widgets/grouptgbutton.h
new file mode 100644
index 00000000..c9fc8757
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/grouptgbutton.h
@@ -0,0 +1,101 @@
+#ifndef __GROUPTGBUTTON_H
+#define __GROUPTGBUTTON_H
+
+#include <api/skin/widgets/groupclickwnd.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define GROUPTOGGLEBUTTON_PARENT GuiObjectWnd
+
+#define STATUS_OFF 0
+#define STATUS_ON 1
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class GroupToggleButton : public GROUPTOGGLEBUTTON_PARENT {
+
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ GroupToggleButton();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~GroupToggleButton();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+
+
+ virtual void setGroups(const wchar_t *on, const wchar_t *off);
+
+
+ virtual void toggle();
+
+ virtual int wantFullClick();
+
+
+ virtual void grouptoggle_onLeftPush();
+
+ virtual void grouptoggle_onRightPush();
+
+
+ virtual void setStatus(int s);
+
+ virtual int getStatus() { return status; }
+
+ virtual int wantAutoToggle() { return 1; }
+
+ virtual GroupClickWnd *enumGroups(int n);
+
+
+ virtual int getNumGroups();
+
+ private:
+
+
+ void initGroups();
+
+ GroupClickWnd on;
+ GroupClickWnd off;
+
+ StringW on_id, off_id;
+
+ int status;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/grouptips.cpp b/Src/Wasabi/api/skin/widgets/grouptips.cpp
new file mode 100644
index 00000000..c066dca0
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/grouptips.cpp
@@ -0,0 +1,92 @@
+#include "precomp.h"
+#include <bfc/wasabi_std.h>
+#include "grouptips.h"
+#include <api/wnd/api_window.h>
+#include <api/script/objects/c_script/c_group.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/guiobject.h>
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(GroupTips_Svc);
+DECLARE_SERVICETMULTI(svc_toolTipsRenderer, GroupTips);
+END_SERVICES(GroupTips_Svc, _GroupTips_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_GroupTipsSvc; }
+#else
+extern "C" { int __link_GroupTipsSvc; }
+#endif
+
+#endif
+
+GroupTips::GroupTips()
+{
+ tipwnd = NULL;
+}
+
+GroupTips::~GroupTips()
+{
+ if (tipwnd)
+ WASABI_API_SKIN->group_destroy(tipwnd);
+}
+
+int GroupTips::spawnTooltip(const wchar_t *text)
+{
+ int x, y;
+ Wasabi::Std::getMousePos(&x, &y);
+
+ ifc_window *wnd = WASABI_API_SKIN->group_create_layout(L"wasabi.tooltip.group");
+
+ if (wnd)
+ {
+ wnd->setStartHidden(1);
+ wnd->setParent(WASABI_API_WND->main_getRootWnd());
+ wnd->init(WASABI_API_WND->main_getRootWnd(), TRUE);
+ wnd->getGuiObject()->guiobject_onStartup();
+
+ RECT r;
+ wnd->getClientRect(&r);
+ int w = r.right - r.left;
+ int h = r.bottom - r.top;
+
+ y -= h; // move tip above mouse by default
+
+ POINT pt = {x, y};
+ RECT vpr;
+
+ Wasabi::Std::getViewport(&vpr, &pt, NULL, NULL);
+
+ if (x + w > vpr.right) x -= vpr.right - w;
+ if (x < vpr.left) x = vpr.left;
+ if (x + w > vpr.right)
+ {
+ w = vpr.right - vpr.left;
+ x = 0;
+ }
+ if (y + h > vpr.bottom) y -= vpr.bottom - w;
+ if (y < vpr.top) y = vpr.top;
+ if (y + h > vpr.bottom)
+ {
+ h = vpr.bottom - vpr.top;
+ y = 0;
+ }
+
+ wnd->resize(x, y, w, h);
+
+ ScriptObject *group = static_cast<ScriptObject *>(wnd->getInterface(scriptObjectGuid));
+ if (group)
+ {
+ ScriptObject *txt = C_Group(group).getObject(L"tooltip.text");
+ if (txt)
+ C_Text(txt).setText(text);
+ }
+
+ // tooltips should always be on top otherwise they're pointless <dro>
+ Wasabi::Std::Wnd::setTopmost(wnd->getOsWindowHandle(), TRUE);
+ wnd->setVisible(1);
+
+ tipwnd = wnd;
+ }
+ return 1;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/grouptips.h b/Src/Wasabi/api/skin/widgets/grouptips.h
new file mode 100644
index 00000000..0676b1e7
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/grouptips.h
@@ -0,0 +1,23 @@
+#ifndef __GROUPTIPS_H
+#define __GROUPTIPS_H
+
+#include <api/service/svcs/svc_tooltips.h>
+#include <bfc/ptrlist.h>
+#include <api/timer/timerclient.h>
+
+class ifc_window;
+
+int groupTipsTimerProc(int id, void *data1, void *data2);
+
+class GroupTips : public svc_toolTipsRendererI/*, public TimerClientI*/ {
+public:
+ GroupTips();
+ virtual ~GroupTips();
+ static const char *getServiceName() { return "Group tooltip renderer"; }
+
+ virtual int spawnTooltip(const wchar_t *text);
+private:
+ ifc_window *tipwnd;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/guiradiogroup.cpp b/Src/Wasabi/api/skin/widgets/guiradiogroup.cpp
new file mode 100644
index 00000000..a2fc3d68
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/guiradiogroup.cpp
@@ -0,0 +1,36 @@
+#include <precomp.h>
+#include "guiradiogroup.h"
+#include <api/script/objects/c_script/c_button.h>
+#include <api/script/objects/guiobject.h>
+#include <api/script/scriptguid.h>
+
+void GuiRadioGroup::toggleChild(GuiObject *who) {
+ int i, num = children.getNumItems();
+ for (i = 0; i < num; i++) {
+ GuiObject *childGuiObj = children.enumItem(i);
+ if (childGuiObj != NULL) {
+ GuiObject *toggleGuiObj = childGuiObj->guiobject_findObject(L"checkbox.toggle");
+ if (toggleGuiObj != NULL) {
+ C_Button buttonObj(*toggleGuiObj);
+ if (childGuiObj != who) {
+ buttonObj.setActivated(0);
+ }
+ }
+ }
+ }
+}
+
+void GuiRadioGroup::registerChild(GuiObject *who) {
+ children.addItem(who);
+}
+
+int GuiRadioGroup::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (!_wcsicmp(action, L"REGISTER") && source != NULL) {
+ registerChild(static_cast<GuiObject *>(source->getInterface(guiObjectGuid)));
+ } else if (!_wcsicmp(action, L"TOGGLE")) {
+ toggleChild(static_cast<GuiObject *>(source->getInterface(guiObjectGuid)));
+ return 1;
+ }
+ return GUIRADIOGROUP_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/guiradiogroup.h b/Src/Wasabi/api/skin/widgets/guiradiogroup.h
new file mode 100644
index 00000000..d1810593
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/guiradiogroup.h
@@ -0,0 +1,53 @@
+#ifndef __GUIRADIOGROUP_H
+#define __GUIRADIOGROUP_H
+
+#include <api/skin/nakedobject.h>
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+#define GUIRADIOGROUP_PARENT NakedObject
+
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class GuiRadioGroup : public GUIRADIOGROUP_PARENT {
+
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void toggleChild(GuiObject *who);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void registerChild(GuiObject *who);
+
+ // From BaseWnd
+
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ private:
+
+ PtrList<GuiObject> children;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/historyeditbox.cpp b/Src/Wasabi/api/skin/widgets/historyeditbox.cpp
new file mode 100644
index 00000000..bec191fc
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/historyeditbox.cpp
@@ -0,0 +1,152 @@
+#include <precomp.h>
+#include "historyeditbox.h"
+
+XMLParamPair HistoryEditBox::params[] = {
+ {HISTORYEDITBOX_SETNAVBUTTONS, L"NAVBUTTONS"}, // param is implemented by script
+};
+HistoryEditBox::HistoryEditBox() {
+ history_pos = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ setXmlParam(L"navbuttons", L"1"); // so we need to set a default value in the xml param list
+}
+
+void HistoryEditBox::CreateXMLParameters(int master_handle)
+{
+ //HISTORYEDITBOX_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+HistoryEditBox::~HistoryEditBox() {
+ history.deleteAll();
+}
+
+void HistoryEditBox::history_forward() {
+ if (history_pos > 0 && !isListOpen()) {
+ history_pos--;
+ if (history_pos > 0)
+ setText(history.enumItem(history.getNumItems()-history_pos)->getValue(), 1);
+ }
+}
+
+void HistoryEditBox::history_back() {
+ if (!isListOpen() && history_pos < history.getNumItems()) {
+ history_pos++;
+ setText(history.enumItem(history.getNumItems()-history_pos)->getValue(), 1);
+ }
+}
+
+void HistoryEditBox::onEditKeyDown(int vk) {
+ HISTORYEDITBOX_PARENT::onEditKeyDown(vk);
+ if (Std::keyDown(VK_CONTROL)) return;
+ if (vk == VK_DOWN) {
+ history_forward();
+ } else if (vk == VK_UP) {
+ history_back();
+ }
+}
+
+int HistoryEditBox::onInit() {
+ int r = HISTORYEDITBOX_PARENT::onInit();
+#ifdef WASABI_COMPILE_CONFIG
+ loadHistory();
+#endif
+ return r;
+}
+
+void HistoryEditBox::dropdownlist_onCloseList() {
+ HISTORYEDITBOX_PARENT::dropdownlist_onCloseList();
+ history_pos = 0;
+}
+
+void HistoryEditBox::onPreOpenList()
+{
+ HISTORYEDITBOX_PARENT::onPreOpenList();
+ addHistory(getText());
+}
+
+void HistoryEditBox::onEditEnter(const wchar_t *txt)
+{
+ HISTORYEDITBOX_PARENT::onEditEnter(txt);
+ if (Std::keyDown(VK_CONTROL)) return;
+ addHistory(txt);
+}
+
+void HistoryEditBox::addHistory(const wchar_t *txt)
+{
+ HISTORYEDITBOX_PARENT::onEditEnter(txt);
+ history_pos = 0;
+
+ if (!txt || !*txt) return;
+
+ // yay multi-instances on unique history
+#ifdef WASABI_COMPILE_CONFIG
+ loadHistory(0);
+#endif
+
+ foreach(history)
+ StringW *s = history.getfor();
+ if (!_wcsicmp(s->getValue(), txt)) {
+ delete s;
+ history.removeByPos(foreach_index);
+ break;
+ }
+ endfor;
+
+ history.addItem(new StringW(txt));
+
+ while (history.getNumItems() > 64)
+ {
+ StringW *s = history.enumItem(0);
+ delete s;
+ history.removeByPos(1);
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ saveHistory();
+ loadHistory(1);
+#endif
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+void HistoryEditBox::loadHistory(int refill) {
+ history.deleteAll();
+ wchar_t d[256] = {0};
+ wchar_t c[WA_MAX_PATH] = {0};
+ int i;
+ for (i=0;;i++) {
+ StringCbPrintfW(d,sizeof(d), L"%s_history_%d", getId(), i);
+ WASABI_API_CONFIG->getStringPrivate(d, c, WA_MAX_PATH, L"");
+ if (!*c)
+ break;
+ history.addItem(new StringW(c));
+ }
+ if (refill) {
+ deleteAllItems();
+ for (i=history.getNumItems()-1;i>=0;i--) {
+ addItem(history.enumItem(i)->getValue());
+ }
+ }
+}
+
+void HistoryEditBox::saveHistory() {
+ wchar_t d[256] = {0};
+ int i;
+ for (i=0;i<history.getNumItems();i++) {
+ StringCbPrintfW(d, sizeof(d), L"%s_history_%d", getId(), i);
+ WASABI_API_CONFIG->setStringPrivate(d, history.enumItem(i)->getValue());
+ }
+ StringCbPrintfW(d, sizeof(d), L"%s_history_%d", getId(), i);
+ WASABI_API_CONFIG->setStringPrivate(d, L"");
+}
+#endif
+
+int HistoryEditBox::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ int r = HISTORYEDITBOX_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ if (WCSCASEEQLSAFE(action, L"back")) history_back();
+ if (WCSCASEEQLSAFE(action, L"forward")) history_forward();
+ return r;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/historyeditbox.h b/Src/Wasabi/api/skin/widgets/historyeditbox.h
new file mode 100644
index 00000000..2a015738
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/historyeditbox.h
@@ -0,0 +1,58 @@
+#ifndef __HISTORYEDITBOX_H
+#define __HISTORYEDITBOX_H
+
+#include <api/skin/widgets/combobox.h>
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+#define HISTORYEDITBOX_PARENT ComboBox
+
+class HistoryEditBox : public HISTORYEDITBOX_PARENT {
+
+ public:
+
+ HistoryEditBox();
+ virtual ~HistoryEditBox();
+
+ virtual const wchar_t *dropdownlist_getMainGroupId() { return L"wasabi.historyeditbox.main.group"; }
+ virtual const wchar_t *dropdownlist_getListGroupId() { return L"wasabi.historyeditbox.list.group"; }
+ virtual const wchar_t *dropdownlist_getButtonId() { return L"historyeditbox.button"; }
+ virtual const wchar_t *dropdownlist_getListId() { return L"historyeditbox.list"; }
+
+ virtual const wchar_t *combobox_getEditId() { return L"historyeditbox.edit"; }
+
+ void onEditKeyDown(int vk);
+ void onEditEnter(const wchar_t *txt);
+
+ virtual int wantAutoSort() { return 0; }
+
+ virtual int wantDownOpenList() { return history_pos == 0; }
+ virtual void dropdownlist_onCloseList();
+ virtual void onPreOpenList();
+ virtual int onInit();
+ virtual void addHistory(const wchar_t *txt);
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+ void history_back();
+ void history_forward();
+
+ enum {
+ HISTORYEDITBOX_SETNAVBUTTONS=0,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+static XMLParamPair params[];
+#ifdef WASABI_COMPILE_CONFIG
+ void saveHistory();
+ void loadHistory(int refill=1);
+#endif
+
+ PtrList<StringW> history;
+ int history_pos;
+ int xuihandle;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/layer.cpp b/Src/Wasabi/api/skin/widgets/layer.cpp
new file mode 100644
index 00000000..1a119563
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/layer.cpp
@@ -0,0 +1,1727 @@
+#include <precomp.h>
+#include "layer.h"
+#include <api/wndmgr/resize.h>
+#include <api/wnd/cwndtrack.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/layout.h>
+#include <api/wac/compon.h>
+#endif
+#ifdef WASABI_COMPILE_COMPONENTS
+#include <api/script/objects/compoobj.h>
+#endif
+#include <api/skin/skinparse.h>
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+#include <api/skin/widgets/fx_dmove.h>
+#endif
+#include <api/script/objects/sregion.h>
+
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/service/svcs/svc_action.h>
+#include <api/script/vcpu.h>
+#include <api/wnd/notifmsg.h>
+#include <tataki/canvas/bltcanvas.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define SNAP_X 1
+#define SNAP_Y 1
+#define FX_TIMER 0x0A1C
+
+const wchar_t layerXuiObjectStr[] = L"Layer"; // This is the xml tag
+char layerXuiSvcName[] = "Layer xui object"; // this is the name of the xuiservice
+
+XMLParamPair Layer::params[] =
+ {
+ {LAYER_SETMYCURSOR, L"CURSOR"},
+ {LAYER_SETDBLCLICKACTION, L"DBLCLICKACTION"},
+ {LAYER_DBLCLICKPARAM, L"DBLCLICKPARAM"},
+ {LAYER_SETIMAGE, L"IMAGE"},
+ {LAYER_SETINACTIVEIMAGE, L"INACTIVEIMAGE"},
+ {LAYER_SETQUALITY, L"QUALITY"},
+ {LAYER_SETREGION, L"REGION"},
+ {LAYER_SETRESIZE, L"RESIZE"},
+ {LAYER_SETSCALE, L"SCALE"},
+ {LAYER_SETTILE, L"TILE"},
+
+ };
+
+Layer::Layer()
+ : resizer(0), resizeway(0), scaler(0), scalerway(0), scaling(0),
+ rgn(NULL), secrgn(NULL), rgnclone(NULL), fx_wrap(0), fx_rect(0),
+ fx_dmove(NULL)
+{
+ getScriptObject()->vcpu_setInterface(layerGuid, (void *)static_cast<Layer *>(this));
+ getScriptObject()->vcpu_setClassName(L"Layer");
+ getScriptObject()->vcpu_setController(layerController);
+ resizerect = 1;
+ tiling = 0;
+ l_customcursor = false;
+ hasInactiveImage = 0;
+ fx_on = 0;
+ fx_bgfx = 0;
+ fx_grid_x = 16;
+ fx_grid_y = 16;
+ fx_bilinear = 1;
+ fx_alphamode = 0;
+ fx_delay = 35;
+ fx_timeron = 0;
+ fx_clear = 1;
+ fx_local = 1;
+ fx_realtime = 0;
+ last_w = last_h = -1;
+ getGuiObject()->guiobject_setMover(1);
+ setRectRgn(1);
+ xuihandle = newXuiHandle();
+CreateXMLParameters(xuihandle);
+
+}
+
+void Layer::CreateXMLParameters(int master_handle)
+{
+ //LAYER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Layer::~Layer()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+ delete rgnclone;
+ delete rgn;
+ delete secrgn;
+ delete fx_dmove;
+}
+
+int Layer::onInit()
+{
+ LAYER_PARENT::onInit();
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+ return 1;
+}
+
+
+int Layer::onPaint(Canvas *canvas)
+{
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ LAYER_PARENT::onPaint(canvas);
+
+ if (!getBitmap()) return 0;
+
+ int talpha = getPaintingAlpha();
+
+ RegionI *orig = NULL;
+
+ if (secrgn)
+ {
+ orig = new RegionI(canvas);
+ api_region *clone = orig->clone();
+ api_region *secclone = secrgn->clone();
+ RECT dr;
+ getClientRect(&dr);
+ secclone->offset(dr.left, dr.top);
+ clone->andRegion(secclone);
+ canvas->selectClipRgn(clone);
+ orig->disposeClone(clone);
+ secrgn->disposeClone(secclone);
+ }
+
+ RECT r, srcR, cb, cr;
+ getClientRect(&srcR);
+ r = cr = srcR;
+
+ if (canvas->getClipBox(&cb))
+ {
+ r.left = MAX(r.left, cb.left);
+ r.top = MAX(r.top, cb.top);
+ r.right = MIN(r.right, cb.right);
+ r.bottom = MIN(r.bottom, cb.bottom);
+ srcR = r;
+ }
+
+ layer_adjustDest(&cr);
+ layer_adjustDest(&r);
+
+
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ int bmw = getBitmap()->getWidth();
+ int bmh = getBitmap()->getHeight();
+ int bmpitch = getBitmap()->getFullWidth();
+ int *bmbits = (int*)getBitmap()->getBits();
+
+ if (bmbits) bmbits += getBitmap()->getX() + getBitmap()->getY() * bmpitch;
+#endif
+
+ if (getWidth() == (cr.right - cr.left) && getHeight() == (cr.bottom - cr.top))
+ {
+ int w = r.right - r.left, h = r.bottom - r.top;
+ srcR.top = r.top - cr.top;
+ srcR.left = r.left - cr.left;
+ srcR.top += getSourceOffsetY();
+ srcR.left += getSourceOffsetX();
+ srcR.bottom = srcR.top + h;
+ srcR.right = srcR.left + w;
+ // FG> NOT READY FOR OPTIMIZATION YET
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ if (fx_on && fx_dmove && bmbits)
+ {
+
+ if (fx_bgfx)
+ {
+ if (!fx_dmove->getBltCanvas() || !fx_dmove->getBltCanvas()->getBits())
+ fx_dmove->render(this, getWidth(), getHeight(), bmbits, bmw, bmh, bmpitch);
+
+ int w, h, p, *bits = (int*)canvas->getBits();
+ if (bits && !canvas->getDim(&w, &h, &p) &&
+ cr.left + getWidth() < w && cr.top + getHeight() < h && cr.left >= 0 && cr.top >= 0)
+ {
+ fx_dmove->render(this, getWidth(), getHeight(), bits + cr.left + cr.top*w, getWidth(), getHeight(), w);
+ }
+ else
+ {
+ BltCanvas c(getWidth(), getHeight());
+ canvas->blit(cr.left, cr.top, &c, 0, 0, getWidth(), getHeight());
+ fx_dmove->render(this, getWidth(), getHeight(), (int *)c.getBits(),
+ getWidth(), getHeight(), getWidth());
+ }
+ if (fx_dmove->getBltCanvas())
+ fx_dmove->getBltCanvas()->blit(0, 0, canvas, cr.left, cr.top, getWidth(), getHeight());
+
+ }
+ else
+ { // no bgfx
+ if (fx_getClear() && fx_dmove->getBltCanvas() && fx_dmove->getBltCanvas()->getBits())
+ fx_dmove->getBltCanvas()->fillBits(0);
+ fx_dmove->render(this, getWidth(), getHeight(), bmbits, bmw, bmh, bmpitch);
+ //SkinBitmap *b = NULL;
+ if (fx_dmove->getBltCanvas())
+ {
+ fx_dmove->getBltCanvas()->stretchToRectAlpha(canvas, &srcR, &r, talpha);
+// b = fx_dmove->getBltCanvas()->getSkinBitmap();
+// if (b)
+// b->stretchToRectAlpha(canvas, &srcR, &r, talpha);
+ }
+ }
+ }
+ else
+#endif
+ getBitmap()->stretchToRectAlpha(canvas, &srcR, &r, talpha);
+ }
+ else
+ {
+ if (r.right == r.left || r.bottom == r.top)
+ {
+ if (orig)
+ {
+ canvas->selectClipRgn(orig);
+ delete orig; orig = 0;
+ }
+ return 0;
+ }
+
+ srcR.top = getSourceOffsetY();
+ srcR.left = getSourceOffsetX();
+ srcR.bottom = srcR.top + getHeight();
+ srcR.right = srcR.left + getWidth();
+
+ if (!tiling)
+ {
+
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ if (fx_on && fx_dmove && bmbits)
+ {
+ if (fx_bgfx)
+ {
+ if (!fx_dmove->getBltCanvas() || !fx_dmove->getBltCanvas()->getBits())
+ fx_dmove->render(this, cr.right - cr.left, cr.bottom - cr.top, bmbits, bmw, bmh, bmpitch);
+
+ int w, h, p;
+ if (canvas->getBits() && !canvas->getDim(&w, &h, &p) &&
+ cr.right < w && cr.bottom < h && cr.left >= 0 && cr.top >= 0)
+ {
+ fx_dmove->render(this, cr.right - cr.left, cr.bottom - cr.top, (int *)canvas->getBits() + cr.left + cr.top*w,
+ cr.right - cr.left, cr.bottom - cr.top, w);
+ }
+ else
+ {
+ BltCanvas c(cr.right - cr.left, cr.bottom - cr.top);
+ canvas->blit(cr.left, cr.top, &c, 0, 0, cr.right - cr.left, cr.bottom - cr.top);
+ fx_dmove->render(this, cr.right - cr.left, cr.bottom - cr.top, (int *)c.getBits(),
+ cr.right - cr.left, cr.bottom - cr.top, cr.right - cr.left);
+
+ }
+
+ if (fx_dmove->getBltCanvas())
+ fx_dmove->getBltCanvas()->blit(0, 0, canvas, cr.left, cr.top, cr.right - cr.left, cr.bottom - cr.top);
+ }
+ else
+ {
+ if (fx_getClear() && fx_dmove->getBltCanvas() && fx_dmove->getBltCanvas()->getBits())
+ fx_dmove->getBltCanvas()->fillBits(0);
+ fx_dmove->render(this, getWidth(), getHeight(), bmbits, bmw, bmh, bmpitch);
+ //SkinBitmap *b = NULL;
+ if (fx_dmove->getBltCanvas())
+ {
+ fx_dmove->getBltCanvas()->stretchToRectAlpha(canvas, &srcR, &cr, talpha);
+// b = fx_dmove->getBltCanvas()->getSkinBitmap();
+// if (b)
+// b->stretchToRectAlpha(canvas, &srcR, &cr, talpha);
+
+ }
+ }
+ }
+ else
+#endif
+ {
+ getBitmap()->stretchToRectAlpha(canvas, &srcR, &cr, talpha);
+ }
+
+ }
+ else
+ {
+ getBitmap()->blitRectToTile(canvas, &cr, &srcR, 0, 0, talpha);
+ }
+ }
+
+ if (orig)
+ {
+ canvas->selectClipRgn(orig);
+ delete orig; orig = 0;
+ }
+ return 1;
+}
+
+int Layer::onResize()
+{
+ LAYER_PARENT::onResize();
+ RECT r;
+ getClientRect(&r);
+ int w = r.right - r.left;
+ int h = r.bottom - r.top;
+ if (w != last_w || h != last_h)
+ invalidateRegionCache();
+ return 1;
+}
+
+#pragma warning (disable : 4065)
+void Layer::timerCallback(int id)
+{
+ switch (id)
+ {
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ case FX_TIMER:
+ fx_onFrame();
+ invalidate();
+ break;
+#endif
+
+ default:
+ LAYER_PARENT::timerCallback(id);
+ break;
+ }
+}
+#pragma warning (default: 4065)
+
+void Layer::invalidateRegionCache()
+{
+ delete rgnclone;
+ rgnclone = NULL;
+ invalidateWindowRegion();
+}
+
+int Layer::setXuiParam(int _xuihandle, int attribid, const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (xuihandle != _xuihandle) return LAYER_PARENT::setXuiParam(_xuihandle, attribid, paramname, strvalue);
+ switch (attribid)
+ {
+ case LAYER_SETIMAGE:
+ setBitmap(strvalue);
+ break;
+ case LAYER_SETRESIZE:
+ setResize(SkinParser::parseResize(strvalue));
+ if (resizer) getGuiObject()->guiobject_setMover(0);
+ break;
+ case LAYER_SETSCALE:
+ setScaler(SkinParser::parseResize(strvalue));
+ if (scaler) getGuiObject()->guiobject_setMover(0);
+ break;
+ case LAYER_SETREGION:
+ setRegionFromBitmap(strvalue);
+ break;
+ case LAYER_SETTILE:
+ setTiling(WTOI(strvalue));
+ break;
+ case LAYER_SETDBLCLICKACTION:
+ dblClickAction = strvalue;
+ break;
+ case LAYER_DBLCLICKPARAM:
+ setDblClickParam(strvalue);
+ break;
+ case LAYER_SETINACTIVEIMAGE:
+ setInactiveBitmap(strvalue);
+ break;
+ case LAYER_SETMYCURSOR:
+ l_customcursor = true;
+ getGuiObject()->guiobject_setCursor(strvalue);
+ break;
+ case LAYER_SETQUALITY:
+ bitmap.setResamplingMode(WTOI(strvalue));
+ break;
+ default:
+ return 0;
+
+ }
+ return 1;
+}
+
+int Layer::getPreferences(int what)
+{
+ if (what == SUGGESTED_W)
+ return getWidth();
+ if (what == SUGGESTED_H)
+ return getHeight();
+ return LAYER_PARENT::getPreferences(what);
+}
+
+int Layer::getSourceOffsetX()
+{
+ return 0;
+}
+
+int Layer::getSourceOffsetY()
+{
+ return 0;
+}
+
+void Layer::setBitmap(const wchar_t *name)
+{
+ bitmapname = name;
+ bitmap = name;
+ deleteRegion();
+ makeRegion();
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ if (isInited()) invalidate();
+}
+
+void Layer::setInactiveBitmap(const wchar_t *name)
+{
+ inactiveImageName = name;
+ inactiveBitmap = name;
+ hasInactiveImage = 1;
+}
+
+void Layer::setDblClickParam(const wchar_t *p)
+{
+ dblclickparam=p;
+}
+
+const wchar_t *Layer::getDblClickParam()
+{
+ return dblclickparam;
+}
+
+int Layer::getWidth()
+{
+ if (getBitmap()) return getBitmap()->getWidth();
+ return 0;
+}
+
+int Layer::getHeight()
+{
+ if (getBitmap()) return getBitmap()->getHeight();
+ return 0;
+}
+
+int Layer::onLeftButtonDown(int x, int y)
+{
+ LAYER_PARENT::onLeftButtonDown(x, y);
+ ifc_window *d = getDesktopParent();
+
+#ifdef WASABI_COMPILE_WNDMGR
+ Layout *_l = NULL;
+ if (d != NULL)
+ {
+ _l = static_cast<Layout *>(d->getInterface(layoutGuid));
+ if (_l && _l->isLocked()) return 1;
+ }
+
+ int need_resize = 0, need_scale = 0, need_move = 0;
+
+ int dock = APPBAR_NOTDOCKED;
+ int rw = applyResizeRestrictions(resizeway, &dock);
+ int sw = (dock == APPBAR_NOTDOCKED) ? scalerway : RESIZE_NONE;
+
+ if (resizer && rw != RESIZE_NONE && (!_l || _l->getResizable()))
+ {
+ if (scaler && sw != RESIZE_NONE && Std::keyModifier(STDKEY_ALT) && (!_l || _l->getScalable()))
+ need_scale = 1;
+ else
+ need_resize = 1;
+ }
+ else if (scaler && sw != RESIZE_NONE && (!_l || _l->getScalable()))
+ {
+ need_scale = 1;
+ }
+ else if (getGuiObject()->guiobject_getMover())
+ {
+ need_move = 1;
+ }
+
+ Group *l = static_cast<Group *>(_l);
+
+ if (need_move)
+ {
+ // do nothin'
+ }
+ else if (need_scale)
+ {
+ if (l)
+ {
+ l->beginScale();
+ scaling = 1;
+ }
+ return 1;
+ }
+ else if (need_resize)
+ {
+ resizerect = 1;
+ if (l)
+ {
+ clientToScreen(&x, &y);
+ l->mouseResize(x, y, resizeway);
+ }
+ }
+#endif
+ return 1;
+}
+
+int Layer::onLeftButtonUp(int x, int y)
+{
+ LAYER_PARENT::onLeftButtonUp(x, y);
+#ifdef WASABI_COMPILE_WNDMGR
+ if (scaling)
+ {
+ getGuiObject()->guiobject_getParentGroup()->endScale();
+ scaling = 0;
+ }
+#endif
+ return 1;
+}
+
+void Layer::onCancelCapture()
+{
+ LAYER_PARENT::onCancelCapture();
+ scaling = 0;
+}
+
+int Layer::onMouseMove(int x, int y)
+{
+ LAYER_PARENT::onMouseMove(x, y);
+ POINT pos = {x, y};
+ clientToScreen(&pos);
+
+#ifdef WASABI_COMPILE_WNDMGR
+ if (scaling && getCapture())
+ { // todo: resizing w/no rect
+ if (!Std::keyDown(MK_LBUTTON))
+ scaling = 0;
+ else
+ {
+ RECT oldRect;
+ RECT newRect;
+ ifc_window *b = getRootParent();
+ b->getWindowRect(&oldRect);
+ newRect = oldRect;
+ clientToScreen(&x, &y);
+ int mask = 0;
+ if (scalerway & RESIZE_BOTTOM)
+ {
+ newRect.bottom = y - y % SNAP_Y;
+ mask |= BOTTOM;
+ }
+ if (scalerway & RESIZE_RIGHT)
+ {
+ newRect.right = x - x % SNAP_X;
+ mask |= RIGHT;
+ }
+ if (scalerway & RESIZE_TOP)
+ {
+ newRect.top = y - y % SNAP_Y;
+ mask |= TOP;
+ }
+ if (scalerway & RESIZE_LEFT)
+ {
+ newRect.left = x - x % SNAP_X;
+ mask |= LEFT;
+ }
+
+ RECT dr = newRect;
+ WASABI_API_WNDMGR->wndTrackDock(b, &dr, &newRect, mask | NOINTERSECT);
+ if (dr.right - dr.left < 32) dr.right = dr.left + 32;
+ if (dr.bottom - dr.top < 32) dr.bottom = dr.top + 32;
+ if (MEMCMP(&dr, &oldRect, sizeof(RECT)))
+ {
+ RECT origRect;
+ b->getClientRect(&origRect);
+ double rx = (double)(dr.right - dr.left) / (double)(origRect.right - origRect.left);
+ double ry = (double)(dr.bottom - dr.top) / (double)(origRect.bottom - origRect.top);
+ double r = MAX(rx, ry);
+ if (r != 0) b->setRenderRatio(r);
+ }
+ }
+ }
+#endif
+
+ return 1;
+}
+
+SkinBitmap *Layer::getBitmap()
+{
+ return layer_getBitmap();
+}
+
+SkinBitmap *Layer::layer_getBitmap()
+{
+ if (hasInactiveImage)
+ if (!isActive())
+ return inactiveBitmap.getBitmap();
+ return bitmap.getBitmap();
+}
+
+const wchar_t *Layer::layer_getBitmapName()
+{
+ return bitmapname;
+}
+
+int Layer::applyResizeRestrictions(int way, int *side)
+{
+ ifc_window *rw = getDesktopParent();
+ int dock = APPBAR_NOTDOCKED;
+ if (side) *side = dock;
+ if (rw)
+ {
+ Layout *l = (Layout *)rw->getInterface(layoutGuid);
+ if (l) dock = l->appbar_getSide();
+ }
+ if (dock == APPBAR_NOTDOCKED) return way;
+ /*
+ switch (way) {
+ case RESIZE_TOPLEFT:
+ if (dock == APPBAR_TOP || dock == APPBAR_LEFT) return RESIZE_NONE;
+ break;
+ case RESIZE_BOTTOMRIGHT:
+ if (dock == APPBAR_RIGHT || dock == APPBAR_BOTTOM) return RESIZE_NONE;
+ break;
+ case RESIZE_TOPRIGHT:
+ if (dock == APPBAR_TOP || dock == APPBAR_RIGHT) return RESIZE_NONE;
+ break;
+ case RESIZE_BOTTOMLEFT:
+ if (dock == APPBAR_BOTTOM || dock == APPBAR_LEFT) return RESIZE_NONE;
+ break;
+ case RESIZE_TOP:
+ if (dock == APPBAR_TOP) return RESIZE_NONE;
+ break;
+ case RESIZE_BOTTOM:
+ if (dock == APPBAR_BOTTOM) return RESIZE_NONE;
+ break;
+ case RESIZE_LEFT:
+ if (dock == APPBAR_LEFT) return RESIZE_NONE;
+ break;
+ case RESIZE_RIGHT:
+ if (dock == APPBAR_RIGHT) return RESIZE_NONE;
+ break;
+ }
+ return way;*/
+ if (dock != APPBAR_NOTDOCKED) return RESIZE_NONE;
+ return way;
+}
+
+int Layer::getCursorType(int x, int y)
+{
+ // Return our user cursor if we have one (even when we are resizable!)
+ if (l_customcursor)
+ {
+ return BASEWND_CURSOR_USERSET;
+ }
+ // Then check if our layer is used to resize or scale the wnd
+ ifc_window *d = getDesktopParent();
+ int scalable = 1;
+ int resizable = 1;
+ Layout *_l = NULL;
+ if (d != NULL)
+ {
+ _l = static_cast<Layout *>(d->getInterface(layoutGuid));
+ if (_l)
+ {
+ scalable = _l->getScalable();
+ resizable = _l->getResizable();
+ }
+ }
+
+ if (!_l || (!_l->isLocked() && (resizer || scaler)))
+ {
+ int dock = APPBAR_NOTDOCKED;
+
+ int r = 0;
+ if (resizer && resizable)
+ {
+ if (scaler && scalable)
+ {
+ if (Std::keyModifier(STDKEY_ALT))
+ {
+ r = applyResizeRestrictions(scalerway, &dock);
+ if (dock != APPBAR_NOTDOCKED) r = RESIZE_NONE;
+ }
+ else
+ {
+ r = applyResizeRestrictions(resizeway);
+ }
+ }
+ else
+ {
+ r = applyResizeRestrictions(resizeway);
+ }
+ }
+ if (scaler && scalable)
+ {
+ r = applyResizeRestrictions(scalerway, &dock);
+ if (dock != APPBAR_NOTDOCKED) r = RESIZE_NONE;
+ }
+
+ switch (r)
+ {
+ case RESIZE_TOPLEFT:
+ case RESIZE_BOTTOMRIGHT:
+ return BASEWND_CURSOR_NORTHWEST_SOUTHEAST;
+ case RESIZE_TOPRIGHT:
+ case RESIZE_BOTTOMLEFT:
+ return BASEWND_CURSOR_NORTHEAST_SOUTHWEST;
+ break;
+ case RESIZE_TOP:
+ case RESIZE_BOTTOM:
+ return BASEWND_CURSOR_NORTHSOUTH;
+ break;
+ case RESIZE_LEFT:
+ case RESIZE_RIGHT:
+ return BASEWND_CURSOR_EASTWEST;
+ break;
+ }
+ }
+ // At leat we want to have a cursor so spit our the normal pointer
+ return BASEWND_CURSOR_POINTER;
+}
+
+void Layer::setScaler(int r)
+{
+ if (r != 0)
+ {
+ scaler = 1;
+ scalerway = r;
+ }
+ else
+ {
+ resizer = 0;
+ scalerway = 0;
+ }
+}
+
+void Layer::setResize(int r)
+{
+ if (r != 0)
+ {
+ resizer = 1;
+ resizeway = r;
+ }
+ else
+ {
+ resizer = 0;
+ resizeway = 0;
+ }
+}
+
+api_region *Layer::getBitmapRegion()
+{
+ return rgn;
+}
+
+api_region *Layer::getRegion()
+{
+ api_region *_rgn = getBitmapRegion();
+ if (!_rgn) return NULL;
+ if (!rgnclone)
+ {
+ rgnclone = new RegionI();
+ rgnclone->addRegion(_rgn);
+ }
+ else
+ return rgnclone;
+ float w, h;
+ RECT r;
+ getClientRect(&r);
+ if (r.right - r.left == 0 || r.bottom - r.top == 0) return NULL;
+ last_w = r.right - r.left;
+ last_h = r.bottom - r.top;
+ if (getWidth() == 0 || getHeight() == 0) return NULL;
+ w = (float)(last_w) / (float)getWidth();
+ h = (float)(last_h) / (float)getHeight();
+ if (!w || !h) return NULL;
+ if (!tiling)
+ {
+ if (w != 1.0 || h != 1.0)
+ {
+ rgnclone->scale(w, h, TRUE);
+ }
+ }
+ else
+ {
+ for (int j = 0;j < h;j++)
+ {
+ for (int i = 0;i < w;i++)
+ {
+ api_region *t = _rgn->clone();
+ t->offset(i*getWidth(), j*getHeight());
+ rgnclone->addRegion(t);
+ _rgn->disposeClone(t);
+ }
+ }
+ }
+ RegionI _r(&r);
+ _r.offset(-r.left, -r.top);
+ rgnclone->andRegion(&_r);
+
+ return rgnclone;
+}
+
+void Layer::setRegionOp(int i)
+{
+ int old = getRegionOp();
+ LAYER_PARENT::setRegionOp(i);
+ if (!old && i) setRectRgn(0);
+}
+
+void Layer::makeRegion()
+{
+ if (!bitmap.getBitmap())
+ return;
+ delete rgn;
+ rgn = new RegionI(bitmap);
+ invalidateRegionCache();
+}
+
+void Layer::deleteRegion()
+{
+ if (!rgn) return;
+ invalidateRegionCache();
+ delete rgn;
+ rgn = NULL;
+}
+
+int Layer::onLeftButtonDblClk(int x, int y)
+{
+ // Martin> copied and adopted from textbase.cpp
+ //if (!dblClickAction.isempty() && !VCPU::getComplete())
+ if (dblClickAction)
+ {
+#ifdef WASABI_COMPILE_WNDMGR
+ const wchar_t *toCheck = L"SWITCH;";
+ if (!_wcsnicmp(dblClickAction, toCheck, 7))
+ {
+ onLeftButtonUp(x, y);
+ getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue() + 7);
+ return 0;
+ }
+ else
+ {
+#endif
+ svc_action *act = ActionEnum(dblClickAction).getNext();
+ if (act)
+ {
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ act->onAction(dblClickAction, getDblClickParam(), _x, _y, NULL, 0, this);
+ //WASABI_API_WNDMGR->messageBox(L"on action; passed", L"debug", 0, NULL, NULL);
+ SvcEnum::release(act);
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+
+ }
+#endif
+
+ }
+ int r = LAYER_PARENT::onLeftButtonDblClk(x, y);
+ return r;
+}
+
+
+void Layer::setRegionFromMap(SMap *map, int byte, int inversed)
+{
+ if (secrgn)
+ {
+ invalidate();
+ delete secrgn;
+ secrgn = NULL;
+ }
+ //RECT r = {map->getBitmap()->getX(), map->getBitmap()->getY(), map->getBitmap()->getWidth(), map->getBitmap()->getHeight()};
+ secrgn = new RegionI(map->getBitmap(), NULL, 0, 0, FALSE, 1, (unsigned char)byte, inversed);
+ if (secrgn)
+ invalidate();
+}
+
+void Layer::setRegion(SRegion *reg)
+{
+ invalidate();
+ delete secrgn;
+ if (!reg)
+ {
+ secrgn = NULL; invalidate(); return;
+ }
+ secrgn = new RegionI();
+ secrgn->addRegion(reg->getRegion());
+ invalidate();
+}
+
+int Layer::wantSiblingInvalidations()
+{
+ return fx_on;
+}
+
+int Layer::onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx)
+{
+ if (!fx_on || !fx_bgfx || who_idx >= my_idx) return 0;
+ RECT rr;
+ getClientRect(&rr);
+ if (rgn)
+ {
+ api_region *_r = rgn->clone();
+ _r->offset(rr.left, rr.top);
+ if (fx_local && !_r->doesIntersectRgn(r))
+ {
+ rgn->disposeClone(_r);
+ return 0;
+ }
+ if (secrgn)
+ {
+ api_region *_rs = secrgn->clone();
+ _rs->offset(rr.left, rr.top);
+ _r->andRegion(_rs);
+ secrgn->disposeClone(_rs);
+ }
+ r->addRegion(_r);
+ rgn->disposeClone(_r);
+ }
+ else
+ {
+ RegionI _r(&rr);
+ if (secrgn)
+ {
+ api_region *_rs = secrgn->clone();
+ _rs->offset(rr.left, rr.top);
+ _r.andRegion(_rs);
+ secrgn->disposeClone(_rs);
+ }
+ if (fx_local && !_r.doesIntersectRgn(r))
+ {
+ return 0;
+ }
+ r->addRegion(&_r);
+ }
+ return 1;
+}
+
+void Layer::onSetVisible(int show)
+{
+ LAYER_PARENT::onSetVisible(show);
+ getGuiObject()->guiobject_onSetVisible(show);
+}
+
+int Layer::onActivate()
+{
+ invalidate();
+ return 0;
+}
+
+int Layer::onDeactivate()
+{
+ invalidate();
+ return 0;
+}
+
+void Layer::setTiling(int t)
+{
+ if (tiling == t) return;
+ tiling = t;
+ invalidate();
+}
+
+int Layer::getTiling()
+{
+ return tiling;
+}
+
+
+void Layer::onBeginResize(RECT r)
+{
+ scriptVar l = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&l, r.left);
+ scriptVar t = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&t, r.top);
+ scriptVar w = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&w, r.right - r.left);
+ scriptVar h = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&h, r.bottom - r.top);
+ script_vcpu_onBeginResize(SCRIPT_CALL, getScriptObject(), l, t, w, h);
+}
+
+void Layer::onEndResize(RECT r)
+{
+ scriptVar l = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&l, r.left);
+ scriptVar t = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&t, r.top);
+ scriptVar w = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&w, r.right - r.left);
+ scriptVar h = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&h, r.bottom - r.top);
+ script_vcpu_onEndResize(SCRIPT_CALL, getScriptObject(), l, t, w, h);
+}
+
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+void Layer::fx_setEnabled(int i)
+{
+ static int inited = 0;
+ if (fx_getEnabled() == !!i) return;
+ fx_on = !!i;
+ if (fx_on)
+ {
+ if (!inited)
+ fx_onInit();
+ fx_dmove = new FxDynamicMove;
+ fx_dmove->setBilinear(fx_getBilinear());
+ if (fx_getAlphaMode())
+ fx_dmove->setAlphaMode(1 | (fx_getBgFx() ? 2 : 0));
+ else fx_setAlphaMode(0);
+ fx_dmove->setAlphaOnce(fx_alphaonce);
+ fx_dmove->setRect(fx_getRect());
+ fx_dmove->setWrap(fx_getWrap());
+ fx_dmove->setGridSize(fx_grid_x, fx_grid_y);
+ if (fx_realtime)
+ {
+ setTimer(FX_TIMER, fx_delay);
+ fx_timeron = 1;
+ }
+ }
+ else
+ {
+ if (fx_timeron)
+ {
+ killTimer(FX_TIMER);
+ fx_timeron = 0;
+ }
+ delete fx_dmove;
+ fx_dmove = NULL;
+ }
+ invalidate();
+}
+
+int Layer::fx_getEnabled(void)
+{
+ return fx_on;
+}
+
+void Layer::fx_setWrap(int i)
+{
+ if (fx_getWrap() == !!i) return;
+ fx_wrap = !!i;
+ if (fx_dmove) fx_dmove->setWrap(fx_wrap);
+ invalidate();
+}
+
+int Layer::fx_getWrap(void)
+{
+ return fx_wrap;
+}
+
+void Layer::fx_setRect(int i)
+{
+ if (fx_getRect() == !!i) return;
+ fx_rect = !!i;
+ if (fx_dmove) fx_dmove->setRect(fx_rect);
+ invalidate();
+}
+
+int Layer::fx_getRect(void)
+{
+ return fx_rect;
+}
+
+int Layer::fx_getAlphaMode()
+{
+ if (!fx_alphamode) return 0;
+ if (fx_alphaonce) return 2;
+ return 1;
+}
+
+void Layer::fx_setAlphaMode(int i)
+{
+
+ if (i == 2)
+ {
+ i = 1;
+ fx_alphaonce = 1;
+ if (fx_dmove) fx_dmove->setAlphaOnce(1);
+ }
+ else
+ {
+ fx_alphaonce = 0;
+ if (fx_dmove) fx_dmove->setAlphaOnce(0);
+ }
+
+ if (fx_getAlphaMode() == !!i) return;
+ fx_alphamode = !!i;
+ if (fx_dmove)
+ {
+ if (fx_getAlphaMode())
+ fx_dmove->setAlphaMode(1 | (fx_getBgFx() ? 2 : 0));
+ else
+ fx_dmove->setAlphaMode(0);
+ }
+ invalidate();
+}
+
+
+int Layer::fx_getBilinear()
+{
+ return fx_bilinear;
+}
+
+void Layer::fx_setBilinear(int i)
+{
+ if (fx_getBilinear() == !!i) return;
+ fx_bilinear = !!i;
+ if (fx_dmove) fx_dmove->setBilinear(fx_bilinear);
+ invalidate();
+}
+
+int Layer::fx_getBgFx()
+{
+ return fx_bgfx;
+}
+
+void Layer::fx_setBgFx(int i)
+{
+ if (fx_getBgFx() == !!i) return;
+ fx_bgfx = !!i;
+ if (fx_dmove) fx_dmove->setCanCache(!i);
+ if (fx_dmove && fx_getAlphaMode())
+ {
+ fx_dmove->setAlphaMode(1 | (fx_getBgFx() ? 2 : 0));
+ }
+ invalidate();
+}
+
+int Layer::fx_getSpeed()
+{
+ return fx_delay;
+}
+
+void Layer::fx_setSpeed(int s)
+{
+ if (fx_getSpeed() == s) return;
+ fx_delay = s;
+ if (fx_timeron)
+ {
+ killTimer(FX_TIMER);
+ fx_timeron = 0;
+ }
+ if (fx_on && fx_realtime)
+ {
+ setTimer(FX_TIMER, fx_delay);
+ fx_timeron = 1;
+ }
+}
+
+int Layer::fx_getClear()
+{
+ return fx_clear;
+}
+
+void Layer::fx_setClear(int i)
+{
+ if (fx_getClear() == !!i) return;
+ fx_clear = !!i;
+}
+
+int Layer::fx_getRealtime()
+{
+ return fx_realtime;
+}
+
+void Layer::fx_setRealtime(int i)
+{
+ if (fx_getRealtime() == !!i) return;
+ fx_realtime = !!i;
+}
+
+int Layer::fx_getLocalized()
+{
+ return fx_local;
+}
+
+void Layer::fx_setLocalized(int i)
+{
+ if (fx_getLocalized() == !!i) return;
+ fx_local = !!i;
+}
+
+void Layer::fx_setGridSize(int x, int y)
+{
+ fx_grid_x = x;
+ fx_grid_y = y;
+ if (!fx_dmove) return;
+ fx_dmove->setGridSize(x, y);
+}
+
+void Layer::fx_update(void)
+{
+ RECT r;
+ getClientRect(&r);
+ if (fx_realtime && !isMinimized())
+ cascadeRepaintRect(&r);
+ else
+ invalidateRect(&r);
+}
+
+void Layer::fx_restart(void)
+{
+ fx_onInit();
+ if (fx_dmove && fx_dmove->getBltCanvas() && fx_dmove->getBltCanvas()->getBits())
+ fx_dmove->getBltCanvas()->fillBits(0);
+ // todo: reset need_alpha in fx_dmove
+}
+
+void Layer::fx_onInit(void)
+{
+ script_vcpu_fx_onInit(SCRIPT_CALL, getScriptObject());
+}
+
+void Layer::fx_onFrame(void)
+{
+ script_vcpu_fx_onFrame(SCRIPT_CALL, getScriptObject());
+}
+
+double Layer::fx_onGetPixelA(double r, double d, double x, double y)
+{
+ scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&_x, x);
+ SOM::assign(&_y, y);
+ SOM::assign(&_r, r);
+ SOM::assign(&_d, d);
+ scriptVar v = script_vcpu_fx_onGetPixelA(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y);
+ return (v.type == 0) ? 0.5 : v.data.ddata;
+}
+
+
+double Layer::fx_onGetPixelX(double r, double d, double x, double y)
+{
+ scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&_x, x);
+ SOM::assign(&_y, y);
+ SOM::assign(&_r, r);
+ SOM::assign(&_d, d);
+ scriptVar v = script_vcpu_fx_onGetPixelX(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y);
+ return (v.type == 0) ? x : v.data.ddata;
+}
+
+double Layer::fx_onGetPixelY(double r, double d, double x, double y)
+{
+ scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&_x, x);
+ SOM::assign(&_y, y);
+ SOM::assign(&_r, r);
+ SOM::assign(&_d, d);
+ scriptVar v = script_vcpu_fx_onGetPixelY(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y);
+ return (v.type == 0) ? y : v.data.ddata;
+}
+
+double Layer::fx_onGetPixelR(double r, double d, double x, double y)
+{
+ scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&_x, x);
+ SOM::assign(&_y, y);
+ SOM::assign(&_r, r);
+ SOM::assign(&_d, d);
+ scriptVar v = script_vcpu_fx_onGetPixelR(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y);
+ return (v.type == 0) ? r : v.data.ddata;
+}
+
+double Layer::fx_onGetPixelD(double r, double d, double x, double y)
+{
+ scriptVar _x = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _y = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _r = SOM::makeVar(SCRIPT_DOUBLE);
+ scriptVar _d = SOM::makeVar(SCRIPT_DOUBLE);
+ SOM::assign(&_x, x);
+ SOM::assign(&_y, y);
+ SOM::assign(&_r, r);
+ SOM::assign(&_d, d);
+ scriptVar v = script_vcpu_fx_onGetPixelD(SCRIPT_CALL, getScriptObject(), _r, _d, _x, _y);
+ return (v.type == 0) ? d : v.data.ddata;
+}
+#endif
+
+int Layer::skincb_onColorThemeChanged(const wchar_t *newcolortheme)
+{
+ #if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ if (fx_getEnabled())
+ {
+ fx_dmove->flushCache();
+ fx_update();
+ }
+#endif
+ return 0;
+}
+
+void Layer::setRegionFromBitmap(const wchar_t *bmpid)
+{
+ delete secrgn;
+ secrgn = NULL;
+ if (bmpid == NULL || *bmpid == '\0')
+ return;
+ bool invert = (*bmpid == '!');
+ if (invert) bmpid++;
+ SkinBitmap b(bmpid);
+ secrgn = new RegionI(&b, NULL, 0, 0, invert);
+}
+
+LayerScriptController _layerController;
+LayerScriptController *layerController = &_layerController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct LayerScriptController::exportedFunction[] = {
+ {L"setRegionFromMap", 3, (void*)Layer::script_vcpu_setRegionFromMap },
+ {L"setRegion", 1, (void*)Layer::script_vcpu_setRegion },
+ {L"isInvalid", 0, (void*)Layer::script_vcpu_isInvalid },
+#ifdef WASABI_COMPILE_WNDMGR
+ {L"onBeginResize", 4, (void*)Layer::script_vcpu_onBeginResize },
+ {L"onEndResize", 4, (void*)Layer::script_vcpu_onEndResize },
+#endif
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ {
+ L"fx_setEnabled", 1, (void*)Layer::script_vcpu_fx_setEnabled
+ },
+ {L"fx_getEnabled", 0, (void*)Layer::script_vcpu_fx_getEnabled },
+ {L"fx_onInit", 0, (void*)Layer::script_vcpu_fx_onInit },
+ {L"fx_onFrame", 0, (void*)Layer::script_vcpu_fx_onFrame },
+ {L"fx_onGetPixelR", 4, (void*)Layer::script_vcpu_fx_onGetPixelR },
+ {L"fx_onGetPixelD", 4, (void*)Layer::script_vcpu_fx_onGetPixelD },
+ {L"fx_onGetPixelX", 4, (void*)Layer::script_vcpu_fx_onGetPixelX },
+ {L"fx_onGetPixelY", 4, (void*)Layer::script_vcpu_fx_onGetPixelY },
+ {L"fx_onGetPixelA", 4, (void*)Layer::script_vcpu_fx_onGetPixelA },
+ {L"fx_setWrap", 1, (void*)Layer::script_vcpu_fx_setWrap },
+ {L"fx_getWrap", 0, (void*)Layer::script_vcpu_fx_getWrap },
+ {L"fx_setRect", 1, (void*)Layer::script_vcpu_fx_setRect },
+ {L"fx_getRect", 0, (void*)Layer::script_vcpu_fx_getRect },
+ {L"fx_setBgFx", 1, (void*)Layer::script_vcpu_fx_setBgFx },
+ {L"fx_getBgFx", 0, (void*)Layer::script_vcpu_fx_getBgFx },
+ {L"fx_setClear", 1, (void*)Layer::script_vcpu_fx_setClear },
+ {L"fx_getClear", 0, (void*)Layer::script_vcpu_fx_getClear },
+ {L"fx_setSpeed", 1, (void*)Layer::script_vcpu_fx_setSpeed },
+ {L"fx_getSpeed", 0, (void*)Layer::script_vcpu_fx_getSpeed },
+ {L"fx_setRealtime", 1, (void*)Layer::script_vcpu_fx_setRealtime },
+ {L"fx_getRealtime", 0, (void*)Layer::script_vcpu_fx_getRealtime },
+ {L"fx_setLocalized", 1, (void*)Layer::script_vcpu_fx_setLocalized },
+ {L"fx_getLocalized", 0, (void*)Layer::script_vcpu_fx_getLocalized },
+ {L"fx_setBilinear", 1, (void*)Layer::script_vcpu_fx_setBilinear },
+ {L"fx_getBilinear", 0, (void*)Layer::script_vcpu_fx_getBilinear },
+ {L"fx_setAlphaMode", 1, (void*)Layer::script_vcpu_fx_setAlphaMode },
+ {L"fx_getAlphaMode", 0, (void*)Layer::script_vcpu_fx_getAlphaMode },
+ {L"fx_setGridSize", 2, (void*)Layer::script_vcpu_fx_setGridSize },
+ {L"fx_update", 0, (void*)Layer::script_vcpu_fx_update },
+ {L"fx_restart", 0, (void*)Layer::script_vcpu_fx_restart },
+#endif
+ };
+// --------------------------------------------------------
+
+const wchar_t *LayerScriptController::getClassName()
+{
+ return L"Layer";
+}
+
+const wchar_t *LayerScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *LayerScriptController::instantiate()
+{
+ Layer *l = new Layer;
+ ASSERT(l != NULL);
+ return l->getScriptObject();
+}
+
+void LayerScriptController::destroy(ScriptObject *o)
+{
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ ASSERT(l != NULL);
+ delete l;
+}
+
+void *LayerScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for layer yet
+}
+
+void LayerScriptController::deencapsulate(void *o)
+{}
+
+int LayerScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *LayerScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID LayerScriptController::getClassGuid()
+{
+ return layerGuid;
+}
+
+
+//------------------------------------------------------------------------
+
+scriptVar Layer::script_vcpu_onBeginResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar width, scriptVar height)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, left, top, width, height);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, left, top, width, height);
+}
+
+scriptVar Layer::script_vcpu_onEndResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar width, scriptVar height)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, left, top, width, height);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, left, top, width, height);
+}
+
+scriptVar Layer::script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&byte));
+ ASSERT(SOM::isNumeric(&inv));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ SMap *m = static_cast<SMap *>(GET_SCRIPT_OBJECT_AS(map, mapGuid));
+ if (l) l->setRegionFromMap(m, GET_SCRIPT_INT(byte), GET_SCRIPT_INT(inv));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ SRegion *r = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(reg, regionGuid));
+ if (l) l->setRegion(r);
+ RETURN_SCRIPT_VOID;
+}
+
+bool Layer::layer_isInvalid()
+{
+ SkinBitmap *b = layer_getBitmap();
+ if (b)
+ return !!b->isInvalid();
+ else
+ return true;
+}
+
+scriptVar Layer::script_vcpu_isInvalid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l)
+ {
+ return MAKE_SCRIPT_INT(l->layer_isInvalid()?1:0);
+ }
+ return MAKE_SCRIPT_INT(1);
+}
+
+
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+scriptVar Layer::script_vcpu_fx_setEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setEnabled(GET_SCRIPT_INT(a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getEnabled());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setWrap(SOM::makeInt(&a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getWrap());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setRect(SOM::makeInt(&a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getRect());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setAlphaMode(SOM::makeInt(&a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getAlphaMode());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setBilinear(SOM::makeInt(&a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getBilinear());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setBgFx(SOM::makeInt(&a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(((Layer *)o)->fx_getBgFx());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&s));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setSpeed(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(((Layer *)o)->fx_getSpeed());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&s));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setRealtime(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(((Layer *)o)->fx_getRealtime());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&s));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setClear(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getClear());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&s));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setLocalized(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_getLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) return MAKE_SCRIPT_INT(l->fx_getLocalized());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layer::script_vcpu_fx_setGridSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&x));
+ ASSERT(SOM::isNumeric(&y));
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_setGridSize(SOM::makeInt(&x), SOM::makeInt(&y));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_update(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_update();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_restart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layer *l = static_cast<Layer *>(o->vcpu_getInterface(layerGuid));
+ if (l) l->fx_restart();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layer::script_vcpu_fx_onInit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layer::script_vcpu_fx_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layerController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layer::script_vcpu_fx_onGetPixelA(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, r, d, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, r, d, x, y);
+}
+
+
+scriptVar Layer::script_vcpu_fx_onGetPixelX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, r, d, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, r, d, x, y);
+}
+
+scriptVar Layer::script_vcpu_fx_onGetPixelY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, r, d, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, r, d, x, y);
+}
+
+scriptVar Layer::script_vcpu_fx_onGetPixelR(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, r, d, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, r, d, x, y);
+}
+
+scriptVar Layer::script_vcpu_fx_onGetPixelD(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layerController, r, d, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, r, d, x, y);
+}
+
+#endif //WA3COMPATIBILITY || GEN_FF
+
+
diff --git a/Src/Wasabi/api/skin/widgets/layer.h b/Src/Wasabi/api/skin/widgets/layer.h
new file mode 100644
index 00000000..efc607d2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/layer.h
@@ -0,0 +1,287 @@
+//PORTABLE
+#ifndef _LAYER_H
+#define _LAYER_H
+
+#ifndef _NOSTUDIO
+
+#include <api/script/objects/smap.h>
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+#include <api/wnd/basewnd.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/virtualwnd.h>
+#include <tataki/region/region.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <api/wnd/wndclass/qpaintwnd.h>
+
+#endif
+
+#include <api/script/script.h>
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+
+// {5AB9FA15-9A7D-4557-ABC8-6557A6C67CA9}
+static const GUID layerGuid =
+{ 0x5ab9fa15, 0x9a7d, 0x4557, { 0xab, 0xc8, 0x65, 0x57, 0xa6, 0xc6, 0x7c, 0xa9 } };
+
+#define LAYER_PARENT GuiObjectWnd
+#ifdef WASABI_WIDGETS_GUIOBJECT
+class LayerScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern LayerScriptController *layerController;
+#endif
+#ifndef _NOSTUDIO
+
+#define RESIZE_NONE 0
+#define RESIZE_TOP 1
+#define RESIZE_BOTTOM 2
+#define RESIZE_LEFT 4
+#define RESIZE_RIGHT 8
+#define RESIZE_TOPLEFT RESIZE_TOP | RESIZE_LEFT
+#define RESIZE_TOPRIGHT RESIZE_TOP | RESIZE_RIGHT
+#define RESIZE_BOTTOMLEFT RESIZE_BOTTOM | RESIZE_LEFT
+#define RESIZE_BOTTOMRIGHT RESIZE_BOTTOM | RESIZE_RIGHT
+
+class FxDynamicMove;
+
+class Layer : public LAYER_PARENT, public SkinCallbackI
+{
+public:
+ Layer();
+ virtual ~Layer();
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *canvas);
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onMouseMove(int x, int y);
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int getCursorType(int x, int y);
+ virtual int onResize();
+ virtual int onActivate();
+ virtual int onDeactivate();
+ virtual int getPreferences(int what);
+
+ virtual void setDblClickParam(const wchar_t *p);
+ virtual const wchar_t *getDblClickParam();
+
+ virtual void timerCallback(int id);
+
+ virtual void setRegionFromBitmap(const wchar_t *bmpid);
+
+ virtual void setRegionFromMap(SMap *map, int byte, int inversed);
+ virtual void setRegion(SRegion *reg);
+ virtual int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx);
+
+ virtual int wantSiblingInvalidations();
+
+ virtual int getSourceOffsetX();
+ virtual int getSourceOffsetY();
+
+ virtual void layer_adjustDest(RECT *r) {}
+
+ virtual void onBeginResize(RECT r);
+ virtual void onEndResize(RECT r);
+ virtual SkinBitmap *getBitmap();
+
+ virtual void onSetVisible(int show);
+
+ void setResize(int r);
+ void setScaler(int m);
+ virtual void invalidateRegionCache();
+
+ virtual api_region *getRegion(); // stretched and tiled as needed
+ virtual api_region *getBitmapRegion(); // not stretched or tiled
+ virtual void makeRegion();
+ virtual void deleteRegion();
+
+ virtual void setTiling(int t);
+ virtual int getTiling();
+
+ virtual void setBitmap(const wchar_t *name);
+ virtual int getWidth();
+ virtual int getHeight();
+
+ virtual int setXuiParam(int _xuihandle, int id, const wchar_t *paramname, const wchar_t *strvalue);
+
+ virtual void setRegionOp(int i);
+
+ virtual void setInactiveBitmap(const wchar_t *name);
+ virtual void onCancelCapture();
+
+ virtual int applyResizeRestrictions(int way, int *side=NULL);
+
+ virtual bool layer_isInvalid();
+ //FG> fx
+
+#if defined(WA3COMPATIBILITY) || defined(GEN_FF)
+ virtual void fx_setEnabled(int i);
+ virtual int fx_getEnabled(void);
+ virtual void fx_setWrap(int i);
+ virtual int fx_getWrap(void);
+ virtual void fx_setRect(int i);
+ virtual int fx_getRect(void);
+ virtual void fx_setBilinear(int i);
+ virtual int fx_getBilinear(void);
+ virtual void fx_setAlphaMode(int i);
+ virtual int fx_getAlphaMode(void);
+ virtual void fx_setBgFx(int i);
+ virtual int fx_getBgFx(void);
+ virtual void fx_setClear(int i);
+ virtual int fx_getClear(void);
+ virtual void fx_setLocalized(int i);
+ virtual int fx_getLocalized(void);
+ virtual void fx_setGridSize(int x, int y);
+ virtual void fx_update(void);
+ virtual void fx_restart(void);
+ virtual void fx_onInit(void);
+ virtual void fx_onFrame(void);
+ virtual void fx_setSpeed(int d);
+ virtual int fx_getSpeed(void);
+ virtual void fx_setRealtime(int r);
+ virtual int fx_getRealtime(void);
+ virtual double fx_onGetPixelA(double r, double d, double x, double y);
+ virtual double fx_onGetPixelX(double r, double d, double x, double y);
+ virtual double fx_onGetPixelY(double r, double d, double x, double y);
+ virtual double fx_onGetPixelR(double r, double d, double x, double y);
+ virtual double fx_onGetPixelD(double r, double d, double x, double y);
+#endif
+
+ virtual int skincb_onColorThemeChanged(const wchar_t *newcolortheme);
+
+ enum {
+ LAYER_SETIMAGE=0,
+ LAYER_SETRESIZE,
+ LAYER_SETSCALE,
+ LAYER_SETREGION,
+ LAYER_SETTILE,
+ LAYER_SETDBLCLICKACTION,
+ LAYER_DBLCLICKPARAM,
+ LAYER_SETINACTIVEIMAGE,
+ LAYER_SETMYCURSOR,
+ LAYER_SETQUALITY,
+ // LAYER_NUMPARAMS, // martin> there is no reference for this elsewhere in gen_ff, so CUT
+
+ };
+
+ int l_customcursor;
+
+protected:
+/*static */void CreateXMLParameters(int master_handle);
+ const wchar_t *layer_getBitmapName();
+ SkinBitmap *layer_getBitmap();
+
+private:
+static XMLParamPair params[];
+ AutoSkinBitmap bitmap;
+ int resizer, resizeway, resizing, resizerect;
+ int cap, scaler, scalerway, scaling;
+ POINT anchor;
+ int clickthrough;
+ RegionI *rgn, *secrgn, *rgnclone;
+ int tiling;
+ StringW bitmapname;
+ int hasInactiveImage;
+ StringW inactiveImageName;
+ AutoSkinBitmap inactiveBitmap;
+ int xuihandle;
+ StringW dblclickparam;
+
+ int fx_on;
+ int fx_wrap;
+ int fx_rect;
+ int fx_grid_x;
+ int fx_grid_y;
+ int fx_bilinear;
+ int fx_alphamode;
+ int fx_alphaonce;
+ int fx_bgfx;
+ int fx_clear;
+ int fx_delay;
+ int fx_timeron;
+ int fx_local;
+ int fx_realtime;
+ int last_w, last_h;
+ FxDynamicMove *fx_dmove;
+
+ StringW dblClickAction;
+ StringW statustext;
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+
+public:
+ static scriptVar script_vcpu_onBeginResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l, scriptVar t, scriptVar w, scriptVar h);
+ static scriptVar script_vcpu_onEndResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l, scriptVar t, scriptVar w, scriptVar h);
+ static scriptVar script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inversed);
+ static scriptVar script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg);
+
+ static scriptVar script_vcpu_isInvalid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static scriptVar script_vcpu_fx_setEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getEnabled(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getWrap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getRect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getBgFx(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getClear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getLocalized(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getBilinear(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_fx_getAlphaMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setGridSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_fx_update(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_restart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_onInit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_setSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_fx_getSpeed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_fx_onGetPixelA(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_fx_onGetPixelX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_fx_onGetPixelY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_fx_onGetPixelR(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y);
+ static scriptVar script_vcpu_fx_onGetPixelD(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r, scriptVar d, scriptVar x, scriptVar y);
+
+#else
+class Layer : public LAYER_SCRIPTPARENT {
+
+#endif
+
+public:
+
+// INSERT_SCRIPT_OBJECT_CONTROL
+
+};
+#ifdef WASABI_WIDGETS_GUIOBJECT
+extern const wchar_t layerXuiObjectStr[];
+extern char layerXuiSvcName[];
+class LayerXuiSvc : public XuiObjectSvc<Layer, layerXuiObjectStr, layerXuiSvcName> {};
+#endif
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp
new file mode 100644
index 00000000..5be43319
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/iebrowser.cpp
@@ -0,0 +1,637 @@
+#include <precomp.h>
+#include "iebrowser.h"
+#include "mbsvc.h"
+#include "main.h"
+#include "../nu/ns_wc.h"
+#include "../Winamp/buildtype.h"
+#include <api/config/items/cfgitem.h>
+#include <wa2frontend.h>
+#include <windows.h>
+#include <Mshtml.h>
+#include "minibrowserCOM.h"
+
+class BrowserMsgProc: public ifc_messageprocessor
+{
+public:
+ BrowserMsgProc(BrowserWnd *pBrowser) : pTarget(pBrowser) {}
+ ~BrowserMsgProc(void) {}
+
+public:
+ bool ProcessMessage(MSG *pMsg)
+ {
+ if (WM_KEYFIRST <= pMsg->message && WM_KEYLAST >= pMsg->message)
+ {
+ HWND hwndHost;
+ hwndHost = pTarget->gethWnd();
+ if ((hwndHost == pMsg->hwnd || IsChild(hwndHost, pMsg->hwnd)) && IsWindowVisible(pMsg->hwnd))
+ {
+ if (!(GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_MENU)&0x8000))
+ {
+ if (pTarget->TranslateKey(pMsg)) return true;
+ }
+ switch(pMsg->message)
+ {
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ switch(pMsg->wParam)
+ {
+ case VK_F1:
+ if (!(GetAsyncKeyState(VK_SHIFT)&0x8000)) pMsg->hwnd = plugin.hwndParent;
+ break;
+
+ case VK_F4:
+ if ((pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) && (GetAsyncKeyState(VK_MENU)&0x8000))
+ SendMessageW(plugin.hwndParent, WM_CLOSE, 0, 0);
+ pMsg->message = WM_NULL;
+ break;
+ case 'P':
+ case 'K':
+ case 'H':
+ case VK_TAB:
+ if ((GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_MENU)&0x8000)) pMsg->hwnd = plugin.hwndParent;
+ break;
+ case '3':
+ case VK_UP:
+ case VK_DOWN:
+ break;
+ default:
+ if ((GetAsyncKeyState(VK_MENU)&0x8000) && !(GetAsyncKeyState(VK_CONTROL)&0x8000)) pMsg->hwnd = plugin.hwndParent;
+ break;
+ }
+ break;
+ }
+
+ }
+
+ }
+ return /*(IsDialogMessageW(pTarget->gethWnd(), pMsg)) ? true :*/ false;
+ }
+
+protected:
+ BrowserWnd *pTarget;
+ RECVS_DISPATCH;
+
+};
+
+extern HINSTANCE hInstance;
+STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc)
+{
+ *pstrDest = SysAllocString( szSrc );
+ if ( !(*pstrDest) ) return E_OUTOFMEMORY;
+ return NOERROR;
+}
+
+STDAPI FreeBSTR(BSTR* pstr)
+{
+ if ( *pstr == NULL ) return S_FALSE;
+ SysFreeString( *pstr );
+ return NOERROR;
+}
+
+HRESULT writeBString(BSTR* psz, const char *str)
+{
+ WCHAR WideStr[WA_MAX_PATH] = {0};
+ String s = str;
+ if (s.isempty()) s = "";
+ MultiByteToWideCharSZ(CP_ACP, 0, s, -1, WideStr, WA_MAX_PATH);
+ return WriteBSTR(psz, WideStr);
+}
+
+BrowserWnd::BrowserWnd() : HTMLContainer2(NULL, NULL), processor(NULL)
+{
+ setVirtual(0);
+
+ oleOk = FALSE;
+ homepage = L"about:blank";
+ timerset1 = 0;
+ timerset2 = 0;
+ cancelIEErrorPage = false;
+ scrollbarsflag = BROWSER_SCROLLBARS_DEFAULT;
+}
+
+BrowserWnd::~BrowserWnd()
+{
+ if (processor)
+ {
+ if (WASABI_API_APP) WASABI_API_APP->app_removeMessageProcessor(processor);
+ free(processor);
+ processor = NULL;
+ }
+ if (timerset1)
+ {
+ killTimer(MB_TIMERID1);
+ timerset1 = 0;
+ }
+ if (timerset2)
+ {
+ killTimer(MB_TIMERID2);
+ timerset2 = 0;
+ }
+
+ freeBrowserStuff();
+}
+
+bool BrowserWnd::InitializeLibrary()
+{
+ return (FALSE != HTMLContainer2_Initialize());
+}
+
+void BrowserWnd::UninitializeLibrary()
+{
+ HTMLContainer2_Uninitialize();
+}
+
+int BrowserWnd::onInit()
+{
+ BROWSER_PARENT::onInit();
+ if (isVisible())
+ onSetVisible(1);
+ updateScrollbars();
+ return 1;
+}
+
+void BrowserWnd::onSetVisible(int show)
+{
+ if (show) initBrowserStuff();
+}
+
+int BrowserWnd::initBrowserStuff()
+{
+ if (pUnk) return 1;
+
+ if (SUCCEEDED(OleInitialize(NULL))) oleOk = TRUE;
+ if (!oleOk) return 1;
+
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ hParent = gethWnd();
+
+ int usemozilla = 0;
+
+#ifdef WASABI_COMPILE_CONFIG
+ usemozilla = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Use Mozilla instead of IE for minibrowser");
+#endif
+
+ if (SUCCEEDED(Initialize()))
+ {
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr))
+ {
+ pWeb2->put_RegisterAsBrowser(VARIANT_TRUE);
+
+ if (deferednavigate.isempty())
+ {
+ if (!homepage.isempty())
+ minibrowser_navigateUrl(homepage);
+ else
+ minibrowser_navigateUrl(L"about:blank");
+ }
+ else minibrowser_navigateUrl(deferednavigate);
+ }
+ }
+ if (!processor && WASABI_API_APP)
+ {
+ processor = new BrowserMsgProc(this);
+ WASABI_API_APP->app_addMessageProcessor(processor);
+
+ }
+
+ ShowWindow(hParent, SW_SHOWNA);
+
+ return 1;
+}
+
+void BrowserWnd::freeBrowserStuff()
+{
+ if (oleOk)
+ {
+ Finish();
+ OleUninitialize();
+ oleOk = FALSE;
+#ifndef WASABINOMAINAPI
+ api->hint_garbageCollect();
+#endif
+
+ }
+}
+
+int BrowserWnd::minibrowser_navigateUrl(const wchar_t *url)
+{
+ HRESULT hr;
+
+ curpage = url;
+
+ hr = NavigateToName(url, 0);
+ if (FAILED(hr))
+ {
+ deferednavigate = url;
+ return 0;
+ }
+ return 1;
+}
+
+int BrowserWnd::minibrowser_back()
+{
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr))
+ {
+ pWeb2->GoBack();
+ pWeb2->Release();
+ }
+ return 1;
+}
+
+int BrowserWnd::minibrowser_forward()
+{
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr))
+ {
+ pWeb2->GoForward();
+ pWeb2->Release();
+ }
+ return 1;
+}
+
+int BrowserWnd::minibrowser_refresh()
+{
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr))
+ {
+ pWeb2->Refresh();
+ pWeb2->Release();
+ }
+ return 1;
+}
+
+int BrowserWnd::minibrowser_home()
+{
+ minibrowser_navigateUrl(homepage);
+ return 1;
+}
+
+int BrowserWnd::minibrowser_stop()
+{
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+ hr = GetIWebBrowser2(&pWeb2);
+ if (SUCCEEDED(hr))
+ {
+ pWeb2->Stop();
+ pWeb2->Release();
+ }
+ return 1;
+}
+
+HWND BrowserWnd::getOSHandle()
+{
+ return ::GetWindow(gethWnd(), GW_CHILD); // assumes setVirtual(0) in constructor
+}
+
+void BrowserWnd::onTargetNameTimer()
+{
+ updateTargetName();
+}
+
+void BrowserWnd::onScrollbarsFlagTimer()
+{
+ updateScrollbars();
+}
+
+void BrowserWnd::timerCallback(int id)
+{
+ switch (id)
+ {
+ case MB_TIMERID1:
+ onTargetNameTimer();
+ return ;
+ case MB_TIMERID2:
+ onScrollbarsFlagTimer();
+ return ;
+ }
+ BROWSER_PARENT::timerCallback(id);
+}
+
+void BrowserWnd::minibrowser_setTargetName(const wchar_t *name)
+{
+ targetname = name;
+ updateTargetName();
+}
+
+void BrowserWnd::updateTargetName()
+{
+ if (!doSetTargetName(targetname))
+ {
+ if (!timerset1) { setTimer(MB_TIMERID1, 100); timerset1 = 1; }
+ return ;
+ }
+ else
+ {
+ if (timerset1) { killTimer(MB_TIMERID1); timerset1 = 0; }
+ }
+}
+
+int BrowserWnd::doSetTargetName(const wchar_t *name)
+{
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+ IDispatch *id;
+
+ hr = GetIWebBrowser2(&pWeb2);
+
+ if (FAILED(hr)) return FALSE;
+
+ if (SUCCEEDED(pWeb2->get_Document(&id)) && id)
+ {
+ IHTMLDocument2 *doc;
+ if (SUCCEEDED(id->QueryInterface(IID_IHTMLDocument2, (void **)&doc)) && doc)
+ {
+ IHTMLWindow2 *w;
+ if (SUCCEEDED(doc->get_parentWindow(&w)) && w)
+ {
+ w->put_name(SysAllocString(targetname.getValue()));
+ w->Release();
+ doc->Release();
+ id->Release();
+ pWeb2->Release();
+ return 1;
+ }
+ doc->Release();
+ }
+ id->Release();
+ }
+ pWeb2->Release();
+ return 0;
+}
+
+const wchar_t *BrowserWnd::minibrowser_getTargetName()
+{
+ return targetname;
+}
+
+void BrowserWnd::OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
+{
+ int i = 0;
+ foreach(callbacks)
+ int r = callbacks.getfor()->minibrowsercb_onBeforeNavigate(URL->bstrVal, Flags->intVal, TargetFrameName->bstrVal);
+ if (i++ == 0) *Cancel = (r) ? VARIANT_TRUE : VARIANT_FALSE;
+ endfor;
+ updateScrollbars();
+
+}
+
+void BrowserWnd::minibrowser_setScrollbarsFlag(int a)
+{
+ scrollbarsflag = a;
+ updateScrollbars();
+}
+
+void BrowserWnd::updateScrollbars()
+{
+ if (!doSetScrollbars())
+ {
+ if (!timerset2) { setTimer(MB_TIMERID2, 100); timerset2 = 1; }
+ return ;
+ }
+ else
+ {
+ if (timerset2) { killTimer(MB_TIMERID2); timerset2 = 0; }
+ }
+}
+
+void BrowserWnd::OnDocumentComplete(IDispatch *pDispatch, VARIANT *URL)
+{
+ if (!targetname.isempty())
+ minibrowser_setTargetName(targetname);
+ foreach(callbacks)
+ callbacks.getfor()->minibrowsercb_onDocumentComplete(URL->bstrVal);
+ endfor;
+ updateScrollbars();
+}
+
+void BrowserWnd::OnDocumentReady(IDispatch *pDispatch, VARIANT *URL)
+{
+ if (!targetname.isempty())
+ minibrowser_setTargetName(targetname);
+ foreach(callbacks)
+ callbacks.getfor()->minibrowsercb_onDocumentReady(URL->bstrVal);
+ endfor;
+ updateScrollbars();
+}
+
+void BrowserWnd::OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel)
+{
+ if (TargetFrameName->bstrVal != NULL)
+ return; //TODO: send targetframe via api to script
+ foreach(callbacks)
+ callbacks.getfor()->minibrowsercb_onNavigateError(URL->bstrVal, StatusCode->intVal);
+ endfor;
+ if (cancelIEErrorPage) *Cancel = -1;
+}
+
+const wchar_t* BrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3)
+{
+ const wchar_t* ret = 0;
+ foreach(callbacks)
+ ret = callbacks.getfor()->minibrowsercb_messageToMaki(str1, str2, i1, i2, i3);
+ if (ret) break;
+ endfor;
+ return ret;
+}
+
+const wchar_t* BrowserWnd::minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3)
+{
+ // TODO feed JS w/ this info
+ return 0;
+}
+
+void BrowserWnd::minibrowser_scrape()
+{
+ IWebBrowser2 *browser=0;
+ GetIWebBrowser2(&browser);
+ IDispatch *docDisp=0;
+ IHTMLDocument2 *document = 0;
+ if (browser)
+ {
+ browser->get_Document(&docDisp);
+ if (docDisp)
+ {
+ docDisp->QueryInterface(&document);
+ docDisp->Release();
+ }
+ browser->Release();
+ }
+
+ if (document)
+ {
+ IHTMLElementCollection *links=0;
+ document->get_all(&links);
+
+ if (links)
+ {
+ IDispatch *anchorDisp=0;
+ VARIANT index;
+
+ VariantInit(&index);
+ index.vt = VT_I4;
+ index.intVal = 0;
+
+ links->item(index, index, &anchorDisp);
+ while (anchorDisp)
+ {
+ IHTMLAnchorElement *anchor=0;
+ anchorDisp->QueryInterface(&anchor);
+ if (anchor)
+ {
+ BSTR href=0;
+ anchor->get_href(&href);
+ if (href && (wa2.CanPlay(href) || wa2.IsPlaylist(href)))
+ {
+ foreach(callbacks)
+ callbacks.getfor()->minibrowsercb_onMediaLink(href);
+ endfor;
+ }
+ SysFreeString(href);
+ anchor->Release();
+ }
+
+ index.intVal++;
+ anchorDisp->Release();
+ links->item(index, index, &anchorDisp);
+ }
+
+ links->Release();
+ }
+ document->Release();
+ }
+
+}
+
+void BrowserWnd::minibrowser_getDocumentTitle(wchar_t *str, size_t len)
+{
+ IWebBrowser2 *browser=0;
+ GetIWebBrowser2(&browser);
+ IDispatch *docDisp=0;
+ IHTMLDocument2 *document = 0;
+ if (browser)
+ {
+ browser->get_Document(&docDisp);
+ if (docDisp)
+ {
+ docDisp->QueryInterface(&document);
+ docDisp->Release();
+ }
+ browser->Release();
+ }
+
+ if (document)
+ {
+ BSTR title_bstr;
+ document->get_title(&title_bstr);
+ document->Release();
+
+ WCSCPYN(str, title_bstr, len);
+ // the COM object SysAllocString'd this for us, so we need to free it via COM also
+ SysFreeString(title_bstr);
+ }
+ else
+ str[0]=0;
+}
+
+void BrowserWnd::minibrowser_setCancelIEErrorPage (bool cancel)
+{
+ cancelIEErrorPage = cancel;
+}
+
+int BrowserWnd::doSetScrollbars()
+{
+ HRESULT hr;
+ IWebBrowser2 *pWeb2;
+ IDispatch *id;
+
+ hr = GetIWebBrowser2(&pWeb2);
+
+ if (FAILED(hr)) return 0;
+
+ if (scrollbarsflag == BROWSER_SCROLLBARS_DEFAULT) return 1;
+
+ if (SUCCEEDED(pWeb2->get_Document(&id)) && id)
+ {
+ IHTMLDocument2 *doc;
+ if (SUCCEEDED(id->QueryInterface(IID_IHTMLDocument2, (void **)&doc)) && doc)
+ {
+ IHTMLElement *e;
+ if (SUCCEEDED(doc->get_body(&e)))
+ {
+ IHTMLStyle *s;
+ if (SUCCEEDED(e->get_style(&s)))
+ {
+ BSTR a;
+ switch (scrollbarsflag)
+ {
+ case BROWSER_SCROLLBARS_ALWAYS:
+ writeBString(&a, "scroll");
+ break;
+ case BROWSER_SCROLLBARS_AUTO:
+ writeBString(&a, "auto");
+ break;
+ case BROWSER_SCROLLBARS_NEVER:
+ writeBString(&a, "hidden");
+ break;
+ default:
+ a = NULL;
+ break;
+ }
+ if (a) s->put_overflow(a);
+ FreeBSTR(&a);
+ s->Release();
+ pWeb2->Release();
+ return 1;
+ }
+ e->Release();
+ }
+ doc->Release();
+ }
+ id->Release();
+ }
+ pWeb2->Release();
+ return 0;
+}
+
+const wchar_t *BrowserWnd::minibrowser_getCurrentUrl()
+{
+ return curpage;
+}
+
+STDMETHODIMP BrowserWnd::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
+{
+ *ppDispatch = (IDispatch*) new MinibrowserCOM(this); //TODO we might need to delete this as well!
+ return S_OK;
+}
+
+DWORD BrowserWnd::OnGetDownlodFlags(void)
+{
+ return DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_PRAGMA_NO_CACHE
+#ifdef WINAMP_FINAL_BUILD
+ |DLCTL_SILENT
+#endif
+ ;
+}
+
+
+#define CBCLASS BrowserMsgProc
+START_DISPATCH;
+CB(IFC_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage)
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/skin/widgets/mb/iebrowser.h b/Src/Wasabi/api/skin/widgets/mb/iebrowser.h
new file mode 100644
index 00000000..e0e61e35
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/iebrowser.h
@@ -0,0 +1,102 @@
+#ifndef __BROWSER_H
+#define __BROWSER_H
+
+class BrowserWnd;
+
+#define BROWSER_PARENT OSWnd
+#define IDC_SINKOBJ 0x9871 // arbitrary unique id
+#define MB_TIMERID1 0x1927
+#define MB_TIMERID2 0x1928
+
+class String;
+
+#include <nu/HTMLContainer2.h>
+#include <api/wnd/wndclass/oswnd.h>
+#include <api/wnd/minibrowser.h>
+
+class BrowserWnd : public BROWSER_PARENT, public HTMLContainer2, public MiniBrowserI {
+public:
+ BrowserWnd();
+ virtual ~BrowserWnd();
+
+public:
+ static bool InitializeLibrary();
+ static void UninitializeLibrary();
+
+public:
+ // ifc_window
+ virtual int onInit();
+ virtual void onSetVisible(int show);
+ virtual int handleDesktopAlpha() { return 0; }
+ DWORD OnGetDownlodFlags(void);
+
+ virtual int onMouseWheelUp(int click, int lines){return 1;}
+ virtual int onMouseWheelDown(int click, int lines){return 1;}
+
+ // OSWnd
+ virtual HWND getOSHandle();
+
+ // MiniBrowser
+ virtual int minibrowser_navigateUrl(const wchar_t *url);
+ virtual void minibrowser_setHome(const wchar_t *url) { homepage = url; }
+ virtual int minibrowser_back();
+ virtual int minibrowser_forward();
+ virtual int minibrowser_home();
+ virtual int minibrowser_refresh();
+ virtual int minibrowser_stop();
+ virtual void minibrowser_setTargetName(const wchar_t *name);
+ const wchar_t *minibrowser_getTargetName();
+ const wchar_t *minibrowser_getCurrentUrl();
+ virtual void minibrowser_addCB(MiniBrowserCallback *cb) { callbacks.addItem(cb); }
+ virtual ifc_window *minibrowser_getRootWnd() { return this; }
+
+ virtual void minibrowser_setScrollbarsFlag(int a); //BROWSER_SCROLLBARS_ALWAYS, BROWSER_SCROLLBARS_AUTO, BROWSER_SCROLLBARS_NEVER
+ virtual void minibrowser_scrape();
+ virtual void minibrowser_setCancelIEErrorPage(bool cancel);
+ void minibrowser_getDocumentTitle(wchar_t *str, size_t len);
+ virtual const wchar_t* minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3);
+ //
+ virtual void timerCallback(int id);
+ void onTargetNameTimer();
+
+ bool ProcessMessage(MSG *msg); // return true to 'eat' the message
+
+ bool cancelIEErrorPage;
+ const wchar_t* messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3);
+
+protected:
+ virtual void OnBeforeNavigate(IDispatch *pDispatch, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel);
+ virtual void OnDocumentComplete(IDispatch *pDispatch, VARIANT *URL);
+ virtual void OnDocumentReady(IDispatch *pDispatch, VARIANT *URL); // So we can get rid of all iFrame completes
+ virtual void OnNavigateError(IDispatch *pDispatch, VARIANT *URL, VARIANT *TargetFrameName, VARIANT *StatusCode, VARIANT_BOOL *Cancel);
+ virtual STDMETHODIMP GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch);
+ virtual int initBrowserStuff();
+ virtual void freeBrowserStuff();
+ virtual void onScrollbarsFlagTimer();
+ virtual int wantFocus() { return 1; }
+
+
+private:
+ virtual int doSetTargetName(const wchar_t *name);
+ virtual int doSetScrollbars();
+
+ virtual void updateTargetName();
+ virtual void updateScrollbars();
+
+
+
+
+ BOOL oleOk;
+ StringW homepage;
+ StringW deferednavigate;
+ StringW targetname;
+ StringW curpage;
+ int timerset1;
+ int timerset2;
+ PtrList<MiniBrowserCallback> callbacks;
+ int scrollbarsflag;
+ ifc_messageprocessor *processor;
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp
new file mode 100644
index 00000000..bdf22f41
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.cpp
@@ -0,0 +1,70 @@
+#include <precomp.h>
+#include "mainminibrowser.h"
+#include <api/script/scriptguid.h>
+#include <api/script/objects/guiobject.h>
+
+ScriptObject *MainMiniBrowser::getScriptObject()
+{
+ return WASABI_API_MAKI->maki_getObjectAtom(L"browser.main.object");
+}
+
+void MainMiniBrowser::back() {
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ C_Browser browser(so);
+ browser.back();
+ }
+}
+
+void MainMiniBrowser::forward(){
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ C_Browser browser(so);
+ browser.forward();
+ }
+}
+
+void MainMiniBrowser::refresh(){
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ C_Browser browser(so);
+ browser.refresh();
+ }
+}
+
+void MainMiniBrowser::stop(){
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ C_Browser browser(so);
+ browser.stop();
+ }
+}
+
+void MainMiniBrowser::home(){
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ C_Browser browser(so);
+ browser.home();
+ }
+}
+
+void MainMiniBrowser::navigateUrl(const wchar_t *url){
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ C_Browser browser(so);
+ browser.navigateUrl(url);
+ }
+}
+
+#ifdef WASABI_COMPILE_WNDMGR
+void MainMiniBrowser::popMb(){
+ ScriptObject *so = getScriptObject();
+ if (so) {
+ GuiObject *go = static_cast<GuiObject*>(so->vcpu_getInterface(guiObjectGuid));
+ if (go) {
+ go->guiobject_popParentLayout();
+ }
+ }
+}
+#endif
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h
new file mode 100644
index 00000000..10af16ad
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/mainminibrowser.h
@@ -0,0 +1,24 @@
+#ifndef __MAINMINIBROWSER_H
+#define __MAINMINIBROWSER_H
+
+#include <wasabicfg.h>
+#include <api/script/objects/c_script/c_browser.h>
+#include <api/script/objects/c_script/h_browser.h>
+
+class MainMiniBrowser {
+
+ public:
+
+ static ScriptObject *getScriptObject();
+ static void back();
+ static void forward();
+ static void refresh();
+ static void stop();
+ static void home();
+ static void navigateUrl(const wchar_t *url);
+#ifdef WASABI_COMPILE_WNDMGR
+ static void popMb();
+#endif
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp b/Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp
new file mode 100644
index 00000000..59dd1c34
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/mbsvc.cpp
@@ -0,0 +1,48 @@
+#include "precomp.h"
+#include <direct.h>
+#include "mbsvc.h"
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(MbSvc_Svc);
+DECLARE_SERVICETSINGLE(svc_miniBrowser, MbSvc);
+END_SERVICES(MbSvc_Svc, _MbSvc_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_MbSvc; }
+#else
+extern "C" { int __link_MbSvc; }
+#endif
+
+#endif
+
+MbSvc::MbSvc()
+{
+ BrowserWnd::InitializeLibrary();
+}
+
+MbSvc::~MbSvc()
+{
+ BrowserWnd::UninitializeLibrary();
+}
+
+int MbSvc::testGuid(GUID g) {
+ return (g == GUID_MINIBROWSER_ANY || g == GUID_MINIBROWSER_IEACTIVEX);
+}
+
+MiniBrowser *MbSvc::createMiniBrowser() {
+ BrowserWnd *w = new BrowserWnd;
+ browsers.addItem(w);
+ return w;
+}
+
+void MbSvc::destroyMiniBrowser(MiniBrowser *b) {
+ ASSERT(b != NULL);
+ BrowserWnd *bw = static_cast<BrowserWnd *>(b->minibrowser_getRootWnd());
+ ASSERT(bw != NULL);
+ int i = browsers.searchItem(bw);
+ if (i < 0) return;
+ browsers.removeByPos(i);
+ delete bw;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvc.h b/Src/Wasabi/api/skin/widgets/mb/mbsvc.h
new file mode 100644
index 00000000..c1c1b4b8
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/mbsvc.h
@@ -0,0 +1,26 @@
+#ifndef _SVC_H
+#define _SVC_H
+
+#include <api/service/svcs/svc_minibrowser.h>
+#include <bfc/ptrlist.h>
+#include <api/service/svc_enum.h>
+#include "iebrowser.h"
+
+class MbSvc : public svc_miniBrowserI {
+public:
+ MbSvc();
+ ~MbSvc();
+
+ static const char *getServiceName() { return "Internet Explorer ActiveX MiniBrowser Service"; }
+ virtual int testQueryFormat(int queryformat) { return WaSvc::MINIBROWSER; }
+
+ virtual int testGuid(GUID g);
+ virtual MiniBrowser *createMiniBrowser();
+ virtual void destroyMiniBrowser(MiniBrowser *w);
+
+private:
+
+ PtrList<BrowserWnd> browsers;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp
new file mode 100644
index 00000000..1f68199b
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.cpp
@@ -0,0 +1,26 @@
+#include "precomp.h"
+#include "mbsvc.h"
+#include "svc.h"
+#include "../studio/genwnd.h"
+
+static WACNAME wac;
+WAComponentClient *the = &wac;
+WACNAME *wacmb = &wac;
+
+#include "../studio/services/servicei.h"
+
+// {181BE599-2249-4a1c-8283-4EE85FE8EC86}
+static const GUID guid =
+{ 0x181be599, 0x2249, 0x4a1c, { 0x82, 0x83, 0x4e, 0xe8, 0x5f, 0xe8, 0xec, 0x86 } };
+
+WACNAME::WACNAME() {
+ registerService(new waServiceFactoryT<svc_miniBrowser, MbSvc>);
+}
+
+WACNAME::~WACNAME() {
+}
+
+GUID WACNAME::getGUID() {
+ return guid;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h
new file mode 100644
index 00000000..e7d94564
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/mbsvcwac.h
@@ -0,0 +1,24 @@
+#ifndef _MB_H
+#define _MB_H
+
+#include "../ns_database/nde.h"
+#include "../studio/wac.h"
+
+#define WACNAME WACmb
+
+class GenWnd;
+
+class WACNAME : public WAComponentClient {
+ public:
+ WACNAME();
+ virtual ~WACNAME();
+
+ virtual const char *getName() { return "Internet Explorer ActiveX MiniBrowser Service"; };
+ virtual GUID getGUID();
+
+ private:
+};
+
+extern WACNAME *wacmb;
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp
new file mode 100644
index 00000000..f70c8609
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/minibrowser.cpp
@@ -0,0 +1,36 @@
+#include <precomp.h>
+#include "minibrowser.h"
+
+#define CBCLASS MiniBrowserCallbackI
+START_DISPATCH;
+ CB(MINIBROWSER_ONBEFORENAVIGATE, minibrowsercb_onBeforeNavigate);
+ VCB(MINIBROWSER_ONDOCUMENTCOMPLETE, minibrowsercb_onDocumentComplete);
+ VCB(MINIBROWSER_ONDOCUMENTREADY, minibrowsercb_onDocumentReady);
+ VCB(MINIBROWSER_ONNAVIGATEERROR, minibrowsercb_onNavigateError);
+ VCB(MINIBROWSER_ONMEDIALINK, minibrowsercb_onMediaLink);
+ CB(MINIBROWSER_MESSAGETOMAKI, minibrowsercb_messageToMaki);
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS MiniBrowserI
+START_DISPATCH;
+ CB(MINIBROWSER_GETROOTWND, minibrowser_getRootWnd);
+ CB(MINIBROWSER_NAVIGATEURL, minibrowser_navigateUrl);
+ CB(MINIBROWSER_BACK, minibrowser_back);
+ CB(MINIBROWSER_FORWARD, minibrowser_forward);
+ CB(MINIBROWSER_HOME, minibrowser_home);
+ CB(MINIBROWSER_REFRESH, minibrowser_refresh);
+ CB(MINIBROWSER_STOP, minibrowser_stop);
+ VCB(MINIBROWSER_SETTARGETNAME, minibrowser_setTargetName);
+ CB(MINIBROWSER_GETTARGETNAME, minibrowser_getTargetName);
+ CB(MINIBROWSER_GETCURRENTURL, minibrowser_getCurrentUrl);
+ VCB(MINIBROWSER_ADDCB, minibrowser_addCB);
+ VCB(MINIBROWSER_SETHOME, minibrowser_setHome);
+ VCB(MINIBROWSER_SETSCROLLFLAG, minibrowser_setScrollbarsFlag);
+ VCB(MINIBROWSER_SCRAPE, minibrowser_scrape);
+ VCB(MINIBROWSER_SETCANCELIEERRORPAGE, minibrowser_setCancelIEErrorPage);
+ VCB(MINIBROWSER_GETDOCUMENTTITLE, minibrowser_getDocumentTitle);
+ CB(MINIBROWSER_MESSAGETOJS, minibrowser_messageToJS);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowser.h b/Src/Wasabi/api/skin/widgets/mb/minibrowser.h
new file mode 100644
index 00000000..f08a5564
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/minibrowser.h
@@ -0,0 +1,215 @@
+#ifndef __MINIBROWSER_H
+#define __MINIBROWSER_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+class ifc_window;
+
+class MiniBrowserCallback : public Dispatchable {
+ public:
+ int minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame);
+ void minibrowsercb_onDocumentComplete(const wchar_t *url);
+ void minibrowsercb_onDocumentReady(const wchar_t *url);
+ void minibrowsercb_onMediaLink(const wchar_t *url);
+ void minibrowsercb_onNavigateError(const wchar_t *url, int status);
+ const wchar_t* minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3);
+
+ enum {
+ MINIBROWSER_ONBEFORENAVIGATE = 10,
+ MINIBROWSER_ONDOCUMENTCOMPLETE = 20,
+ MINIBROWSER_ONMEDIALINK = 30,
+ MINIBROWSER_ONNAVIGATEERROR = 40,
+ MINIBROWSER_ONDOCUMENTREADY = 50,
+ MINIBROWSER_MESSAGETOMAKI = 60,
+ };
+};
+
+inline int MiniBrowserCallback ::minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) {
+ return _call(MINIBROWSER_ONBEFORENAVIGATE, 0, url, flags, frame);
+}
+
+inline void MiniBrowserCallback ::minibrowsercb_onDocumentComplete(const wchar_t *url) {
+ _voidcall(MINIBROWSER_ONDOCUMENTCOMPLETE, url);
+}
+
+inline void MiniBrowserCallback ::minibrowsercb_onDocumentReady(const wchar_t *url) {
+ _voidcall(MINIBROWSER_ONDOCUMENTREADY, url);
+}
+
+inline void MiniBrowserCallback ::minibrowsercb_onNavigateError(const wchar_t *url, int status) {
+ _voidcall(MINIBROWSER_ONNAVIGATEERROR, url, status);
+}
+
+inline void MiniBrowserCallback ::minibrowsercb_onMediaLink(const wchar_t *url) {
+ _voidcall(MINIBROWSER_ONMEDIALINK, url);
+}
+
+inline const wchar_t* MiniBrowserCallback ::minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3) {
+ return _call(MINIBROWSER_MESSAGETOMAKI, (const wchar_t*)0, str1, str2, i1, i2, i3);
+}
+
+class MiniBrowserCallbackI : public MiniBrowserCallback {
+ public:
+ virtual int minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame)=0;
+ virtual void minibrowsercb_onDocumentComplete(const wchar_t *url)=0;
+ virtual void minibrowsercb_onDocumentReady(const wchar_t *url)=0;
+ virtual void minibrowsercb_onMediaLink(const wchar_t *url)=0;
+ virtual void minibrowsercb_onNavigateError(const wchar_t *url, int status)=0;
+ virtual const wchar_t* minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+class MiniBrowser : public Dispatchable {
+
+ public:
+
+ ifc_window *minibrowser_getRootWnd();
+ int minibrowser_navigateUrl(const wchar_t *url);
+ int minibrowser_back();
+ int minibrowser_forward();
+ int minibrowser_home();
+ int minibrowser_refresh();
+ int minibrowser_stop();
+ void minibrowser_setTargetName(const wchar_t *name);
+ const wchar_t *minibrowser_getTargetName();
+ const wchar_t *minibrowser_getCurrentUrl();
+ void minibrowser_getDocumentTitle(wchar_t *str, size_t len);
+ void minibrowser_addCB(MiniBrowserCallback *cb);
+ void minibrowser_setHome(const wchar_t *url);
+ void minibrowser_setScrollbarsFlag(int a); // BROWSER_SCROLLBARS_ALWAYS, BROWSER_SCROLLBARS_AUTO, BROWSER_SCROLLBARS_NEVER
+ void minibrowser_scrape();
+ virtual void minibrowser_setCancelIEErrorPage(bool cancel);
+ virtual const wchar_t* minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3);
+
+ enum {
+ MINIBROWSER_GETROOTWND = 100,
+ MINIBROWSER_NAVIGATEURL = 200,
+ MINIBROWSER_BACK = 300,
+ MINIBROWSER_FORWARD = 400,
+ MINIBROWSER_HOME = 500,
+ MINIBROWSER_REFRESH = 600,
+ MINIBROWSER_STOP = 700,
+ MINIBROWSER_SETTARGETNAME = 800,
+ MINIBROWSER_GETTARGETNAME = 900,
+ MINIBROWSER_GETCURRENTURL = 1000,
+ MINIBROWSER_ADDCB = 1100,
+ MINIBROWSER_SETHOME = 1200,
+ MINIBROWSER_SETSCROLLFLAG = 1300,
+ MINIBROWSER_SCRAPE = 2000,
+ MINIBROWSER_GETDOCUMENTTITLE = 2100,
+ MINIBROWSER_SETCANCELIEERRORPAGE = 2200,
+ MINIBROWSER_MESSAGETOJS = 2300,
+ };
+
+ enum {
+ BROWSER_SCROLLBARS_DEFAULT = -1,
+ BROWSER_SCROLLBARS_ALWAYS = 0,
+ BROWSER_SCROLLBARS_AUTO = 1,
+ BROWSER_SCROLLBARS_NEVER = 2,
+ };
+
+};
+
+inline ifc_window *MiniBrowser::minibrowser_getRootWnd() {
+ return _call(MINIBROWSER_GETROOTWND, (ifc_window *)NULL);
+}
+
+inline int MiniBrowser::minibrowser_navigateUrl(const wchar_t *url) {
+ return _call(MINIBROWSER_NAVIGATEURL, 0, url);
+}
+
+inline int MiniBrowser::minibrowser_back() {
+ return _call(MINIBROWSER_BACK, 0);
+}
+
+inline int MiniBrowser::minibrowser_forward() {
+ return _call(MINIBROWSER_FORWARD, 0);
+}
+
+inline int MiniBrowser::minibrowser_home() {
+ return _call(MINIBROWSER_HOME, 0);
+}
+
+inline int MiniBrowser::minibrowser_refresh() {
+ return _call(MINIBROWSER_REFRESH, 0);
+}
+
+inline int MiniBrowser::minibrowser_stop() {
+ return _call(MINIBROWSER_STOP, 0);
+}
+
+inline void MiniBrowser::minibrowser_setHome(const wchar_t *url) {
+ _voidcall(MINIBROWSER_SETHOME, url);
+}
+
+inline void MiniBrowser::minibrowser_setTargetName(const wchar_t *name) {
+ _voidcall(MINIBROWSER_SETTARGETNAME, name);
+}
+
+inline const wchar_t *MiniBrowser::minibrowser_getTargetName() {
+ return _call(MINIBROWSER_GETTARGETNAME, (const wchar_t *)NULL);
+}
+
+inline void MiniBrowser::minibrowser_getDocumentTitle(wchar_t *str, size_t len) {
+ _voidcall(MINIBROWSER_GETDOCUMENTTITLE, str, len);
+}
+
+inline const wchar_t *MiniBrowser::minibrowser_getCurrentUrl() {
+ return _call(MINIBROWSER_GETCURRENTURL, (const wchar_t *)NULL);
+}
+
+inline void MiniBrowser::minibrowser_addCB(MiniBrowserCallback *cb) {
+ _voidcall(MINIBROWSER_ADDCB, cb);
+}
+
+inline void MiniBrowser::minibrowser_setScrollbarsFlag(int a) {
+ _voidcall(MINIBROWSER_SETSCROLLFLAG, a);
+}
+
+inline void MiniBrowser::minibrowser_scrape()
+{
+ _voidcall(MINIBROWSER_SCRAPE);
+}
+
+inline void MiniBrowser::minibrowser_setCancelIEErrorPage(bool cancel)
+{
+ _voidcall(MINIBROWSER_SETCANCELIEERRORPAGE, cancel);
+}
+
+inline const wchar_t* MiniBrowser::minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3)
+{
+ return _call(MINIBROWSER_MESSAGETOJS, (const wchar_t *)NULL, str1, str2, i1, i2, i3);
+}
+
+class MiniBrowserI : public MiniBrowser {
+
+ public:
+
+ virtual ifc_window *minibrowser_getRootWnd()=0;
+ virtual int minibrowser_navigateUrl(const wchar_t *url)=0;
+ virtual int minibrowser_back()=0;
+ virtual int minibrowser_forward()=0;
+ virtual int minibrowser_home()=0;
+ virtual int minibrowser_refresh()=0;
+ virtual int minibrowser_stop()=0;
+ virtual void minibrowser_setTargetName(const wchar_t *name)=0;
+ virtual const wchar_t *minibrowser_getTargetName()=0;
+ virtual const wchar_t *minibrowser_getCurrentUrl()=0;
+ virtual void minibrowser_getDocumentTitle(wchar_t *str, size_t len)=0;
+ virtual void minibrowser_addCB(MiniBrowserCallback *cb)=0;
+ virtual void minibrowser_setHome(const wchar_t *url)=0;
+ virtual void minibrowser_setScrollbarsFlag(int a)=0;
+ virtual void minibrowser_scrape()=0;
+ virtual void minibrowser_setCancelIEErrorPage(bool cancel)=0;
+ virtual const wchar_t* minibrowser_messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+
+#endif
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp
new file mode 100644
index 00000000..87cc8d30
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.cpp
@@ -0,0 +1,173 @@
+#include <precomp.h>
+#include <api/skin/widgets/mb/minibrowserwnd.h>
+#include <api/skin/widgets/mb/minibrowser.h>
+#include <api/service/svcs/svc_minibrowser.h>
+#include <api/service/svc_enum.h>
+
+MiniBrowserWnd::MiniBrowserWnd(GUID mb_provider) {
+ mb = NULL;
+ mbsvc = MiniBrowserSvcEnum(mb_provider).getFirst();
+}
+
+MiniBrowserWnd::~MiniBrowserWnd() {
+ if (mbsvc) {
+ if (mb) mbsvc->destroyMiniBrowser(mb);
+ WASABI_API_SVC->service_release(mbsvc);
+ }
+}
+
+int MiniBrowserWnd::onInit() {
+ int r = MBWND_PARENT::onInit();
+ if (mb) {
+ mb->minibrowser_getRootWnd()->setStartHidden(1);
+ mb->minibrowser_getRootWnd()->setParent(this);
+ r &= mb->minibrowser_getRootWnd()->init(this);
+ }
+ onSetVisible(1);
+ return r;
+}
+
+void MiniBrowserWnd::onSetVisible(int i) {
+ MBWND_PARENT::onSetVisible(i);
+ if (i) {
+ if (!mb && mbsvc) {
+ mb = mbsvc->createMiniBrowser();
+ if (mb) {
+ mb->minibrowser_addCB(this);
+ mb->minibrowser_getRootWnd()->setStartHidden(1);
+ mb->minibrowser_getRootWnd()->setParent(this);
+ mb->minibrowser_getRootWnd()->init(this);
+ if (isPostOnInit())
+ onResize();
+ }
+ }
+ } else {
+ if (mb) {
+ mbsvc->destroyMiniBrowser(mb);
+ mb = NULL;
+ }
+ }
+ if (mb && mb->minibrowser_getRootWnd()) {
+ mb->minibrowser_getRootWnd()->setVisible(i);
+ }
+}
+
+int MiniBrowserWnd::onResize() {
+ int r = MBWND_PARENT::onResize();
+ if (mb && mb->minibrowser_getRootWnd()) {
+ RECT r;
+ getClientRect(&r);
+ mb->minibrowser_getRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ }
+ return r;
+}
+
+
+int MiniBrowserWnd::handleDesktopAlpha() {
+ if (mb && mb->minibrowser_getRootWnd()) return mb->minibrowser_getRootWnd()->handleDesktopAlpha();
+ return 0;
+}
+
+int MiniBrowserWnd::handleRatio() {
+ if (mb && mb->minibrowser_getRootWnd()) return mb->minibrowser_getRootWnd()->handleRatio();
+ return 0;
+}
+
+int MiniBrowserWnd::navigateUrl(const wchar_t *url) {
+ if (mb) return mb->minibrowser_navigateUrl(url);
+ return 0;
+}
+
+int MiniBrowserWnd::back() {
+ if (mb) return mb->minibrowser_back();
+ return 0;
+}
+
+int MiniBrowserWnd::forward() {
+ if (mb) return mb->minibrowser_forward();
+ return 0;
+}
+
+int MiniBrowserWnd::home() {
+ if (mb) return mb->minibrowser_home();
+ return 0;
+}
+
+int MiniBrowserWnd::refresh() {
+ if (mb) return mb->minibrowser_refresh();
+ return 0;
+}
+
+int MiniBrowserWnd::stop() {
+ if (mb) return mb->minibrowser_stop();
+ return 0;
+}
+
+void MiniBrowserWnd::setTargetName(const wchar_t *name) {
+ if (mb) mb->minibrowser_setTargetName(name);
+}
+
+const wchar_t *MiniBrowserWnd::getTargetName() {
+ if (mb) return mb->minibrowser_getTargetName();
+ return NULL;
+}
+
+const wchar_t *MiniBrowserWnd::getCurrentUrl() {
+ if (mb) return mb->minibrowser_getCurrentUrl();
+ return NULL;
+}
+
+int MiniBrowserWnd::onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) {
+ return 0; // return 1 to cancel navigation
+}
+
+void MiniBrowserWnd::onDocumentComplete(const wchar_t *url) {
+}
+
+void MiniBrowserWnd::onDocumentReady(const wchar_t *url) {
+}
+
+void MiniBrowserWnd::onNavigateError(const wchar_t *url, int status) {
+}
+
+void MiniBrowserWnd::onMediaLink(const wchar_t *url) {
+}
+
+const wchar_t* MiniBrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3)
+{
+ return 0;
+}
+
+int MiniBrowserWnd::minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame) {
+ return onBeforeNavigate(url, flags, frame);
+}
+
+void MiniBrowserWnd::minibrowsercb_onDocumentComplete(const wchar_t *url) {
+ onDocumentComplete(url);
+}
+
+void MiniBrowserWnd::minibrowsercb_onDocumentReady(const wchar_t *url) {
+ onDocumentReady(url);
+}
+
+void MiniBrowserWnd::minibrowsercb_onMediaLink(const wchar_t *url) {
+ onMediaLink(url);
+}
+
+void MiniBrowserWnd::minibrowsercb_onNavigateError(const wchar_t *url, int status) {
+ onNavigateError(url, status);
+}
+
+const wchar_t* MiniBrowserWnd::minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3)
+{
+ return messageToMaki(str1, str2, i1, i2, i3);
+}
+
+void MiniBrowserWnd::setScrollbarsFlag(int a) {
+ if (mb) mb->minibrowser_setScrollbarsFlag(a);
+}
+
+MiniBrowser *MiniBrowserWnd::getBrowser() {
+ return mb;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h
new file mode 100644
index 00000000..093e466e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/minibrowserwnd.h
@@ -0,0 +1,57 @@
+#ifndef __MINIBROWSERWND_H
+#define __MINIBROWSERWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/service/svcs/svc_minibrowser.h>
+#include <api/skin/widgets/mb/minibrowser.h>
+
+#define MBWND_PARENT GuiObjectWnd
+
+class MiniBrowserWnd : public MBWND_PARENT, public MiniBrowserCallbackI {
+
+ public:
+
+ MiniBrowserWnd(GUID mb_provider=GUID_MINIBROWSER_ANY);
+ virtual ~MiniBrowserWnd();
+
+ virtual int handleDesktopAlpha();
+ virtual int handleRatio();
+ virtual void onSetVisible(int i);
+ virtual int onResize();
+ virtual int onInit();
+
+ virtual int navigateUrl(const wchar_t *url);
+ virtual int back();
+ virtual int forward();
+ virtual int home();
+ virtual int refresh();
+ virtual int stop();
+ virtual void setTargetName(const wchar_t *name);
+ virtual const wchar_t *getTargetName();
+ virtual const wchar_t *getCurrentUrl();
+ virtual int onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame); // return 1 to cancel navigation
+ virtual void onDocumentComplete(const wchar_t *url);
+ virtual void onDocumentReady(const wchar_t *url);
+ virtual void onNavigateError(const wchar_t *url, int status);
+ virtual void onMediaLink(const wchar_t *url);
+ virtual const wchar_t* messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3);
+
+ virtual void setScrollbarsFlag(int a); // BROWSER_SCROLLBARS_ALWAYS, BROWSER_SCROLLBARS_AUTO, BROWSER_SCROLLBARS_NEVER
+
+ virtual int minibrowsercb_onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame);
+ virtual void minibrowsercb_onDocumentComplete(const wchar_t *url);
+ virtual void minibrowsercb_onDocumentReady(const wchar_t *url);
+ virtual void minibrowsercb_onMediaLink(const wchar_t *url);
+ virtual void minibrowsercb_onNavigateError(const wchar_t *url, int status);
+ virtual const wchar_t* minibrowsercb_messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3);
+
+ virtual MiniBrowser *getBrowser();
+
+ private:
+
+ MiniBrowser *mb;
+ svc_miniBrowser *mbsvc;
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp
new file mode 100644
index 00000000..bb86a227
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.cpp
@@ -0,0 +1,180 @@
+#include "precomp.h"
+
+#include "scriptbrowser.h"
+
+#include "main.h"
+
+#include "script/script.h"
+#include "script/scriptmgr.h"
+#include "script/vcpu.h"
+
+#include "mbmgr.h"
+
+BrowserScriptController _browserController;
+BrowserScriptController *browserController = &_browserController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct BrowserScriptController::exportedFunction[] = {
+ {"gotoUrl", 1, (void*)ScriptBrowserWnd::script_vcpu_gotoUrl },
+ {"back", 0, (void*)ScriptBrowserWnd::script_vcpu_back },
+ {"forward", 0, (void*)ScriptBrowserWnd::script_vcpu_forward },
+ {"home", 0, (void*)ScriptBrowserWnd::script_vcpu_home},
+ {"refresh", 0, (void*)ScriptBrowserWnd::script_vcpu_refresh},
+ {"setTargetName", 1, (void*)ScriptBrowserWnd::script_vcpu_setTargetName},
+ {"onBeforeNavigate", 3, (void*)ScriptBrowserWnd::script_vcpu_onBeforeNavigate},
+ {"onDocumentComplete", 1, (void*)ScriptBrowserWnd::script_vcpu_onDocumentComplete},
+
+};
+// --------------------------------------------------------
+
+const wchar_t *BrowserScriptController::getClassName() {
+ return L"Browser";
+}
+
+const wchar_t *BrowserScriptController::getAncestorClassName() {
+ return L"GuiObject";
+}
+
+ScriptObject *BrowserScriptController::instantiate() {
+ ScriptBrowserWnd *sb = new ScriptBrowserWnd;
+ ASSERT(sb != NULL);
+ return sb->getScriptObject();
+}
+
+void BrowserScriptController::destroy(ScriptObject *o) {
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd *>(o->vcpu_getInterface(browserGuid));
+ ASSERT(sb != NULL);
+ delete sb;
+}
+
+void *BrowserScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for browsers yet
+}
+
+void BrowserScriptController::deencapsulate(void *o) {
+}
+
+int BrowserScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *BrowserScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID BrowserScriptController::getClassGuid() {
+ return browserGuid;
+}
+
+ScriptBrowserWnd::ScriptBrowserWnd() {
+ getScriptObject()->vcpu_setInterface(browserGuid, (void *)static_cast<ScriptBrowserWnd *>(this));
+ getScriptObject()->vcpu_setClassName("Browser");
+ getScriptObject()->vcpu_setController(browserController);
+}
+
+ScriptBrowserWnd::~ScriptBrowserWnd() {
+}
+
+int ScriptBrowserWnd::setXmlParam(const char *name, const char *value) {
+ if (SCRIPTBROWSERWND_PARENT::setParam(name, value)) return 1;
+ else if (STRCASEEQL(name,"url")) defurl = value;
+ else if (STRCASEEQL(name,"mainmb")) setMainMB(WTOI(value));
+ else if (STRCASEEQL(name,"targetname")) setTargetName(value);
+ else return 0;
+ return 1;
+}
+
+int ScriptBrowserWnd::onInit() {
+ SCRIPTBROWSERWND_PARENT::onInit();
+ if (!defurl.isempty()) navigateUrl(defurl);
+ return 1;
+}
+
+void ScriptBrowserWnd::setMainMB(int m) {
+ if (m)
+ MBManager::setMainMB(this);
+ else
+ if (MBManager::getMainMB() == this)
+ MBManager::setMainMB(NULL);
+}
+
+int ScriptBrowserWnd::onBeforeNavigate(const char *url, int flags, const char *frame) {
+ if (SCRIPTBROWSERWND_PARENT::onBeforeNavigate(url, flags, frame)) return 1;
+ scriptVar v = script_vcpu_onBeforeNavigate(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url), MAKE_SCRIPT_INT(flags), MAKE_SCRIPT_STRING(frame));
+ if (SOM::isNumeric(&v)) return GET_SCRIPT_BOOLEAN(v);
+ return 0;
+}
+
+void ScriptBrowserWnd::onDocumentComplete(const char *url) {
+ SCRIPTBROWSERWND_PARENT::onDocumentComplete(url);
+ script_vcpu_onDocumentComplete(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url));
+}
+
+
+// VCPU
+
+scriptVar ScriptBrowserWnd::script_vcpu_gotoUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) {
+ SCRIPT_FUNCTION_INIT
+ ASSERT(url.type == SCRIPT_STRING);
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->navigateUrl(url.data.sdata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->back();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->forward();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->home();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->refresh();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->stop();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->setTargetName(GET_SCRIPT_STRING(name));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS3(o, browserController, url, flags, framename);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, url, flags, framename);
+}
+
+scriptVar ScriptBrowserWnd::script_vcpu_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, browserController, url);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, url);
+}
+
+
diff --git a/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h
new file mode 100644
index 00000000..3ff2b5d0
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/scriptbrowser.h
@@ -0,0 +1,63 @@
+#ifndef _SCRIPTBROWSER_H
+#define _SCRIPTBROWSER_H
+
+#include <api/skin/widgets/mb/minibrowserwnd.h>
+#include <api/script/script.h>
+#include <api/script/objects/guiobj.h>
+
+class BrowserScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern BrowserScriptController *browserController;
+
+
+#define SCRIPTBROWSERWND_PARENT MiniBrowserWnd
+class ScriptBrowserWnd : public SCRIPTBROWSERWND_PARENT {
+public:
+
+ ScriptBrowserWnd();
+ virtual ~ScriptBrowserWnd();
+
+ void setMainMB(int m);
+ virtual int setXmlParam(const wchar_t *name, const wchar_t *value);
+ virtual int onInit();
+
+ virtual int handleDesktopAlpha() { return 0; } // showing the browser will turn off desktop alpha on the parent layout
+
+ virtual void onDocumentComplete(const char *url);
+ virtual int onBeforeNavigate(const char *url, int flags, const char *frame);
+
+public:
+ static scriptVar script_vcpu_gotoUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+ static scriptVar script_vcpu_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar script_vcpu_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+ static scriptVar script_vcpu_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename);
+
+private:
+
+ String defurl;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp
new file mode 100644
index 00000000..f22f3580
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.cpp
@@ -0,0 +1,39 @@
+#include "precomp.h"
+#include "sharedminibrowser.h"
+#include "wnds/skinwnd.h"
+#include "../studio/api.h"
+#include "../common/mainminibrowser.h"
+
+void SharedMiniBrowser::navigateUrl(const char *url) {
+ if (!m_monitor) {
+ m_monitor = new SkinMonitor();
+ }
+
+ if (!MainMiniBrowser::getScriptObject()) {
+
+ if (!m_inserted) {
+ String xml = "buf:\n";
+ xml += "<WinampAbstractionLayer>\n";
+ xml += " <groupdef id=\"addon.shared.minibrowser\" name=\"MiniBrowser\">\n";
+ xml += " <browser mainmb=\"1\" x=\"0\" y=\"0\" w=\"0\" h=\"0\" relatw=\"1\" relath=\"1\" />\n";
+ xml += " </groupdef>\n";
+ xml += "</WinampAbstractionLayer>\n";
+ WASABI_API_SKIN->loadSkinFile(xml);
+ m_inserted = 1;
+ }
+
+ SkinWnd("addon.shared.minibrowser", WASABISTDCONTAINER_RESIZABLE_NOSTATUS);
+ ASSERTPR(MainMiniBrowser::getScriptObject() != NULL, "Something is really wrong with wasabi");
+ }
+
+ MainMiniBrowser::navigateUrl(url);
+ MainMiniBrowser::popMb();
+}
+
+void SharedMiniBrowser::shutdown() {
+ if (m_monitor) delete m_monitor;
+ m_monitor = NULL;
+}
+
+int SharedMiniBrowser::m_inserted = 0;
+SkinMonitor *SharedMiniBrowser::m_monitor = NULL; \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h
new file mode 100644
index 00000000..57dbf15c
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/sharedminibrowser.h
@@ -0,0 +1,33 @@
+#ifndef _SHAREDMINIBROWSER_H
+#define _SHAREDMINIBROWSER_H
+
+#include "../studio/skincb.h"
+
+class SkinMonitor;
+
+class SharedMiniBrowser {
+public:
+ static void navigateUrl(const char *url);
+ static void shutdown();
+
+ static int m_inserted;
+ static SkinMonitor *m_monitor;
+
+};
+
+class SkinMonitor : public SkinCallbackI {
+public:
+ SkinMonitor() {
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+ }
+ virtual ~SkinMonitor() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+ }
+ virtual int skincb_onReset() {
+ SharedMiniBrowser::m_inserted = 0;
+ return 0;
+ }
+};
+
+
+#endif // _SHAREDMINIBROWSER_H
diff --git a/Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp
new file mode 100644
index 00000000..a8c82408
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.cpp
@@ -0,0 +1,385 @@
+#include <precomp.h>
+#include "xuibrowser.h"
+
+const wchar_t browserXuiObjectStr[] = L"Browser"; // This is the xml tag
+char browserXuiSvcName[] = "Browser xui object"; // this is the name of the xuiservice
+
+XMLParamPair ScriptBrowserWnd::params[] = {
+ {BROWSER_SETMAINMB, L"MAINMB"},
+ {BROWSER_SETSCROLLBARS, L"SCROLLBARS"},
+ {BROWSER_SETTARGETNAME, L"TARGETNAME"},
+ {BROWSER_SETURL, L"URL"},
+ };
+
+ScriptBrowserWnd::ScriptBrowserWnd()
+{
+ getScriptObject()->vcpu_setInterface(browserGuid, (void *)static_cast<ScriptBrowserWnd *>(this));
+ getScriptObject()->vcpu_setClassName(L"Browser"); // this is the script class name
+ getScriptObject()->vcpu_setController(browserController);
+
+ myxuihandle = newXuiHandle();
+CreateXMLParameters(myxuihandle);
+}
+
+void ScriptBrowserWnd::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTBROWSERWND_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ScriptBrowserWnd::~ScriptBrowserWnd()
+{
+
+ if (WASABI_API_MAKI->maki_getObjectAtom(MAIN_BROWSER_ATOM_NAME) == getScriptObject())
+ WASABI_API_MAKI->maki_setObjectAtom(MAIN_BROWSER_ATOM_NAME, NULL);
+}
+
+int ScriptBrowserWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return SCRIPTBROWSERWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case BROWSER_SETURL:
+ setUrl(value);
+ break;
+ case BROWSER_SETMAINMB:
+ setMainMB(WTOI(value));
+ break;
+ case BROWSER_SETTARGETNAME:
+ setTargetName(value);
+ break;
+ case BROWSER_SETSCROLLBARS:
+ setScrollbarsFlag(translateScrollbarFlag(value));
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int ScriptBrowserWnd::translateScrollbarFlag(const wchar_t *scrollbarflag)
+{
+ if (WCSCASEEQLSAFE(scrollbarflag, L"auto")) return MiniBrowser::BROWSER_SCROLLBARS_AUTO;
+ if (WCSCASEEQLSAFE(scrollbarflag, L"never")) return MiniBrowser::BROWSER_SCROLLBARS_NEVER;
+ if (WCSCASEEQLSAFE(scrollbarflag, L"always")) return MiniBrowser::BROWSER_SCROLLBARS_ALWAYS;
+ if (WCSCASEEQLSAFE(scrollbarflag, L"default")) return MiniBrowser::BROWSER_SCROLLBARS_DEFAULT; // as specified by HTML content
+ return MiniBrowser::BROWSER_SCROLLBARS_AUTO;
+}
+
+void ScriptBrowserWnd::onSetVisible(int v)
+{
+ SCRIPTBROWSERWND_PARENT::onSetVisible(v);
+ if (v && !defurl.isempty() && _wcsicmp(defurl, getCurrentUrl() ? getCurrentUrl() : L""))
+ navigateUrl(defurl);
+}
+
+void ScriptBrowserWnd::setMainMB(int m)
+{
+ if (m)
+ WASABI_API_MAKI->maki_setObjectAtom(MAIN_BROWSER_ATOM_NAME, getScriptObject());
+ else
+ if (WASABI_API_MAKI->maki_getObjectAtom(MAIN_BROWSER_ATOM_NAME) == getScriptObject())
+ WASABI_API_MAKI->maki_setObjectAtom(MAIN_BROWSER_ATOM_NAME, NULL);
+}
+
+void ScriptBrowserWnd::setUrl(const wchar_t *url)
+{
+ defurl = url;
+ if (isVisible())
+ {
+ if (!defurl.isempty())
+ navigateUrl(defurl);
+ }
+}
+
+void ScriptBrowserWnd::setCancelIEErrorPage(bool cancel)
+{
+ MiniBrowser *browser = getBrowser();
+ if (browser) browser->minibrowser_setCancelIEErrorPage(cancel);
+}
+
+void ScriptBrowserWnd::Scrape()
+{
+ MiniBrowser *browser = getBrowser();
+ if (browser) browser->minibrowser_scrape();
+}
+
+void ScriptBrowserWnd::getDocumentTitle(wchar_t *str, size_t len)
+{
+ MiniBrowser *browser = getBrowser();
+ if (browser)
+ browser->minibrowser_getDocumentTitle(str, len);
+ else
+ str[0]=0;
+}
+
+int ScriptBrowserWnd::navigateUrl(const wchar_t *url)
+{
+ defurl = url;
+ return SCRIPTBROWSERWND_PARENT::navigateUrl(url);
+}
+
+int ScriptBrowserWnd::onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame)
+{
+ if (SCRIPTBROWSERWND_PARENT::onBeforeNavigate(url, flags, frame)) return 1;
+ scriptVar v = BrowserScriptController::browser_onBeforeNavigate(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url), MAKE_SCRIPT_INT(flags), MAKE_SCRIPT_STRING(frame));
+ if (v.type != SCRIPT_VOID)
+ return GET_SCRIPT_BOOLEAN(v);
+ return 0;
+}
+
+void ScriptBrowserWnd::onDocumentComplete(const wchar_t *url)
+{
+ SCRIPTBROWSERWND_PARENT::onDocumentComplete(url);
+ if (url)
+ BrowserScriptController::browser_onDocumentComplete(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url));
+}
+
+void ScriptBrowserWnd::onDocumentReady(const wchar_t *url)
+{
+ SCRIPTBROWSERWND_PARENT::onDocumentComplete(url);
+ if (url)
+ BrowserScriptController::browser_onDocumentReady(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url));
+}
+
+void ScriptBrowserWnd::onNavigateError(const wchar_t *url, int status)
+{
+ SCRIPTBROWSERWND_PARENT::onNavigateError(url, status);
+ BrowserScriptController::browser_onNavigateError(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url), MAKE_SCRIPT_INT(status));
+}
+
+void ScriptBrowserWnd::onMediaLink(const wchar_t *url)
+{
+ SCRIPTBROWSERWND_PARENT::onMediaLink(url);
+ if (url)
+ BrowserScriptController::browser_onMediaLink(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(url));
+}
+
+const wchar_t * ScriptBrowserWnd::messageToMaki(wchar_t* str1, wchar_t* str2, int intval1, int intval2, int intval3)
+{
+ const wchar_t* ret = SCRIPTBROWSERWND_PARENT::messageToMaki(str1, str2, intval1, intval2, intval3);
+ if (ret) return ret;
+
+ scriptVar v = BrowserScriptController::browser_messageToMaki(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(str1), MAKE_SCRIPT_STRING(str2), MAKE_SCRIPT_INT(intval1), MAKE_SCRIPT_INT(intval2), MAKE_SCRIPT_INT(intval3));
+ if (v.type == SCRIPT_STRING)
+ return v.data.sdata;
+ return 0;
+}
+
+const wchar_t * ScriptBrowserWnd::messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3)
+{
+ MiniBrowser *browser = getBrowser();
+ if (browser) return browser->minibrowser_messageToJS(str1, str2, i1, i2, i3);
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+BrowserScriptController _browserController;
+BrowserScriptController *browserController = &_browserController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct BrowserScriptController::exportedFunction[] = {
+ {L"gotoUrl", 1, (void*)BrowserScriptController::browser_navigateUrl },
+ {L"navigateUrl", 1, (void*)BrowserScriptController::browser_navigateUrl },
+ {L"back", 0, (void*)BrowserScriptController::browser_back },
+ {L"forward", 0, (void*)BrowserScriptController::browser_forward },
+ {L"home", 0, (void*)BrowserScriptController::browser_home},
+ {L"stop", 0, (void*)BrowserScriptController::browser_stop},
+ {L"refresh", 0, (void*)BrowserScriptController::browser_refresh},
+ {L"scrape", 0, (void*)BrowserScriptController::browser_scrape},
+ {L"setTargetName", 1, (void*)BrowserScriptController::browser_setTargetName},
+ {L"onBeforeNavigate", 3, (void*)BrowserScriptController::browser_onBeforeNavigate},
+ {L"onDocumentComplete", 1, (void*)BrowserScriptController::browser_onDocumentComplete},
+ {L"onDocumentReady", 1, (void*)BrowserScriptController::browser_onDocumentReady},
+ {L"onNavigateError", 2, (void*)BrowserScriptController::browser_onNavigateError},
+ {L"onMediaLink", 1, (void*)BrowserScriptController::browser_onMediaLink},
+ {L"getDocumentTitle", 0, (void*)BrowserScriptController::browser_getDocumentTitle},
+ {L"setCancelIEErrorPage",1, (void*)BrowserScriptController::browser_setCancelIEErrorPage},
+ {L"messageToMaki", 5, (void*)BrowserScriptController::browser_messageToMaki},
+ {L"messageToJS", 5, (void*)BrowserScriptController::browser_messageToJS},
+ };
+
+ScriptObject *BrowserScriptController::instantiate()
+{
+ ScriptBrowserWnd *sb = new ScriptBrowserWnd;
+ ASSERT(sb != NULL);
+ return sb->getScriptObject();
+}
+
+void BrowserScriptController::destroy(ScriptObject *o)
+{
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd *>(o->vcpu_getInterface(browserGuid));
+ ASSERT(sb != NULL);
+ delete sb;
+}
+
+void *BrowserScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for browsers yet
+}
+
+void BrowserScriptController::deencapsulate(void *o)
+{}
+
+int BrowserScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *BrowserScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+
+scriptVar BrowserScriptController::browser_navigateUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(url.type == SCRIPT_STRING);
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->navigateUrl(url.data.sdata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->back();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->forward();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->home();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->refresh();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->stop();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_scrape(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->Scrape();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_setCancelIEErrorPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cancel)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb) sb->setCancelIEErrorPage(!!cancel.data.idata);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb)
+ sb->setTargetName(GET_SCRIPT_STRING(name));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar BrowserScriptController::browser_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS3(o, browserController, url, flags, framename);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, url, flags, framename);
+}
+
+scriptVar BrowserScriptController::browser_messageToMaki(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS5(o, browserController, str1, str2, i1, i2, i3);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT5(o, str1, str2, i1, i2, i3);
+}
+
+scriptVar BrowserScriptController::browser_messageToJS(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ if (sb)
+ {
+ const wchar_t * ret = sb->messageToJS(str1.data.sdata, str2.data.sdata, i1.data.idata, i2.data.idata, i3.data.idata);
+ if (ret)
+ return MAKE_SCRIPT_STRING(ret);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar BrowserScriptController::browser_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, browserController, url);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, url);
+}
+
+scriptVar BrowserScriptController::browser_onDocumentReady(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, browserController, url);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, url);
+}
+
+scriptVar BrowserScriptController::browser_onNavigateError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar status)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, browserController, url, status);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, url, status);
+}
+
+scriptVar BrowserScriptController::browser_onMediaLink(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, browserController, url);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, url);
+}
+
+static wchar_t docTitle[1024];
+
+/*string*/ scriptVar BrowserScriptController::browser_getDocumentTitle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptBrowserWnd *sb = static_cast<ScriptBrowserWnd*>(o->vcpu_getInterface(browserGuid));
+ docTitle[0]=0;
+ if (sb) sb->getDocumentTitle(docTitle, 1024);
+ return MAKE_SCRIPT_STRING(docTitle);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/mb/xuibrowser.h b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.h
new file mode 100644
index 00000000..90989240
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mb/xuibrowser.h
@@ -0,0 +1,106 @@
+#ifndef __XUIBROWSER_H
+#define __XUIBROWSER_H
+
+#include <api/skin/widgets/mb/minibrowserwnd.h>
+#include <api/script/objcontroller.h>
+
+#define MAIN_BROWSER_ATOM_NAME L"browser.main.object"
+#define SCRIPTBROWSERWND_PARENT MiniBrowserWnd
+
+// -----------------------------------------------------------------------------------------------------
+class ScriptBrowserWnd : public SCRIPTBROWSERWND_PARENT {
+
+ public:
+
+ ScriptBrowserWnd();
+ virtual ~ScriptBrowserWnd();
+
+ virtual void onSetVisible(int v);
+
+ // XuiObject
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ // MiniBrowserWnd
+ int onBeforeNavigate(const wchar_t *url, int flags, const wchar_t *frame);
+ void onDocumentComplete(const wchar_t *url);
+ void onDocumentReady(const wchar_t *url);
+ void onNavigateError(const wchar_t *url, int status);
+ void onMediaLink(const wchar_t *url);
+ void getDocumentTitle(wchar_t *str, size_t len);
+
+ virtual int navigateUrl(const wchar_t *url);
+ const wchar_t* messageToMaki(wchar_t* str1, wchar_t* str2, int i1, int i2, int i3);
+ const wchar_t* messageToJS(const wchar_t* str1, const wchar_t* str2, int i1, int i2, int i3);
+
+ // --
+
+ void setUrl(const wchar_t *url);
+ void setMainMB(int tf);
+ void Scrape(); // benski> added Aug 17 2007
+
+ void setCancelIEErrorPage(bool cancel);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ enum {
+ BROWSER_SETURL = 0,
+ BROWSER_SETMAINMB,
+ BROWSER_SETTARGETNAME,
+ BROWSER_SETSCROLLBARS,
+ BROWSER_CANCELIEERRORPAGE,
+ };
+static XMLParamPair params[];
+ int translateScrollbarFlag(const wchar_t *scrollbarflag);
+
+ StringW defurl;
+ int myxuihandle;
+};
+
+// -----------------------------------------------------------------------------------------------------
+class BrowserScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"Browser"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return browserGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar browser_navigateUrl(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+ static scriptVar browser_back(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_forward(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_scrape(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_setTargetName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar browser_onDocumentComplete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+ static scriptVar browser_onDocumentReady(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+ static scriptVar browser_onNavigateError(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar status);
+ static scriptVar browser_onBeforeNavigate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url, scriptVar flags, scriptVar framename);
+ static scriptVar browser_messageToMaki(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3);
+ static scriptVar browser_messageToJS(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str1, scriptVar str2, scriptVar i1, scriptVar i2, scriptVar i3);
+ static scriptVar browser_onMediaLink(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar url);
+ static /*string*/ scriptVar browser_getDocumentTitle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar browser_setCancelIEErrorPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cancel);
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern BrowserScriptController *browserController;
+
+extern const wchar_t browserXuiObjectStr[];
+extern char browserXuiSvcName[];
+class BrowserXuiSvc : public XuiObjectSvc<ScriptBrowserWnd, browserXuiObjectStr, browserXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/mouseredir.cpp b/Src/Wasabi/api/skin/widgets/mouseredir.cpp
new file mode 100644
index 00000000..5fe58c15
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mouseredir.cpp
@@ -0,0 +1,221 @@
+#include <precomp.h>
+#include "mouseredir.h"
+
+#include <api/skin/widgets/group.h>
+#include <api/script/scriptmgr.h>
+#include <api/script/objects/smap.h>
+#include <api/script/objects/sregion.h>
+const wchar_t mouseRedirXuiObjectStr[] = L"MouseRedir"; // This is the xml tag
+char mouseRedirXuiSvcName[] = "MouseRedir xui object"; // this is the name of the xuiservice
+
+XMLParamPair MouseRedir::params[] = {
+ {MOUSEREDIR_TARGET, L"target"},
+ };
+MouseRedir::MouseRedir()
+{
+ getScriptObject()->vcpu_setInterface(mouseredirGuid, (void *)static_cast<MouseRedir *>(this));
+ getScriptObject()->vcpu_setClassName(L"MouseRedir");
+ getScriptObject()->vcpu_setController(mouseredirController);
+ rgn = NULL;
+ redirobject = NULL;
+ getGuiObject()->guiobject_setClickThrough(0);
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void MouseRedir::CreateXMLParameters(int master_handle)
+{
+ //MOUSEREDIR_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_REQUIRED);
+}
+
+MouseRedir::~MouseRedir()
+{
+ delete rgn;
+}
+
+int MouseRedir::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (_xuihandle == xuihandle)
+ {
+ switch (xmlattributeid)
+ {
+ case MOUSEREDIR_TARGET:
+ setTarget(value);
+ return 1;
+ }
+ }
+ return MOUSEREDIR_PARENT::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, value);
+}
+
+int MouseRedir::onInit()
+{
+ MOUSEREDIR_PARENT::onInit();
+ if (!deferedredirobjectid.isempty())
+ doSetTarget(deferedredirobjectid);
+ deferedredirobjectid = L"";
+ return 1;
+}
+
+int MouseRedir::mouseInRegion(int x, int y)
+{
+ if (!rgn) return 1;
+ RECT cr;
+ getClientRect(&cr);
+ POINT pt = {x - cr.left, y - cr.top};
+ return rgn->ptInRegion(&pt);
+}
+
+void MouseRedir::setRedirection(GuiObject *o)
+{
+ redirobject = o;
+}
+
+GuiObject *MouseRedir::getRedirection()
+{
+ return redirobject;
+}
+
+void MouseRedir::setTarget(const wchar_t *id)
+{
+ if (!isInited())
+ deferedredirobjectid = id;
+ else
+ doSetTarget(id);
+}
+
+void MouseRedir::doSetTarget(const wchar_t *id)
+{
+ Group *g = getGuiObject()->guiobject_getParentGroup();
+ if (!g) return ;
+ GuiObject *o = g->getObject(id);
+ if (!o) return ;
+ redirobject = o;
+}
+
+MouseRedirScriptController _mouseredirController;
+MouseRedirScriptController *mouseredirController = &_mouseredirController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct MouseRedirScriptController::exportedFunction[] = {
+ {L"setRegionFromMap", 1, (void*)MouseRedir::script_vcpu_setRegionFromMap},
+ {L"setRegion", 1, (void*)MouseRedir::script_vcpu_setRegion },
+ {L"setRedirection", 1, (void*)MouseRedir::script_vcpu_setRedirection},
+ {L"getRedirection", 0, (void*)MouseRedir::script_vcpu_getRedirection},
+ };
+// --------------------------------------------------------
+
+
+const wchar_t *MouseRedirScriptController::getClassName()
+{
+ return L"MouseRedir";
+}
+
+const wchar_t *MouseRedirScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *MouseRedirScriptController::instantiate()
+{
+ MouseRedir *m = new MouseRedir;
+ if (!m) return NULL;
+ return m->getScriptObject();
+}
+
+void MouseRedirScriptController::destroy(ScriptObject *o)
+{
+ MouseRedir *obj = static_cast<MouseRedir*>(o->vcpu_getInterface(mouseredirGuid));
+ ASSERT(obj != NULL);
+ delete obj;
+}
+
+void *MouseRedirScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for mouseredir yet
+}
+
+void MouseRedirScriptController::deencapsulate(void *)
+{}
+
+
+int MouseRedirScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *MouseRedirScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID MouseRedirScriptController::getClassGuid()
+{
+ return mouseredirGuid;
+}
+
+//---------------------------------------------------------------------------
+
+
+void MouseRedir::setRegionFromMap(SMap *map, int byte, int inversed)
+{
+ if (rgn)
+ {
+ delete rgn;
+ rgn = NULL;
+ }
+ rgn = new RegionI(map->getBitmap(), NULL, 0, 0, FALSE, 1, (unsigned char)byte, inversed);
+}
+
+void MouseRedir::setRegion(SRegion *reg)
+{
+ if (rgn) { delete rgn; rgn = NULL; }
+ if (!reg) { invalidate(); return ; }
+ rgn = new RegionI();
+ rgn->addRegion(reg->getRegion());
+}
+
+ifc_window *MouseRedir::getForwardWnd()
+{
+ if (redirobject) return redirobject->guiobject_getRootWnd();
+ return this;
+}
+
+scriptVar MouseRedir::script_vcpu_setRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj)
+{
+ SCRIPT_FUNCTION_INIT;
+ MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid));
+ if (mr) mr->setRedirection(static_cast<GuiObject *>(GET_SCRIPT_OBJECT_AS(obj, guiObjectGuid)));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar MouseRedir::script_vcpu_getRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid));
+ return MAKE_SCRIPT_OBJECT(mr ? mr ->getRedirection()->guiobject_getScriptObject() : NULL);
+}
+
+scriptVar MouseRedir::script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv)
+{
+ SCRIPT_FUNCTION_INIT;
+ ASSERT(SOM::isNumeric(&byte));
+ ASSERT(SOM::isNumeric(&inv));
+ MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid));
+ SMap *sm = static_cast<SMap*>(GET_SCRIPT_OBJECT_AS(map, mapGuid));
+ if (mr) mr->setRegionFromMap(sm, SOM::makeInt(&byte), SOM::makeInt(&inv));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar MouseRedir::script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg)
+{
+ SCRIPT_FUNCTION_INIT;
+ MouseRedir *mr = static_cast<MouseRedir *>(o->vcpu_getInterface(mouseredirGuid));
+ SRegion *r = static_cast<SRegion *>(GET_SCRIPT_OBJECT_AS(reg, regionGuid));
+ if (mr) mr->setRegion(r);
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/mouseredir.h b/Src/Wasabi/api/skin/widgets/mouseredir.h
new file mode 100644
index 00000000..c852c34e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/mouseredir.h
@@ -0,0 +1,88 @@
+//PORTABLE
+#ifndef _MOUSEREDIR_H
+#define _MOUSEREDIR_H
+
+#include <api/script/script.h>
+#include <api/script/objects/guiobj.h>
+#include <bfc/string/StringW.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define MOUSEREDIR_PARENT GuiObjectWnd
+
+// {9B2E341B-6C98-40fa-8B85-0C1B6EE89405}
+static const GUID mouseredirGuid =
+{ 0x9b2e341b, 0x6c98, 0x40fa, { 0x8b, 0x85, 0xc, 0x1b, 0x6e, 0xe8, 0x94, 0x5 } };
+
+
+class SMap;
+class SRegion;
+
+class MouseRedirScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void destroy(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern MouseRedirScriptController *mouseredirController;
+
+class MouseRedir : public MOUSEREDIR_PARENT {
+public:
+ MouseRedir();
+ virtual ~MouseRedir();
+
+ virtual int onInit();
+
+ void setTarget(const wchar_t *id);
+
+ void setRedirection(GuiObject *o);
+ GuiObject *getRedirection();
+ void setRegionFromMap(SMap *map, int byte, int inversed);
+ void setRegion(SRegion *reg);
+ virtual int mouseInRegion(int x, int y);
+
+ virtual ifc_window *getForwardWnd();
+ virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+protected:
+/*static */void CreateXMLParameters(int master_handle);
+ enum {
+ MOUSEREDIR_TARGET=0,
+ };
+
+
+private:
+ GuiObject *redirobject;
+ StringW deferedredirobjectid;
+ int xuihandle;
+ static XMLParamPair params[];
+
+ void doSetTarget(const wchar_t *id);
+ RegionI *rgn;
+
+public:
+ static scriptVar script_vcpu_setRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_vcpu_getRedirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv);
+ static scriptVar script_vcpu_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg);
+};
+
+extern const wchar_t mouseRedirXuiObjectStr[];
+extern char mouseRedirXuiSvcName[];
+class MouseRedirXuiSvc : public XuiObjectSvc<MouseRedir, mouseRedirXuiObjectStr, mouseRedirXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/objdirwnd.cpp b/Src/Wasabi/api/skin/widgets/objdirwnd.cpp
new file mode 100644
index 00000000..d49515a6
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/objdirwnd.cpp
@@ -0,0 +1,227 @@
+#include <precomp.h>
+
+#include "objdirwnd.h"
+
+#include <api/wnd/contextmenu.h>
+#include <api/wnd/dragitemi.h>
+#include <api/skin/widgets/customobject.h>
+#include <bfc/parse/pathparse.h>
+
+ObjDirWnd::ObjDirWnd() :
+ objdir(NULL), displaygroup(NULL) { }
+
+ObjDirWnd::~ObjDirWnd() {
+ WASABI_API_SVC->service_release(objdir);
+ if (displaygroup != NULL) WASABI_API_SKIN->group_destroy(displaygroup);
+}
+
+void ObjDirWnd::setTargetDirName(const wchar_t *dirname) {
+ objectDirName = dirname;
+//FUCKO: reset here
+}
+
+void ObjDirWnd::setActionTarget(const wchar_t *targetname) {
+ objectDirTarget = targetname;
+}
+
+void ObjDirWnd::setDisplayTarget(const wchar_t *name) {
+ displayTarget = name;
+}
+
+void ObjDirWnd::setDefaultDisplay(const wchar_t *display) {
+ defaultDisplay = display;
+}
+
+int ObjDirWnd::onInit() {
+ OBJDIRWND_PARENT::onInit();
+
+ setSorted(TRUE);
+
+ ASSERT(!objectDirName.isempty());
+ objdir = ObjectDirEnum(objectDirName).getNext();
+
+ if (objdir != NULL) {
+ setHilitedColor(L"pledit.currentOutline");//FUCKO from service
+ viewer_addViewItem(objdir);
+
+ int nobj = objdir->getNumObjects();
+ for (int i = 0; i < nobj; i++) {
+ ObjectHandle hand = objdir->enumObject(i);
+ folderify(createObjItem(hand));
+ }
+ }
+
+ return 1;
+}
+
+int ObjDirWnd::onContextMenu(int x, int y) {
+ if (objdir != NULL) {
+ DragItemT<svc_objectDir> di(objdir);
+ ContextMenu(this, &di);
+ }
+ return 1;
+}
+
+int ObjDirWnd::onPreItemContextMenu(TreeItem *item, int x, int y) {
+ BaseObjItem *boi = static_cast<BaseObjItem*>(item);
+ if (boi->getParam() == OBJTYPE_OBJ) {
+ ObjItem *oi = static_cast<ObjItem*>(item);
+ int r = objdir->contextMenu(this, x, y, oi->getObjectHandle());
+ if (r == -1) {
+ editItemLabel(item);
+ }
+ } else {
+ // handle other item types here
+ }
+ return 1;
+}
+
+int ObjDirWnd::compareItem(TreeItem *p1, TreeItem *p2) {
+ BaseObjItem *b1 = static_cast<BaseObjItem*>(p1);
+ BaseObjItem *b2 = static_cast<BaseObjItem*>(p2);
+ int r = CMP3(b1->sortorder, b2->sortorder);
+ if (r == 0) return OBJDIRWND_PARENT::compareItem(p1, p2);
+ return r;
+}
+
+int ObjDirWnd::viewer_onEvent(svc_objectDir *item, int event, intptr_t param2, void *ptr, size_t ptrlen) {
+ switch (event) {
+ case svc_objectDir::Event_OBJECT_ADDED: {
+ int sel_after = (enumAllItems(0) == NULL);
+ ObjItem *oi = createObjItem(param2);
+ folderify(oi);
+ if (sel_after) selectItemDeferred(oi);
+ }
+ break;
+ case svc_objectDir::Event_OBJECT_REMOVED: {
+ ObjItem *pli = getObjItemForHandle(param2);
+ delItemDeferred(pli);
+ }
+ break;
+ case svc_objectDir::Event_OBJECT_LABELCHANGE: {
+ ObjItem *pli = getObjItemForHandle(param2);
+ const wchar_t *name = objdir->getObjectLabel(pli->getObjectHandle());
+ pli->setLabel(name);
+ }
+ break;
+ case svc_objectDir::Event_OBJECT_PATHCHANGE: {
+ ObjItem *pli = getObjItemForHandle(param2);
+ folderify(pli);
+ }
+ break;
+ case svc_objectDir::Event_OBJECT_SORTORDERCHANGE: {
+ ObjItem *pli = getObjItemForHandle(param2);
+ ASSERT(pli != NULL);
+ pli->sortorder = objdir->getObjectSortOrder(param2);
+ sortTreeItems();
+ }
+ break;
+ }
+ return 1;
+}
+
+ObjItem *ObjDirWnd::createObjItem(ObjectHandle handle) {
+ ObjItem *ret = new ObjItem(handle, objdir->getObjectLabel(handle));
+ const wchar_t *nn = objdir->getObjectIcon(handle);
+ if (nn && *nn) {
+ SkinBitmap *ic = new SkinBitmap(nn);
+ ret->setIcon(ic);
+ }
+ ret->hittable = objdir->getObjectSelectable(handle);
+ ret->sortorder = objdir->getObjectSortOrder(handle);
+ return ret;
+}
+
+ObjItem *ObjDirWnd::getObjItemForHandle(ObjectHandle handle) {
+ for (int i = 0; ; i++) {
+ TreeItem *it = enumAllItems(i);
+ if (it == NULL) break;
+ BaseObjItem *boi = static_cast<BaseObjItem*>(it);
+ if (boi->getParam() != OBJTYPE_OBJ) continue;
+ ObjItem *plit = static_cast<ObjItem *>(it);
+ if (plit->getObjectHandle() == handle) return plit;
+ }
+ return NULL;
+}
+
+void ObjDirWnd::folderify(ObjItem *item) {
+ if (item->getTree() != NULL)
+ removeTreeItem(item);
+
+ PathParserW pp(objdir->getObjectPath(item->getObjectHandle()));
+ TreeItem *prevpar = NULL;
+
+ for (int i = 0; i < pp.getNumStrings(); i++) {
+ TreeItem *newpar = NULL;
+ // check for already-existing folder
+ for (int j = 0; ; j++) {
+ if (prevpar == NULL) { // search top level
+ newpar = enumRootItem(j);
+ } else { // search prevpar children
+ newpar = prevpar->getNthChild(j);
+ }
+
+ if (newpar == NULL) break; // out of thingies
+ BaseObjItem *boi = static_cast<BaseObjItem*>(newpar);
+ if (boi->getParam() != OBJTYPE_FOLDER) continue;
+ ObjDirFolderItem *fi = static_cast<ObjDirFolderItem*>(newpar);
+ if (fi->dying) continue;
+
+ if (!wcscmp(boi->getLabel(), pp.enumString(i))) {
+ break;
+ }
+ }
+ if (newpar == NULL) {
+ newpar = new ObjDirFolderItem(pp.enumString(i));
+ addTreeItem(newpar, prevpar, FALSE, TRUE);
+ expandItemDeferred(newpar);
+ }
+ prevpar = newpar;
+ }
+
+ // now attach it
+ addTreeItem(item, prevpar);
+}
+
+void ObjDirWnd::onItemSelected(TreeItem *item) {
+ BaseObjItem *boi = static_cast<BaseObjItem*>(item);
+ if (boi->getParam() == OBJTYPE_OBJ) {
+ ObjItem *objitem = static_cast<ObjItem *>(item);
+ ObjectHandle handle = objitem->getObjectHandle();
+ StringW display(objdir->getObjectDisplayGroup(handle));
+ if (display.isempty()) display = defaultDisplay;
+ if (!display.isempty())
+ {
+ GuiObject *go = findObject(displayTarget);
+ if (go != NULL)
+ {
+ CustomObject *co = static_cast<CustomObject *>(go->guiobject_getScriptObject()->vcpu_getInterface(customObjectGuid));
+ if (co != NULL) {
+ if (displaygroupname != display) {
+ co->customobject_setRootWnd(NULL);
+ ifc_window *prev = displaygroup;
+ if (prev != NULL) WASABI_API_SKIN->group_destroy(prev);
+ displaygroup = WASABI_API_SKIN->group_create(display);
+ co->customobject_setRootWnd(displaygroup);
+ displaygroupname = display;
+ }
+ }
+ }
+ }
+ // tell the objdir
+ objdir->onAction(svc_objectDir::ODACTION_SELECTED, this, objectDirTarget, handle);
+ } else {
+ // handle other item types here
+ }
+}
+
+void ObjDirWnd::onItemDeselected(TreeItem *item) {
+ BaseObjItem *boi = static_cast<BaseObjItem*>(item);
+ if (boi->getParam() == OBJTYPE_OBJ) {
+ ObjItem *objitem = static_cast<ObjItem *>(item);
+ ObjectHandle handle = objitem->getObjectHandle();
+ objdir->onAction(svc_objectDir::ODACTION_DESELECTED, this, objectDirTarget, handle);
+ } else {
+ // handle other item types here
+ }
+}
diff --git a/Src/Wasabi/api/skin/widgets/objdirwnd.h b/Src/Wasabi/api/skin/widgets/objdirwnd.h
new file mode 100644
index 00000000..fc6ce78f
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/objdirwnd.h
@@ -0,0 +1,90 @@
+#ifndef _OBJDIRWND_H
+#define _OBJDIRWND_H
+
+#include <api/wnd/wndclass/treewnd.h>
+#include <api/service/svcs/svc_objectdir.h>
+#include <bfc/depview.h>
+
+enum OBJ_type { OBJTYPE_OBJ, OBJTYPE_FOLDER };
+class BaseObjItem : public TreeItemParam<OBJ_type> {
+protected:
+ BaseObjItem(OBJ_type type, const wchar_t *label) : TreeItemParam<OBJ_type>(type, label), sortorder(0) { }
+public:
+ int sortorder;
+};
+
+class ObjItem : public BaseObjItem {
+public:
+ ObjItem(ObjectHandle _handle, const wchar_t *label=NULL) : hittable(TRUE), handle(_handle), BaseObjItem(OBJTYPE_OBJ, label) {}
+
+ ObjectHandle getObjectHandle() const { return handle; }
+
+ virtual int onBeginLabelEdit() { return 0; } // allow editing
+ virtual int isHitTestable() { return hittable; }
+
+ int hittable;
+
+private:
+ ObjectHandle handle;
+};
+
+class ObjDirFolderItem : public BaseObjItem {
+public:
+ ObjDirFolderItem(const wchar_t *label) : BaseObjItem(OBJTYPE_FOLDER, label), dying(0) {
+ setIcon(new SkinBitmap(L"player.button.thinger"));
+ }
+ virtual void onChildItemRemove(TreeItem *item) {
+ if (getNumChildren() == 0) {
+ dying = 1;
+ getTree()->delItemDeferred(this);
+ }
+ }
+
+ int dying;
+};
+
+#define OBJDIRWND_PARENT TreeWnd
+class ObjDirWnd : public OBJDIRWND_PARENT, DependentViewerTPtr<svc_objectDir> {
+public:
+ ObjDirWnd();
+ virtual ~ObjDirWnd();
+
+ void setTargetDirName(const wchar_t *dirname);
+
+ void setActionTarget(const wchar_t *targetname);
+
+ void setDisplayTarget(const wchar_t *name);
+
+ void setDefaultDisplay(const wchar_t *display);
+
+ virtual int onInit();
+
+ virtual int onContextMenu(int x, int y);
+ virtual int onPreItemContextMenu(TreeItem *item, int x, int y);
+ virtual int compareItem(TreeItem *p1, TreeItem *p2);
+
+ virtual int viewer_onEvent(svc_objectDir *item, int event, intptr_t param2, void *ptr, size_t ptrlen);
+
+protected:
+ ObjItem *createObjItem(ObjectHandle handle);
+ ObjItem *getObjItemForHandle(ObjectHandle handle);
+
+ void folderify(ObjItem *item);
+
+private:
+ virtual void onItemSelected(TreeItem *item);
+ virtual void onItemDeselected(TreeItem *item);
+
+ svc_objectDir *objdir;
+ StringW objectDirName, objectDirTarget, displayTarget, defaultDisplay;
+ ifc_window *displaygroup;
+ StringW displaygroupname;
+};
+
+template <class TREEITEMCLASS>
+class ObjDirWndT : public ObjDirWnd {
+public:
+ virtual ObjItem *createObjItem(ObjectHandle handle) { return new TREEITEMCLASS(handle); }
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/pathpicker.cpp b/Src/Wasabi/api/skin/widgets/pathpicker.cpp
new file mode 100644
index 00000000..baa0c443
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/pathpicker.cpp
@@ -0,0 +1,111 @@
+#include <precomp.h>
+#include "pathpicker.h"
+#include <api/script/objects/guiobject.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/util/selectfile.h>
+
+#define PATHPICKER_MAIN_GROUP L"wasabi.pathpicker.main.group"
+#define PATHPICKER_BUTTON L"pathpicker.button"
+#define PATHPICKER_TEXT L"pathpicker.text"
+
+// -----------------------------------------------------------------------
+PathPicker::PathPicker()
+{
+ abstract_setAllowDeferredContent(1);
+ abstract_setContent(PATHPICKER_MAIN_GROUP);
+ clicks_button = NULL;
+ disable_cfg_event = 0;
+}
+
+PathPicker::~PathPicker() {
+}
+
+int PathPicker::onInit() {
+ int rt = PATHPICKER_PARENT::onInit();
+ return rt;
+}
+
+void PathPicker::abstract_onNewContent() {
+ PATHPICKER_PARENT::abstract_onNewContent();
+ trapControls();
+ updatePathInControl();
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+int PathPicker::onReloadConfig() {
+ int r = PATHPICKER_PARENT::onReloadConfig();
+ disable_cfg_event = 1;
+ updatePathFromConfig(); // triggers onSelect
+ disable_cfg_event = 0;
+ return r;
+}
+
+void PathPicker::updatePathFromConfig() {
+
+ const wchar_t *val = getGuiObject()->guiobject_getCfgString();
+ const wchar_t *old = getPath();
+ if (old && val && !_wcsicmp(val, old)) return;
+
+ setPath(val);
+}
+#endif
+
+void PathPicker::trapControls() {
+ delete clicks_button;
+ clicks_button = NULL;
+
+ GuiObject *butGuiObj = getGuiObject()->guiobject_findObject(PATHPICKER_BUTTON);
+ if (butGuiObj) clicks_button = new PPClicksCallback(*butGuiObj, this);
+}
+
+void PathPicker::clickCallback() {
+ SelectFile sf(this,0,0);
+ sf.setDefaultDir(getPath());
+ if (sf.runSelector(L"directory",0,0)) {
+ StringW p = sf.getDirectory();
+ if (p[wcslen(p-1)] != '/' && p[wcslen(p-1)] != '\\')
+ p += L"\\";
+ setPath(p);
+ }
+}
+
+void PathPicker::setDefault() {
+#ifdef WASABI_COMPILE_CONFIG
+ onReloadConfig();
+#endif
+}
+
+void PathPicker::setPath(const wchar_t *path)
+{
+ if (WCSCASEEQLSAFE(curpath, path)) return;
+ curpath = path;
+ onPathChanged(path);
+}
+
+void PathPicker::onPathChanged(const wchar_t *newpath) {
+ updatePathInControl();
+ if (!disable_cfg_event) {
+#ifdef WASABI_COMPILE_CONFIG
+ if (newpath == NULL)
+ getGuiObject()->guiobject_setCfgString(L"");
+ else
+ getGuiObject()->guiobject_setCfgString(newpath);
+#endif
+ }
+}
+
+void PathPicker::updatePathInControl() {
+ GuiObject *content = getContent();
+ if (content != NULL) {
+ GuiObject *text = content->guiobject_findObject(PATHPICKER_TEXT);
+ if (text != NULL) {
+ C_Text t(*text);
+ if (curpath.isempty())
+ t.setText(L"");
+ else
+ t.setText(curpath);
+ }
+ }
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/pathpicker.h b/Src/Wasabi/api/skin/widgets/pathpicker.h
new file mode 100644
index 00000000..37b9127b
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/pathpicker.h
@@ -0,0 +1,183 @@
+#ifndef __PATHPICKER_H
+#define __PATHPICKER_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+#include <api/script/objects/c_script/h_button.h>
+
+#define PATHPICKER_PARENT GuiObjectWnd
+
+class PPClicksCallback;
+extern int __id;
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class PathPicker : public PATHPICKER_PARENT {
+
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ PathPicker();
+
+
+ virtual ~PathPicker();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void clickCallback();
+
+
+#ifdef WASABI_COMPILE_CONFIG
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onReloadConfig();
+#endif
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void abstract_onNewContent();
+ void setPath(const wchar_t *newpath);
+ const wchar_t *getPath() { return curpath; }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onPathChanged(const wchar_t *newpath);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void setDefault();
+
+ private:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void updatePathInControl();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+#ifdef WASABI_COMPILE_CONFIG
+ void updatePathFromConfig();
+#endif
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void trapControls();
+
+ PPClicksCallback *clicks_button;
+ StringW curpath;
+ int disable_cfg_event;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class PPClicksCallback : public H_GuiObject {
+ public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ PPClicksCallback(ScriptObject *trap, PathPicker *_callback) :
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ callback(_callback), H_GuiObject(trap) {
+ }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void hook_onLeftButtonDown(int x, int y) {
+ callback->clickCallback();
+ }
+ private:
+ PathPicker *callback;
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/pslider.cpp b/Src/Wasabi/api/skin/widgets/pslider.cpp
new file mode 100644
index 00000000..8d960f21
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/pslider.cpp
@@ -0,0 +1,371 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "pslider.h"
+#include <api/script/scriptmgr.h>
+#include <api/script/vcpu.h>
+#include <api/skin/skinparse.h>
+
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+#include "seqband.h"
+#include "seqpreamp.h"
+#include "svolbar.h"
+#include "sseeker.h"
+#include "spanbar.h"
+#endif
+
+char sliderObjectStr[] = "Slider"; // This is the xml tag
+char sliderXuiSvcName[] = "Slider xui object"; // this is the name of the xuiservice
+XMLParamPair PSliderWnd::params[] =
+{
+ {PSLIDER_SETBARLEFT, L"BARLEFT"},
+ {PSLIDER_SETBARMIDDLE, L"BARMIDDLE"},
+ {PSLIDER_SETBARRIGHT, L"BARRIGHT"},
+ {PSLIDER_SETDOWNTHUMB, L"DOWNTHUMB"},
+ {PSLIDER_SETHIGH, L"HIGH"},
+ {PSLIDER_SETHOTPOS, L"HOTPOS"},
+ {PSLIDER_SETHOTRANGE, L"HOTRANGE"},
+ {PSLIDER_SETHOVERTHUMB, L"HOVERTHUMB"},
+ {PSLIDER_SETLOW, L"LOW"},
+ {PSLIDER_SETORIENTATION, L"ORIENTATION"},
+ {PSLIDER_SETTHUMB, L"THUMB"},
+ {PSLIDER_SETSTRETCHTHUMB, L"STRETCHTHUMB"},
+ };
+
+PSliderWnd::PSliderWnd()
+{
+ setLimits(0, 255);
+ getScriptObject()->vcpu_setInterface(sliderGuid, (void *)static_cast<PSliderWnd *>(this));
+ getScriptObject()->vcpu_setClassName(L"Slider");
+ getScriptObject()->vcpu_setController(sliderController);
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void PSliderWnd::CreateXMLParameters(int master_handle)
+{
+ //PSLIDER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+PSliderWnd::~PSliderWnd()
+{}
+
+int PSliderWnd::setXuiParam(int _xuihandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (xuihandle != _xuihandle) return PSLIDER_PARENT::setXuiParam(_xuihandle, attrid, paramname, strvalue);
+ switch (attrid)
+ {
+ case PSLIDER_SETBARLEFT:
+ setLeftBmp(strvalue);
+ break;
+ case PSLIDER_SETBARMIDDLE:
+ setMiddleBmp(strvalue);
+ break;
+ case PSLIDER_SETBARRIGHT:
+ setRightBmp(strvalue);
+ break;
+ case PSLIDER_SETTHUMB:
+ setThumbBmp(strvalue);
+ break;
+ case PSLIDER_SETDOWNTHUMB:
+ setThumbDownBmp(strvalue);
+ break;
+ case PSLIDER_SETHOVERTHUMB:
+ setThumbHiliteBmp(strvalue);
+ break;
+ case PSLIDER_SETSTRETCHTHUMB:
+ setThumbStretched(_wtoi(strvalue));
+ break;
+ case PSLIDER_SETORIENTATION:
+ setOrientation(SkinParser::getOrientation(strvalue));
+ break;
+ case PSLIDER_SETLOW:
+ {
+ int mx = getMaxLimit();
+ setLimits(WTOI(strvalue), mx);
+#ifdef WASABI_COMPILE_CONFIG
+ reloadConfig();
+#endif
+ break;
+ }
+ case PSLIDER_SETHIGH:
+ {
+ int mn = getMinLimit();
+ setLimits(mn, WTOI(strvalue));
+#ifdef WASABI_COMPILE_CONFIG
+ reloadConfig();
+#endif
+ break;
+ }
+ case PSLIDER_SETHOTPOS:
+ {
+ int a = WTOI(strvalue);
+ setHotPosition(a);
+ break;
+ }
+ case PSLIDER_SETHOTRANGE:
+ {
+ int a = WTOI(strvalue);
+ setHotPosRange(a);
+ break;
+ }
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int PSliderWnd::onInit()
+{
+ setNoDefaultBackground(1);
+ PSLIDER_PARENT::onInit();
+ return 1;
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+void PSliderWnd::reloadConfig()
+{
+ if (getGuiObject()->guiobject_hasCfgAttrib())
+ onReloadConfig();
+}
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+int PSliderWnd::onReloadConfig()
+{
+ int newVal = getGuiObject()->guiobject_getCfgInt();
+ setPosition(newVal, 0);
+
+ return PSLIDER_PARENT::onReloadConfig();
+}
+#endif
+
+int PSliderWnd::onSetPosition()
+{
+ int r = PSLIDER_PARENT::onSetPosition();
+ scriptVar p = SOM::makeVar(SCRIPT_INT);
+ int intVal = getSliderPosition();
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgInt(intVal);
+#endif
+ SOM::assign(&p, intVal / scriptDivisor());
+ script_onSetPosition(SCRIPT_CALL, getScriptObject(), p);
+ return r;
+}
+
+int PSliderWnd::onPostedPosition(int pp)
+{
+ scriptVar p = SOM::makeVar(SCRIPT_INT);
+ int intVal = getSliderPosition();
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgInt(intVal);
+#endif
+ SOM::assign(&p, intVal / scriptDivisor());
+ script_onPostedPosition(SCRIPT_CALL, getScriptObject(), p);
+ return 1;
+}
+
+int PSliderWnd::onSetFinalPosition()
+{
+ int r = PSLIDER_PARENT::onSetPosition();
+ scriptVar p = SOM::makeVar(SCRIPT_INT);
+ int intVal = getSliderPosition();
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgInt(intVal);
+#endif
+ SOM::assign(&p, intVal / scriptDivisor());
+ script_onSetFinalPosition(SCRIPT_CALL, getScriptObject(), p);
+ return r;
+}
+
+SliderScriptController _sliderController;
+SliderScriptController *sliderController = &_sliderController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct SliderScriptController::exportedFunction[] = {
+ {L"setPosition", 1, (void*)PSliderWnd::script_setPosition },
+ {L"getPosition", 0, (void*)PSliderWnd::script_getPosition },
+ {L"onSetPosition", 1, (void*)PSliderWnd::script_onSetPosition },
+ {L"onPostedPosition", 1, (void*)PSliderWnd::script_onPostedPosition },
+ {L"onSetFinalPosition", 1, (void*)PSliderWnd::script_onSetFinalPosition },
+ {L"lock", 0, (void*)PSliderWnd::script_lock},
+ {L"unlock", 0, (void*)PSliderWnd::script_unlock},
+ };
+// --------------------------------------------------------
+
+const wchar_t *SliderScriptController::getClassName()
+{
+ return L"Slider";
+}
+
+const wchar_t *SliderScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *SliderScriptController::instantiate()
+{
+ PSliderWnd *s = new PSliderWnd;
+ ASSERT(s != NULL);
+ return s->getScriptObject();
+}
+
+void SliderScriptController::destroy(ScriptObject *o)
+{
+ PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid));
+ ASSERT(s != NULL);
+ delete s;
+}
+
+void *SliderScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for sliders yet
+}
+
+void SliderScriptController::deencapsulate(void *o)
+{}
+
+int SliderScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *SliderScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID SliderScriptController::getClassGuid()
+{
+ return sliderGuid;
+}
+
+
+const wchar_t *PSliderWnd::vcpu_getClassName()
+{
+ return L"Slider";
+}
+
+void PSliderWnd::lock ()
+{}
+
+void PSliderWnd::unlock()
+{}
+
+//------------------------------------------------------------------------
+
+scriptVar PSliderWnd::script_onSetPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, sliderController, p);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, p);
+}
+
+scriptVar PSliderWnd::script_onPostedPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, sliderController, p);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, p);
+}
+
+scriptVar PSliderWnd::script_onSetFinalPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, sliderController, p);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, p);
+}
+
+scriptVar PSliderWnd::script_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&v));
+ PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid));
+ if (s) s->setPosition(GET_SCRIPT_INT(v) * s->scriptDivisor());
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar PSliderWnd::script_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid));
+ if (s) return MAKE_SCRIPT_INT(s->getSliderPosition() / s->scriptDivisor());
+ return MAKE_SCRIPT_FLOAT(0);
+}
+
+scriptVar PSliderWnd::script_lock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid));
+ if (s) s->lock ();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar PSliderWnd::script_unlock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PSliderWnd *s = static_cast<PSliderWnd *>(o->vcpu_getInterface(sliderGuid));
+ if (s) s->unlock();
+ RETURN_SCRIPT_VOID;
+}
+
+GuiObject *SliderXuiSvc::instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+ if (!params)
+ {
+ PSliderWnd *r = new PSliderWnd;
+ return r->getGuiObject();
+ }
+ const wchar_t *action = params->getItemValue(L"action");
+ const wchar_t *param = params->getItemValue(L"param");
+ if (!action)
+ action=L"";
+ PSliderWnd *r = NULL;
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+ if (!_wcsicmp(action, L"seek"))
+ r = new SSeeker;
+ else if (!_wcsicmp(action, L"volume"))
+ r = new SVolBar;
+ else if (!_wcsicmp(action, L"pan"))
+ r = new SPanBar;
+ else if (!_wcsicmp(action, L"eq_band"))
+ {
+ if (!_wcsicmp(param, L"preamp"))
+ r = new SEQPreamp;
+ else
+ r = new SEQBand;
+ }
+ else if (!_wcsicmp(action, L"eq_preamp"))
+ {
+ r = new SEQPreamp;
+ }
+ else
+ {
+#endif
+
+ r = new PSliderWnd;
+
+#ifdef WASABI_WIDGETS_MEDIASLIDERS
+
+ }
+#endif
+
+ return r->getGuiObject();
+#else
+ PSliderWnd *r = new PSliderWnd;
+ return r->getGuiObject();
+#endif
+}
+
+void SliderXuiSvc::destroy(GuiObject *g)
+{
+ PSliderWnd *obj = static_cast<PSliderWnd *>(g->guiobject_getRootWnd());
+ delete obj;
+}
diff --git a/Src/Wasabi/api/skin/widgets/pslider.h b/Src/Wasabi/api/skin/widgets/pslider.h
new file mode 100644
index 00000000..6ef52870
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/pslider.h
@@ -0,0 +1,110 @@
+#ifndef _PSLIDER_H
+#define _PSLIDER_H
+
+#include <api/wnd/wndclass/slider.h>
+#include <api/script/objects/guiobj.h>
+#include <api/skin/widgets.h>
+
+#define PSLIDER_PARENT SliderWnd
+
+class SliderScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern SliderScriptController *sliderController;
+
+
+
+class PSliderWnd : public PSLIDER_PARENT {
+
+public:
+
+ PSliderWnd();
+ virtual ~PSliderWnd();
+
+ virtual int onSetPosition();
+ virtual int onSetFinalPosition();
+ virtual int onPostedPosition(int p);
+ virtual void lock();
+ virtual void unlock();
+
+ virtual int setXuiParam(int _xuihandle, int attribid, const wchar_t *paramname, const wchar_t *strvalue);
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return sliderController; }
+
+/* virtual int getAutoHeight();
+ virtual int getAutoWidth();*/
+
+ virtual int onInit();
+
+#ifdef WASABI_COMPILE_CONFIG
+ virtual int onReloadConfig();
+ void reloadConfig();
+#endif
+
+ virtual int scriptDivisor() { return 1; }
+
+ enum {
+ PSLIDER_SETBARLEFT=0,
+ PSLIDER_SETBARMIDDLE,
+ PSLIDER_SETBARRIGHT,
+ PSLIDER_SETTHUMB,
+ PSLIDER_SETDOWNTHUMB,
+ PSLIDER_SETHOVERTHUMB,
+ PSLIDER_SETORIENTATION,
+ PSLIDER_SETLOW,
+ PSLIDER_SETHIGH,
+ PSLIDER_SETHOTPOS,
+ PSLIDER_SETHOTRANGE,
+ PSLIDER_SETSTRETCHTHUMB,
+ PSLIDER_NUMPARAMS,
+ };
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+
+public:
+ static scriptVar script_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_onSetPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p);
+ static scriptVar script_onPostedPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p);
+ static scriptVar script_onSetFinalPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p);
+ static scriptVar script_lock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_unlock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+
+private:
+ int xuihandle;
+ static XMLParamPair params[];
+};
+
+class SliderXuiSvc : public svc_xuiObjectI {
+
+public:
+ SliderXuiSvc() {};
+ virtual ~SliderXuiSvc() {};
+
+ static const char *getServiceName() { return "Slider xui object"; }
+ static const wchar_t *xuisvc_getXmlTag() { return L"Slider"; }
+ virtual int testTag(const wchar_t *xmltag) { return !WCSICMP(xmltag, L"Slider"); }
+ virtual GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params=NULL);
+ virtual void destroy(GuiObject *g);
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/sa.cpp b/Src/Wasabi/api/skin/widgets/sa.cpp
new file mode 100644
index 00000000..ff2c72fc
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/sa.cpp
@@ -0,0 +1,735 @@
+#include <precomp.h>
+#include <api/wnd/popup.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <math.h>
+#include <api/skin/skinparse.h>
+#include "sa.h"
+#include <api/core/api_core.h>
+#include <tataki/canvas/bltcanvas.h>
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+const wchar_t visXuiStr[] = L"Vis"; // This is the xml tag
+char visXuiSvcName[] = "Vis xui object"; // this is the name of the xuiservice
+
+
+// {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+
+unsigned char ppal[] = {
+#ifdef CLASSIC
+ 0,0,0, // color 0 = black
+ 75,72,80, // color 1 = grey for dots
+ 255,55,16, // color 2 = top of spec
+ 255,55,16, // 3
+ 255,80,0, // 4
+ 255,80,0, // 5
+ 239,112,0, // 6
+ 239,112,0, // 7
+ 255,168,32, // 8
+ 255,168,32, // 9
+ 176,255,47, // 10
+ 176,255,47, // 11
+ 47,239,0, // 12
+ 47,239,0, // 13
+ 48,160,0, // 14
+ 48,160,0, // 15
+ 32,128,0, // 16
+ 32,128,0, // 17 = bottom of spec
+ 255,255,255, // 18 = osc 1
+ 214,214,222, // 19 = osc 2 (slightly dimmer)
+ 181,189,189, // 20 = osc 3
+ 160,170,175, // 21 = osc 4
+ 148,156,165, // 22 = osc 4
+ 150, 150, 150, // 23 = analyzer peak dots
+#else
+ 0,0,0, // color 0 = black
+ 24,33,41, // color 1 = grey for dots
+ 239,49,16, // color 2 = top of spec
+ 206,41,16, // 3
+ 214,90,0, // 4
+ 214,102,0, // 5
+ 214,115,0, // 6
+ 198,123,8, // 7
+ 222,165,24, // 8
+ 214,181,33, // 9
+ 189,222,41, // 10
+ 148,222,33, // 11
+ 41,206,16, // 12
+ 50,190,16, // 13
+ 57,181,16, // 14
+ 49,156,8, // 15
+ 41,148,0, // 16
+ 24,132,8, // 17
+ 255,255,255, // 18 = osc 1
+ 214,214,222, // 19 = osc 2 (slightly dimmer)
+ 181,189,189, // 20 = osc 3
+ 160,170,175, // 21 = osc 4
+ 148,156,165, // 22 = osc 4
+ 150, 150, 150, // 23 = analyzer peak
+#endif
+};
+
+#define CHANNEL_LEFT 1
+#define CHANNEL_RIGHT 2
+
+XMLParamPair SAWnd::params[] = {
+ {SA_SETCOLORALLBANDS, L"COLORALLBANDS"},
+ {SA_SETCOLORBAND1, L"COLORBAND1"},
+ {SA_SETCOLORBAND2, L"COLORBAND2"},
+ {SA_SETCOLORBAND3, L"COLORBAND3"},
+ {SA_SETCOLORBAND4, L"COLORBAND4"},
+ {SA_SETCOLORBAND5, L"COLORBAND5"},
+ {SA_SETCOLORBAND6, L"COLORBAND6"},
+ {SA_SETCOLORBAND7, L"COLORBAND7"},
+ {SA_SETCOLORBAND8, L"COLORBAND8"},
+ {SA_SETCOLORBAND9, L"COLORBAND9"},
+ {SA_SETCOLORBAND10, L"COLORBAND10"},
+ {SA_SETCOLORBAND11, L"COLORBAND11"},
+ {SA_SETCOLORBAND12, L"COLORBAND12"},
+ {SA_SETCOLORBAND13, L"COLORBAND13"},
+ {SA_SETCOLORBAND14, L"COLORBAND14"},
+ {SA_SETCOLORBAND15, L"COLORBAND15"},
+ {SA_SETCOLORBAND16, L"COLORBAND16"},
+ {SA_SETCOLORBANDPEAK, L"COLORBANDPEAK"},
+ {SA_SETCOLORALLOSC, L"COLORALLOSC"},
+ {SA_SETCOLOROSC1, L"COLOROSC1"},
+ {SA_SETCOLOROSC2, L"COLOROSC2"},
+ {SA_SETCOLOROSC3, L"COLOROSC3"},
+ {SA_SETCOLOROSC4, L"COLOROSC4"},
+ {SA_SETCOLOROSC5, L"COLOROSC5"},
+ {SA_SETCHANNEL, L"CHANNEL"},
+ {SA_SETFLIPH, L"FLIPH"},
+ {SA_SETFLIPV, L"FLIPV"},
+ {SA_SETMODE, L"MODE"},
+ {SA_SETGAMMA, L"GAMMAGROUP"},
+ {SA_SETFALLOFF, L"FALLOFF"},
+ {SA_SETPEAKFALLOFF, L"PEAKFALLOFF"},
+ {SA_SETBANDWIDTH, L"BANDWIDTH"},
+ {SA_FPS, L"FPS"},
+ {SA_COLORING, L"COLORING"},
+ {SA_PEAKS, L"PEAKS"},
+ {SA_OSCDRAWSTYLE, L"OSCSTYLE"},
+};
+
+SAWnd::SAWnd()
+{
+ filtergroup = SA_PARENT::getFiltersGroup();
+
+ getScriptObject()->vcpu_setInterface(visGuid, (void *)static_cast<SAWnd *>(this));
+ getScriptObject()->vcpu_setClassName(L"Vis");
+ getScriptObject()->vcpu_setController(visController);
+
+ char *p = (char *)&ppal;
+ for (int i=0;i<72;i++) {
+ palette[i] = ((*p)<<16) + ((*(p+1))<<8) + *(p+2);
+ p += 3;
+ }
+
+ setRealtime(1);
+ startQuickPaint();
+
+ config_sa=-1; // default value
+#ifdef WASABI_COMPILE_CONFIG
+ {
+ CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if(ci) {
+ config_sa=ci->getDataAsInt(L"Spectrum analyzer mode");
+ viewer_addViewItem(ci->getDependencyPtr());
+ }
+ }
+ saveconfsa=0;
+#endif
+
+ flip_v = 0;
+ flip_h = 0;
+ channel = CHANNEL_LEFT | CHANNEL_RIGHT;
+ off = 0;
+
+ config_safalloff=2;
+ config_sa_peak_falloff=1;
+ config_safire=4;
+ config_sa_peaks=1;
+
+ memset(bx, 0, sizeof(bx));
+ memset(t_bx, 0, sizeof(t_bx));
+ memset(t_vx, 0, sizeof(t_vx));
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void SAWnd::CreateXMLParameters(int master_handle)
+{
+ //SA_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+int SAWnd::onInit() {
+ SA_PARENT::onInit();
+#ifdef WASABI_COMPILE_CONFIG
+ if(config_sa==-1) {
+ Layout *pl=getGuiObject()->guiobject_getParentLayout();
+ if (pl->getParentContainer()) {
+ confsaname.printf(L"%s/%s/%s/config_sa",WASABI_API_SKIN->getSkinName(),pl->getParentContainer()->getName(),pl->getName());
+ config_sa=WASABI_API_CONFIG->getIntPrivate(confsaname,1);
+ saveconfsa=1;
+ }
+ }
+#endif
+ return 1;
+}
+
+SAWnd::~SAWnd()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if(saveconfsa)
+ WASABI_API_CONFIG->setIntPrivate(confsaname,config_sa);
+#endif
+}
+
+int SAWnd::setXuiParam(int _xuihandle, int attrid, const wchar_t *pname, const wchar_t *str) {
+ if (_xuihandle != xuihandle) return SA_PARENT::setXuiParam(_xuihandle, attrid, pname, str);
+ switch (attrid) {
+ case SA_SETCOLORALLBANDS:
+ setBandColor(-1, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND1:
+ setBandColor(15, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND2:
+ setBandColor(14, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND3:
+ setBandColor(13, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND4:
+ setBandColor(12, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND5:
+ setBandColor(11, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND6:
+ setBandColor(10, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND7:
+ setBandColor(9, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND8:
+ setBandColor(8, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND9:
+ setBandColor(7, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND10:
+ setBandColor(6, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND11:
+ setBandColor(5, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND12:
+ setBandColor(4, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND13:
+ setBandColor(3, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND14:
+ setBandColor(2, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND15:
+ setBandColor(1, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBAND16:
+ setBandColor(0, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORBANDPEAK:
+ setPeakColor(SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLORALLOSC:
+ setOscColor(-1, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLOROSC1:
+ setOscColor(0, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLOROSC2:
+ setOscColor(1, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLOROSC3:
+ setOscColor(2, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLOROSC4:
+ setOscColor(3, SkinParser::parseColor(str));
+ break;
+ case SA_SETCOLOROSC5:
+ setOscColor(4, SkinParser::parseColor(str));
+ break;
+ case SA_SETCHANNEL:
+ setChannel(WTOI(str));
+ break;
+ case SA_SETFLIPH:
+ setFlipH(WTOI(str));
+ break;
+ case SA_SETFLIPV:
+ setFlipV(WTOI(str));
+ break;
+ case SA_SETMODE:
+ setMode(WTOI(str));
+ break;
+ case SA_SETGAMMA:
+ filtergroup = str;
+ break;
+ case SA_SETFALLOFF:
+ config_safalloff = WTOI(str);
+ break;
+ case SA_SETPEAKFALLOFF:
+ config_sa_peak_falloff=WTOI(str);
+ break;
+ case SA_SETBANDWIDTH:
+ if (WCSCASEEQLSAFE(str, L"wide"))
+ config_safire &= (~32);
+ else if (WCSCASEEQLSAFE(str, L"thin"))
+ config_safire |= 32;
+ break;
+ case SA_FPS:
+ {
+ int fps = WTOI(str);
+ if (fps)
+ setSpeed(1000/fps);
+ }
+ break;
+ case SA_COLORING:
+ if (WCSCASEEQLSAFE(str, L"fire"))
+ config_safire = (config_safire&~3) | 1;
+ else if (WCSCASEEQLSAFE(str, L"normal"))
+ config_safire = (config_safire&~3) | 0;
+ else if (WCSCASEEQLSAFE(str, L"line"))
+ config_safire = (config_safire&~3) | 2;
+ break;
+ case SA_PEAKS:
+ if (str && WTOI(str))
+ config_sa_peaks=1;
+ else
+ config_sa_peaks=0;
+ break;
+ case SA_OSCDRAWSTYLE:
+ if (WCSCASEEQLSAFE(str, L"dots"))
+ config_safire = (config_safire & ~(3<<2)) | 0;
+ else if (WCSCASEEQLSAFE(str, L"solid"))
+ config_safire = (config_safire & ~(3<<2)) | 4;
+ else if (WCSCASEEQLSAFE(str, L"lines"))
+ config_safire = (config_safire & ~(3<<2)) | 8;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void SAWnd::setChannel(int c) {
+ channel = c;
+}
+
+void SAWnd::setFlipH(int v) {
+ if (v == flip_h) return;
+ flip_h = v;
+ invalidate();
+}
+
+void SAWnd::setFlipV(int v) {
+ if (v == flip_v) return;
+ flip_v = v;
+ invalidate();
+}
+
+void SAWnd::setBandColor(int band, ARGB32 col) {
+ if (band == -1) {
+ for (int i=0;i<16;i++)
+ palette[i+2] = RGBTOBGR(col);
+ } else
+ palette[band+2] = RGBTOBGR(col);
+}
+
+void SAWnd::setOscColor(int n, ARGB32 col) {
+ if (n == -1) {
+ for (int i=0;i<4;i++)
+ palette[i+18] = RGBTOBGR(col);
+ } else
+ palette[n+18] = RGBTOBGR(col);
+}
+
+void SAWnd::setPeakColor(ARGB32 col) {
+ palette[23] = RGBTOBGR(col);
+}
+
+#define SA_BLEND(c) (palette[c] | 0xFF000000) //(alpha << 24))
+
+int SAWnd::onQuickPaint(BltCanvas *bc, int w, int h, int newone) {
+ if(!isVisible()) return 0;
+
+#ifdef WASABI_COMPILE_MEDIACORE
+ int x;
+ int fo[5] = {3, 6, 12, 16, 32 };
+ float pfo[5]={1.05f,1.1f,1.2f,1.4f,1.6f};
+
+ specData=(int *)bc->getBits();
+ if (newone || !config_sa)
+ MEMSET(specData,0,76*16*4*4);
+
+ if(!config_sa) {
+ if (!off) {
+ off = 1;
+ return 1;
+ }
+ return 0;
+ }
+
+ off = 0;
+
+ char visdata[576*2*2] = {0};
+ unsigned char *values=(unsigned char *)visdata;
+ int ret=WASABI_API_MEDIACORE->core_getVisData(0,visdata,sizeof(visdata));
+ if (!ret) {
+ MEMSET(visdata,0,sizeof(visdata));
+ } else if (ret == 75*2) {
+ if (config_sa==2) values+=75;
+ } else {
+ if(config_sa==1) {
+ register int v;
+ for(int x=0;x<75;x++) {
+ v=values[x]+values[576+x];
+ v>>=4;
+ values[x]=v;
+ }
+ }
+ if (config_sa==2) {
+ values+=576*2;
+ register int v;
+ register char *blah=(char *)values;
+ for(int x=0;x<75;x++) {
+ v=blah[x*4]+blah[576+(x*4)];
+ v>>=4;
+ blah[x]=v;
+ }
+ }
+ }
+
+// int ws=(config_windowshade&&config_mw_open);
+// int s = (config_dsize&&config_mw_open)?1:0;
+
+ int dbx = fo[max(min(config_safalloff,4),0)];
+ float spfo=pfo[max(min(config_sa_peak_falloff,4),0)];
+
+ MEMSET(specData,0,76*16*4*4);
+
+ {
+ {
+ if (config_sa == 2)
+ {
+ int *gmem = specData;
+ {
+ int lv=-1;
+ if (((config_safire>>2)&3)==0) for (x = 0; x < 75; x ++)
+ {
+ register int v; register char c;
+ v = (((int) ((signed char *)values)[x])) + 8;
+ if (v < 0) v = 0 ; if (v > 15) v = 15; c = v/2-4; if (c < 0) c = -c; c += 18;
+ gmem[v*76*2] = SA_BLEND(c);
+ gmem++;
+ }
+ else if (((config_safire>>2)&3)==1) for (x = 0; x < 75; x ++)
+ {
+ register int v,t; register char c;
+ v = (((int) ((signed char *)values)[x])) + 8;
+ if (v < 0) v = 0 ; if (v > 15) v = 15; c = v/2-4; if (c < 0) c = -c; c += 18;
+ if (lv == -1) lv=v;
+ t=lv;
+ lv=v;
+ if (v >= t) while (v >= t) gmem[v--*76*2] = SA_BLEND(c);
+ else while (v < t) gmem[v++*76*2] = SA_BLEND(c);
+ gmem++;
+ }
+ else if (((config_safire>>2)&3)==2) for (x = 0; x < 75; x ++) // solid
+ {
+ register int v; register char c;
+ v = (((int) ((signed char *)values)[x])) + 8;
+ if (v < 0) v = 0 ; if (v > 15) v = 15; c = v/2-4; if (c < 0) c = -c; c += 18;
+ if (v > 7) while (v > 7) gmem[v--*76*2] = SA_BLEND(c);
+ else while (v <= 7) gmem[v++*76*2] = SA_BLEND(c);
+ gmem++;
+ }
+ }
+ }
+ else
+ {
+ for (x = 0; x < 75; x ++)
+ {
+ register int y,v,t;
+#ifndef CLASSIC
+ t=x&~3;
+#else
+ t=x-(x%6);
+#endif
+ if (!(config_safire&32))
+ {
+ int a=values[t],b=values[t+1],c=values[t+2],d=values[t+3];
+#ifndef CLASSIC
+ v = a+b+c+d;//-min(a,min(b,min(c,d)));
+ v/=4;
+#else
+ v = a+b+c+d+(int)values[t+4]+(int)values[t+5];//-min(a,min(b,min(c,d)));
+ v/=6;
+#endif
+ }
+ else v = (((int)values[x]));
+ if (v > 15) v = 15;
+ if ((v<<4) < bx[x]) v = (bx[x]-=dbx)>>4;
+ else bx[x] = v<<4;
+ if (bx[x] < 0) bx[x] = 0;
+ if (v < 0) v = 0;
+ int *gmem = specData + 76*2*15 + x;
+ if ((config_safire&3)==1) t = v+2;
+ else if ((config_safire&3)==2) t=17-(v);
+ else t = 17;
+
+ if (t_bx[x] <= v*256) {
+ t_bx[x]=v*256;
+ t_vx[x]=3.0f;
+ }
+#ifndef CLASSIC
+ if ((config_safire&32 || (x&3)!=3))
+ {
+ if ((config_safire&3)!=2) for (y = 0; y < v; y ++)
+ {
+ *gmem = SA_BLEND(t-y);
+ gmem -= 76*2;
+ }
+ else for (y = 0; y < v; y ++)
+ {
+ *gmem = SA_BLEND(t);
+ gmem -= 76*2;
+ }
+#else
+ if ((config_safire&32 || (!(x&1) && (x%6) < 4)))
+ {
+ if ((config_safire&3)!=2) for (y = 0; y < v/2; y ++)
+ {
+ *gmem = SA_BLEND(t-y*2);
+ gmem -= 76*2*2;
+ }
+ else for (y = 0; y < v/2; y ++)
+ {
+ *gmem = SA_BLEND(t);
+ gmem -= 76*2*2;
+ }
+#endif
+#ifndef CLASSIC
+ if (config_sa_peaks && t_bx[x]/256 >= 0 && t_bx[x]/256 <= 15)
+ {
+ specData[76*2*15 - (t_bx[x]/256)*76*2 + x]=SA_BLEND(23);
+ }
+#endif
+ }
+ t_bx[x] -= (int)t_vx[x];
+ t_vx[x] *= spfo;
+ if (t_bx[x] < 0) t_bx[x]=0;
+ }
+ }
+ }
+ }
+
+ if (flip_v)
+ bc->vflip(2);
+ if (flip_h)
+ bc->hflip(2);
+
+ invalidated = 1; // rerun filter
+
+#endif //mediacore
+
+ return 1;
+}
+
+int SAWnd::onLeftButtonDown(int x, int y) {
+ SA_PARENT::onLeftButtonDown(x, y);
+ if (!WASABI_API_MAKI->vcpu_getComplete()) {
+ nextMode();
+#ifdef WASABI_COMPILE_CONFIG
+ CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if(ci) ci->setDataAsInt(L"Spectrum analyzer mode",config_sa);
+#endif
+ }
+ return 1;
+}
+
+void SAWnd::nextMode() {
+ config_sa++;
+ if(config_sa>2) config_sa=0;
+}
+
+void SAWnd::setMode(int mode) {
+ config_sa=mode;
+ if(config_sa>2) config_sa=0;
+}
+
+int SAWnd::getMode() {
+ return config_sa;
+}
+
+int SAWnd::onRightButtonUp(int x, int y)
+{
+ SA_PARENT::onRightButtonUp(x, y);
+
+ PopupMenu menu (this);
+ menu.addCommand(WASABI_API_LNGSTRINGW(IDS_NO_VISUALISATION)/*"No visualization"*/, 0, config_sa==0, FALSE);
+ menu.addCommand(WASABI_API_LNGSTRINGW(IDS_SPECTRUM_ANALYZER)/*L"Spectrum analyzer"*/, 1, config_sa==1, FALSE);
+ menu.addCommand(WASABI_API_LNGSTRINGW(IDS_OSCILLOSCOPE)/*L"Oscilloscope"*/, 2, config_sa==2, FALSE);
+
+ clientToScreen(&x, &y);
+
+ int ret = menu.popAtXY(x,y);
+#ifdef WASABI_COMPILE_CONFIG
+ if(ret>=0)
+ {
+ config_sa=ret;
+ CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if(ci) ci->setDataAsInt(L"Spectrum analyzer mode",config_sa);
+ }
+#endif
+
+ WASABI_API_MAKI->vcpu_setComplete();
+ return 1;
+}
+
+int SAWnd::getPreferences(int what) {
+ switch (what) {
+ case SUGGESTED_W: return 76;
+ case SUGGESTED_H: return 16;
+ }
+ return SA_PARENT::getPreferences(what);
+}
+
+void SAWnd::getQuickPaintSize(int *w, int *h) {
+ if (w) *w = 76*2;
+ if (h) *h = 16*2;
+}
+
+void SAWnd::getQuickPaintSource(RECT *r) {
+ ASSERT(r != NULL);
+ r->left = 0;
+ r->top = 0;
+ r->right = 72;
+ r->bottom = 16;
+}
+
+int SAWnd::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen) {
+#ifdef WASABI_COMPILE_CONFIG
+ if(event==CfgItem::Event_ATTRIBUTE_CHANGED && ptr && STRCASEEQLSAFE((const char *)ptr, "Spectrum analyzer mode")) {
+ CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if(ci) config_sa=ci->getDataAsInt((const wchar_t *)ptr);
+ }
+#endif
+ return 1;
+}
+
+VisScriptController _visController;
+VisScriptController *visController = &_visController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct VisScriptController::exportedFunction[] = {
+ {L"onFrame", 0, (void*)SAWnd::script_onFrame },
+ {L"setRealtime", 1, (void*)SAWnd::script_setRealtime },
+ {L"getRealtime", 0, (void*)SAWnd::script_getRealtime },
+ {L"setMode", 1, (void*)SAWnd::script_vcpu_setMode},
+ {L"getMode", 0, (void*)SAWnd::script_vcpu_getMode},
+ {L"nextMode", 0, (void*)SAWnd::script_vcpu_nextMode},
+};
+
+// --------------------------------------------------------
+const wchar_t *VisScriptController::getClassName() {
+ return L"Vis";
+}
+
+const wchar_t *VisScriptController::getAncestorClassName() {
+ return L"GuiObject";
+}
+
+ScriptObject *VisScriptController::instantiate() {
+ SAWnd *sa = new SAWnd;
+ ASSERT(sa != NULL);
+ return sa->getScriptObject();
+}
+
+void VisScriptController::destroy(ScriptObject *o) {
+ SAWnd *sa = static_cast<SAWnd *>(o->vcpu_getInterface(visGuid));
+ ASSERT(sa != NULL);
+ delete sa;
+}
+
+void *VisScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for vis yet
+}
+
+void VisScriptController::deencapsulate(void *o) {
+}
+
+int VisScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *VisScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID VisScriptController::getClassGuid() {
+ return visGuid;
+}
+
+// -----------------------------------------------------------------------
+scriptVar SAWnd::script_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, visController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar SAWnd::script_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s) {
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&s));
+ SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid));
+ if (sa) sa->setRealtime(SOM::makeInt(&s));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SAWnd::script_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid));
+ if (sa) return MAKE_SCRIPT_INT(sa->getRealtime());
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar SAWnd::script_vcpu_setMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&a));
+ SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid));
+ if (sa) sa->setMode(SOM::makeInt(&a));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar SAWnd::script_vcpu_getMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid));
+ if (sa) return MAKE_SCRIPT_INT(sa->getMode());
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar SAWnd::script_vcpu_nextMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ SAWnd *sa = static_cast<SAWnd*>(o->vcpu_getInterface(visGuid));
+ if (sa) sa->nextMode();
+ RETURN_SCRIPT_VOID;
+}
diff --git a/Src/Wasabi/api/skin/widgets/sa.h b/Src/Wasabi/api/skin/widgets/sa.h
new file mode 100644
index 00000000..a421bb3b
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/sa.h
@@ -0,0 +1,157 @@
+#ifndef _SA_H
+#define _SA_H
+
+#include <api/wnd/wndclass/qpaintwnd.h>
+#include <api/service/svc_enum.h>
+#include <api/service/svcs/svc_skinfilter.h>
+
+#define SA_TIMER_UPDATE 1
+#define SA_PARENT QuickPaintWnd
+
+// {CE4F97BE-77B0-4e19-9956-D49833C96C27}
+static const GUID visGuid =
+{ 0xce4f97be, 0x77b0, 0x4e19, { 0x99, 0x56, 0xd4, 0x98, 0x33, 0xc9, 0x6c, 0x27 } };
+
+#include <api/script/objects/guiobj.h>
+
+class VisScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern VisScriptController *visController;
+
+class SAWnd : public SA_PARENT, public DependentViewerI {
+public:
+ SAWnd();
+ virtual ~SAWnd();
+
+ int onInit();
+ int onRightButtonUp(int x, int y);
+ int onLeftButtonDown(int x, int y);
+ virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *p, const wchar_t *s);
+ virtual int getPreferences(int what);
+
+ void setChannel(int c);
+ void setFlipH(int v);
+ void setFlipV(int v);
+ int wantAutoContextMenu() { return 0; }
+
+ virtual int onQuickPaint(BltCanvas *c, int w, int h, int newone);
+
+ virtual void setBandColor(int band, ARGB32 col);
+ virtual void setOscColor(int n, ARGB32 col);
+ virtual void setPeakColor(ARGB32 col);
+
+ virtual void setMode(int mode);
+ virtual int getMode();
+ virtual void nextMode();
+ virtual void getQuickPaintSize(int *w, int *h);
+ virtual void getQuickPaintSource(RECT *r);
+ virtual int wantNegativeHeight() { return 1; }
+ virtual int wantFilters() { return 1; }
+ virtual const wchar_t *getFiltersGroup() { return filtergroup; }
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ int *specData;
+ int palette[256];
+ int realtime;
+ int xuihandle;
+
+ enum {
+ SA_SETCOLORALLBANDS=0,
+ SA_SETCOLORBAND1,
+ SA_SETCOLORBAND2,
+ SA_SETCOLORBAND3,
+ SA_SETCOLORBAND4,
+ SA_SETCOLORBAND5,
+ SA_SETCOLORBAND6,
+ SA_SETCOLORBAND7,
+ SA_SETCOLORBAND8,
+ SA_SETCOLORBAND9,
+ SA_SETCOLORBAND10,
+ SA_SETCOLORBAND11,
+ SA_SETCOLORBAND12,
+ SA_SETCOLORBAND13,
+ SA_SETCOLORBAND14,
+ SA_SETCOLORBAND15,
+ SA_SETCOLORBAND16,
+ SA_SETCOLORBANDPEAK,
+ SA_SETCOLORALLOSC,
+ SA_SETCOLOROSC1,
+ SA_SETCOLOROSC2,
+ SA_SETCOLOROSC3,
+ SA_SETCOLOROSC4,
+ SA_SETCOLOROSC5,
+ SA_SETCHANNEL,
+ SA_SETFLIPH,
+ SA_SETFLIPV,
+ SA_SETMODE,
+ SA_SETGAMMA,
+ SA_SETFALLOFF,
+ SA_SETPEAKFALLOFF,
+ SA_SETBANDWIDTH,
+ SA_FPS,
+ SA_COLORING,
+ SA_PEAKS,
+ SA_OSCDRAWSTYLE,
+ };
+ static XMLParamPair params[];
+
+ int config_safalloff;
+ int config_sa_peak_falloff;
+ int config_sa;
+ int config_safire;
+ int config_sa_peaks;
+ int flip_h, flip_v;
+ int channel;
+ StringW filtergroup;
+
+ int bx[75];
+int t_bx[75];
+float t_vx[75];
+
+ PtrList<svc_skinFilter>filters;
+ SkinFilterEnum *sfe;
+
+#ifdef WASABI_COMPILE_CONFIG
+ int saveconfsa;
+ StringW confsaname;
+#endif
+ int off;
+
+ virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen);
+
+public:
+
+ static scriptVar script_onFrame(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar r);
+ static scriptVar script_getRealtime(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar script_vcpu_getMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_nextMode(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+};
+
+extern const wchar_t visXuiStr[];
+extern char visXuiSvcName[];
+class VisXuiSvc : public XuiObjectSvc<SAWnd, visXuiStr, visXuiSvcName> {};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/seeker.h b/Src/Wasabi/api/skin/widgets/seeker.h
new file mode 100644
index 00000000..6b95e9df
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seeker.h
@@ -0,0 +1,22 @@
+#ifndef _SEEKER_H
+#define _SEEKER_H
+
+#include "../common/slider.h"
+
+#define SEEKER_PARENT SliderWnd
+class Seeker : public SliderWnd {
+public:
+ Seeker();
+ virtual ~Seeker();
+
+ virtual int onInit();
+ virtual int onResize();
+
+protected:
+ virtual int onSetFinalPosition();
+
+ // from BaseWnd
+ virtual void timerCallback(int id);
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/seqband.cpp b/Src/Wasabi/api/skin/widgets/seqband.cpp
new file mode 100644
index 00000000..2d813fd2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seqband.cpp
@@ -0,0 +1,121 @@
+#include <precomp.h>
+#include "seqband.h"
+#include <api/core/api_core.h>
+
+#define NOTIFYMSG_EQ_HELLO 0x3003
+
+const wchar_t eqBandXuiStr[] = L"EqBand"; // This is the xml tag
+char eqBandXuiSvcName[] = "EqBand xui object"; // this is the name of the xuiservice
+
+XMLParamPair SEQBand::params[] = {
+ {SEQBAND_SETPARAM, L"BAND"},
+ {SEQBAND_SETPARAM, L"PARAM"},
+};
+
+SEQBand::SEQBand() {
+ band = 0;
+ setDrawOnBorders(TRUE);
+ setEnable(TRUE);
+ setHotPosition(0);
+ isactive=0;
+ discard_next_event = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ setLimits(-127,127);
+}
+
+void SEQBand::CreateXMLParameters(int master_handle)
+{
+ //SEQBAND_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+SEQBand::~SEQBand() {
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SEQBand::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) {
+ if (_xuihandle != xuihandle) return SEQBAND_PARENT::setXuiParam(_xuihandle, attrid, name, strval);
+ switch (attrid) {
+ case SEQBAND_SETPARAM:
+ case SEQBAND_SETBAND:
+ setBand(WTOI(strval)-1);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void SEQBand::setBand(int b) {
+ band = b;
+}
+
+int SEQBand::onInit() {
+ SEQBAND_PARENT::onInit();
+
+ corecb_onEQBandChange(band, WASABI_API_MEDIACORE->core_getEqBand(0, band));
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+
+ return 1;
+}
+
+int SEQBand::onSetPosition() {
+ setHotPosition((Std::keyDown(VK_SHIFT) ? -1 : 0));
+ SEQBAND_PARENT::onSetPosition();
+ int pos = getSliderPosition(); // get slider pos
+ discard_next_event = 1;
+ WASABI_API_MEDIACORE->core_setEqBand(0,band,pos);
+ return 1;
+}
+
+int SEQBand::onResize() {
+ SEQBAND_PARENT::onResize();
+ invalidate();
+ return 1;
+}
+
+int SEQBand::corecb_onEQBandChange(int b, int newval) {
+ if(b!=band) return 0;
+ if (discard_next_event) {
+ discard_next_event = 0;
+ return 0;
+ }
+ setPosition(newval,0);
+ return 0;
+}
+
+int SEQBand::onLeftButtonDown(int x, int y) {
+ isactive=1;
+ return SEQBAND_PARENT::onLeftButtonDown(x,y);
+}
+
+int SEQBand::onMouseMove(int x, int y) {
+ if(isactive) {
+ ifc_window *parent=getParent();
+ if(parent) {
+ ifc_window *wnd=parent->findRootWndChild(x,y);
+ if(wnd && wnd!=this) {
+ if(wnd->childNotify(this,NOTIFYMSG_EQ_HELLO,0,0)) { // will return 1 if it's another EQBand
+ onLeftButtonUp(x,y);
+ wnd->onLeftButtonDown(x,y);
+ }
+ }
+ }
+ }
+ return SEQBAND_PARENT::onMouseMove(x,y);
+}
+
+int SEQBand::onLeftButtonUp(int x, int y) {
+ isactive=0;
+ return SEQBAND_PARENT::onLeftButtonUp(x,y);
+}
+
+int SEQBand::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+ if(msg==NOTIFYMSG_EQ_HELLO) return 1;
+ return SEQBAND_PARENT::childNotify(child,msg,param1,param2);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/seqband.h b/Src/Wasabi/api/skin/widgets/seqband.h
new file mode 100644
index 00000000..26c211bb
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seqband.h
@@ -0,0 +1,47 @@
+#ifndef _SEQBAND_H
+#define _SEQBAND_H
+
+#include "pslider.h"
+#include <api/syscb/callbacks/corecbi.h>
+
+#define SEQBAND_PARENT PSliderWnd
+#define SEQBAND_XMLPARENT PSliderWnd
+
+class SEQBand : public SEQBAND_PARENT, public CoreCallbackI {
+public:
+ SEQBand(); // band=0-9
+ virtual ~SEQBand();
+
+ virtual int onInit();
+ virtual int onResize();
+ virtual int setXuiParam(int xuihandle, int attrid, const wchar_t *name, const wchar_t *strval);
+ virtual void setBand(int b);
+
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onMouseMove(int x, int y); // only called when mouse captured
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+
+ enum {
+ SEQBAND_SETPARAM=0,
+ SEQBAND_SETBAND,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ virtual int onSetPosition();
+
+ virtual int corecb_onEQBandChange(int band, int newval);
+
+ int band, isactive;
+ int discard_next_event;
+private:
+ static XMLParamPair params[];
+ int xuihandle;
+};
+
+extern const wchar_t eqBandXuiStr[];
+extern char eqBandXuiSvcName[];
+class EqBandXuiSvc : public XuiObjectSvc<SEQBand, eqBandXuiStr, eqBandXuiSvcName> {};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/seqpreamp.cpp b/Src/Wasabi/api/skin/widgets/seqpreamp.cpp
new file mode 100644
index 00000000..7b61d2cd
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seqpreamp.cpp
@@ -0,0 +1,44 @@
+#include <precomp.h>
+#include "seqpreamp.h"
+
+#include <api/core/api_core.h>
+
+const wchar_t eqPreAmpXuiStr[] = L"EQPreAmp"; // This is the xml tag
+char eqPreAmpXuiSvcName[] = "EQPreAmp xui object"; // this is the name of the xuiservice
+
+SEQPreamp::SEQPreamp() {
+ setDrawOnBorders(TRUE);
+ setEnable(TRUE);
+ setHotPosition(0);
+ setLimits(-127,127);
+ discard_next_event = 0;
+}
+
+SEQPreamp::~SEQPreamp() {
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SEQPreamp::onInit() {
+ SEQPREAMP_PARENT::onInit();
+
+ corecb_onEQPreampChange(WASABI_API_MEDIACORE->core_getEqPreamp(0));
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+
+ return 1;
+}
+
+int SEQPreamp::onSetPosition() {
+ setHotPosition((Std::keyDown(VK_SHIFT) ? -1 : 0));
+ SEQPREAMP_PARENT::onSetPosition();
+ int pos = getSliderPosition(); // get slider pos
+ discard_next_event = 1;
+ WASABI_API_MEDIACORE->core_setEqPreamp(0,pos);
+ discard_next_event = 0;
+ return 1;
+}
+
+int SEQPreamp::corecb_onEQPreampChange(int newval) {
+ if (discard_next_event) return 0;
+ setPosition(newval,0);
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/seqpreamp.h b/Src/Wasabi/api/skin/widgets/seqpreamp.h
new file mode 100644
index 00000000..7d7c779f
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seqpreamp.h
@@ -0,0 +1,28 @@
+#ifndef _SEQPREAMP_H
+#define _SEQPREAMP_H
+
+#include "pslider.h"
+#include <api/syscb/callbacks/corecbi.h>
+
+#define SEQPREAMP_PARENT PSliderWnd
+#define SEQPREAMP_XMLPARENT PSliderWnd
+
+class SEQPreamp : public SEQPREAMP_PARENT, public CoreCallbackI {
+public:
+ SEQPreamp();
+ virtual ~SEQPreamp();
+
+ virtual int onInit();
+
+protected:
+ virtual int onSetPosition();
+
+ virtual int corecb_onEQPreampChange(int newval);
+ int discard_next_event;
+};
+
+extern const wchar_t eqPreAmpXuiStr[];
+extern char eqPreAmpXuiSvcName[];
+class EqPreAmpXuiSvc : public XuiObjectSvc<SEQPreamp, eqPreAmpXuiStr, eqPreAmpXuiSvcName> {};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/seqvis.cpp b/Src/Wasabi/api/skin/widgets/seqvis.cpp
new file mode 100644
index 00000000..9850954d
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seqvis.cpp
@@ -0,0 +1,367 @@
+#include <precomp.h>
+
+#include <api/wnd/popup.h>
+#include <math.h>
+#include <api/skin/skinparse.h>
+#include <api/service/svc_enum.h>
+#include <api/service/svcs/svc_skinfilter.h>
+#include <api/skin/widgets/seqvis.h>
+#include <api/core/api_core.h>
+#include <tataki/canvas/bltcanvas.h>
+const wchar_t eqVisXuiStr[] = L"EQVis"; // This is the xml tag
+char eqVisXuiSvcName[] = "EQVis xui object"; // this is the name of the xuiservice
+XMLParamPair SEQVis::params[] =
+ {
+ {
+ SEQVIS_SETCOLORBOTTOM, L"COLORBOTTOM"
+ },
+ {SEQVIS_SETCOLORMIDDLE, L"COLORMIDDLE"},
+ {SEQVIS_SETCOLORPREAMP, L"COLORPREAMP"},
+ {SEQVIS_SETCOLORTOP, L"COLORTOP"},
+ {SEQVIS_SETALPHA, L"GAMMA"}, // BACKWARD COMPAT
+ };
+SEQVis::SEQVis()
+{
+ getScriptObject()->vcpu_setInterface(eqvisGuid, (void *)static_cast<SEQVis *>(this));
+ getScriptObject()->vcpu_setClassName(L"EqVis");
+ getScriptObject()->vcpu_setController(eqvisController);
+ colortop = colormid = colorbottom = 0xffffff;
+ colorpreamp = 0x888888;
+ shadedColors = NULL;
+ bc = NULL;
+ sfe = new SkinFilterEnum();
+
+ while (1)
+ {
+ svc_skinFilter *obj = sfe->getNext();
+ if (!obj) break;
+ filters.addItem(obj);
+ }
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+}
+
+void SEQVis::CreateXMLParameters(int master_handle)
+{
+ //SEQVIS_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+int SEQVis::onInit()
+{
+ SEQVIS_PARENT::onInit();
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ return 1;
+}
+
+SEQVis::~SEQVis()
+{
+ foreach(filters)
+ sfe->release(filters.getfor());
+ endfor;
+ delete sfe;
+ if (shadedColors) FREE(shadedColors);
+ delete(bc);
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SEQVis::setXuiParam(int _xuihandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (_xuihandle != xuihandle) return SEQVIS_PARENT::setXuiParam(_xuihandle, attrid, paramname, strvalue);
+ switch (attrid)
+ {
+ case SEQVIS_SETALPHA:
+ getGuiObject()->guiobject_setAlpha(WTOI(strvalue));
+ break;
+ case SEQVIS_SETCOLORTOP:
+ colortop = RGBTOBGR(SkinParser::parseColor(strvalue));
+ break;
+ case SEQVIS_SETCOLORMIDDLE:
+ colormid = RGBTOBGR(SkinParser::parseColor(strvalue));
+ break;
+ case SEQVIS_SETCOLORBOTTOM:
+ colorbottom = RGBTOBGR(SkinParser::parseColor(strvalue));
+ break;
+ case SEQVIS_SETCOLORPREAMP:
+ colorpreamp = RGBTOBGR(SkinParser::parseColor(strvalue));
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void SEQVis::splineGetPoint(spline_struct *s, float frame, float *out)
+{
+ int i, i_1, i0, i1, i2;
+ float time1, time2, time3;
+ float t1, t2, t3, t4, u1, u2, u3, u4, v1, v2, v3;
+ float a, b, c, d;
+
+ float *keys = s->keys;
+
+ a = (1 - s->tens) * (1 + s->cont) * (1 + s->bias);
+ b = (1 - s->tens) * (1 - s->cont) * (1 - s->bias);
+ c = (1 - s->tens) * (1 - s->cont) * (1 + s->bias);
+ d = (1 - s->tens) * (1 + s->cont) * (1 - s->bias);
+ v1 = t1 = -a / 2.0f; u1 = a;
+ u2 = (-6 - 2 * a + 2 * b + c) / 2.0f; v2 = (a - b) / 2.0f; t2 = (4 + a - b - c) / 2.0f;
+ t3 = (-4 + b + c - d) / 2.0f;
+ u3 = (6 - 2 * b - c + d) / 2.0f;
+ v3 = b / 2.0f;
+ t4 = d / 2.0f; u4 = -t4;
+
+ i0 = (int) frame;
+ i_1 = i0 - 1;
+ while (i_1 < 0) i_1 += s->numKeys;
+ i1 = i0 + 1;
+ while (i1 >= s->numKeys) i1 -= s->numKeys;
+ i2 = i0 + 2;
+ while (i2 >= s->numKeys) i2 -= s->numKeys;
+ time1 = frame - (float)((int) frame);
+ time2 = time1 * time1;
+ time3 = time2 * time1;
+ i0 *= s->keyWidth;
+ i1 *= s->keyWidth;
+ i2 *= s->keyWidth;
+ i_1 *= s->keyWidth;
+ for (i = 0; i < s->keyWidth; i ++)
+ {
+ a = t1 * keys[i + i_1] + t2 * keys[i + i0] + t3 * keys[i + i1] + t4 * keys[i + i2];
+ b = u1 * keys[i + i_1] + u2 * keys[i + i0] + u3 * keys[i + i1] + u4 * keys[i + i2];
+ c = v1 * keys[i + i_1] + v2 * keys[i + i0] + v3 * keys[i + i1];
+ *out++ = a * time3 + b * time2 + c * time1 + keys[i + i0];
+ }
+}
+
+void SEQVis::DrawEQVis()
+{
+
+ if (!shadedColors) return ;
+
+ float keys[12] = {0};
+ spline_struct spline = {keys, 1, 12, 0.0f, 0.0f, 0.1f};
+
+ MEMSET(specData, 0, cur_w*cur_h*4);
+
+ int ph = (int)((127 + WASABI_API_MEDIACORE->core_getEqPreamp(0)) * ((float)cur_h) / 256.0f);
+ ph *= cur_w;
+ for (int j = 0;j < cur_w;j++)
+ specData[j + ph] = colorpreamp | 0xFF000000; // alpha :)
+
+ {
+ int x;
+ int last_p = -1;
+ for (x = 0; x < 10; x ++)
+ keys[x + 1] = (127 - WASABI_API_MEDIACORE->core_getEqBand(0, x)) * ((float)cur_h) / 256.0f;
+ keys[0] = keys[1];
+ keys[11] = keys[10];
+
+ for (x = 0; x < cur_w; x ++)
+ {
+ float p;
+ int this_p;
+ splineGetPoint(&spline, 1.0f + x / (cur_w*11.0f / 100.0f), &p);
+ this_p = (int)p;
+ if (this_p < 0) this_p = 0;
+ if (this_p >= cur_h) this_p = cur_h - 1;
+ if (last_p == -1 || this_p == last_p)
+ specData[x + this_p*cur_w] = shadedColors[this_p];
+ else
+ {
+ if (this_p < last_p)
+ for (int j = 0;j < last_p - this_p + 1;j++)
+ specData[x + (this_p + j)*cur_w] = shadedColors[this_p + j];
+ else if (this_p > last_p)
+ for (int j = 0;j < this_p - last_p + 1;j++)
+ specData[x + (last_p + j)*cur_w] = shadedColors[last_p + j];
+ }
+ last_p = this_p;
+ }
+ }
+ invalidate();
+ invalidated = 1; // rerun filter
+}
+
+int SEQVis::onPaint(Canvas *canvas)
+{
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+
+ SEQVIS_PARENT::onPaint(canvas);
+
+ RECT s, r;
+ getClientRect(&r);
+ s.left = 0;
+ s.top = 0;
+ s.right = cur_w;
+ s.bottom = cur_h;
+
+ if (invalidated)
+ {
+ SkinBitmap *b = bc->getSkinBitmap();
+ foreach(filters)
+ filters.getfor()->filterBitmap((unsigned char *)bc->getBits(), b->getWidth(), b->getHeight(), 32, NULL, L"Vis/Eq");
+ endfor;
+ invalidated = 0;
+ b->stretchToRectAlpha(canvas, &s, &r, getPaintingAlpha());
+ }
+ else
+ {
+ bc->stretchToRectAlpha(canvas, &s, &r, getPaintingAlpha());
+ //SkinBitmap *b = bc->getSkinBitmap();
+ //b->stretchToRectAlpha(canvas, &s, &r, getPaintingAlpha());
+ }
+
+
+ return 1;
+}
+
+int SEQVis::corecb_onEQBandChange(int b, int newval)
+{
+ DrawEQVis();
+ return 0;
+}
+
+int SEQVis::corecb_onEQPreampChange(int newval)
+{
+ DrawEQVis();
+ return 0;
+}
+
+void SEQVis::reloadResources()
+{
+ SEQVIS_PARENT::reloadResources();
+ DrawEQVis();
+ invalidate();
+}
+
+int SEQVis::onResize()
+{
+ SEQVIS_PARENT::onResize();
+ RECT r;
+ getClientRect(&r);
+
+ cur_h = r.bottom - r.top;
+ if (cur_h <= 0) cur_h = 1;
+ cur_w = r.right - r.left;
+ if (cur_w <= 0) cur_w = 1;
+
+ delete bc;
+ bc = new BltCanvas(cur_w, -cur_h);
+ specData = (int *)bc->getBits();
+ MEMSET(specData, 0, cur_w*cur_h*4);
+
+ if (shadedColors) FREE(shadedColors);
+ shadedColors = (int *)MALLOC(sizeof(int) * cur_h);
+ int r1 = colortop & 0xff0000;
+ int g1 = (colortop & 0x00ff00) << 8;
+ int b1 = (colortop & 0x0000ff) << 16;
+ int r2 = colormid & 0xff0000;
+ int g2 = (colormid & 0x00ff00) << 8;
+ int b2 = (colormid & 0x0000ff) << 16;
+ int r3 = colorbottom & 0xff0000;
+ int g3 = (colorbottom & 0x00ff00) << 8;
+ int b3 = (colorbottom & 0x0000ff) << 16;
+ int l = cur_h / 2;
+ if (!l) l = 1;
+ int i;
+ for (i = 0;i < l;i++)
+ {
+ int r = r1 + ((r2 - r1) * i / l);
+ int g = g1 + ((g2 - g1) * i / l);
+ int b = b1 + ((b2 - b1) * i / l);
+ shadedColors[i] = (r & 0xff0000);
+ shadedColors[i] += ((g & 0xff0000) >> 8);
+ shadedColors[i] += ((b & 0xff0000) >> 16);
+ shadedColors[i] += 0xff000000; // alpha?
+ }
+ for (i = l;i < cur_h;i++)
+ {
+ int r = r2 + ((r3 - r2) * (i - l) / l);
+ int g = g2 + ((g3 - g2) * (i - l) / l);
+ int b = b2 + ((b3 - b2) * (i - l) / l);
+ shadedColors[i] = (r & 0xff0000);
+ shadedColors[i] += ((g & 0xff0000) >> 8);
+ shadedColors[i] += ((b & 0xff0000) >> 16);
+ shadedColors[i] += 0xff000000; // alpha?
+ }
+ DrawEQVis();
+
+ return 1;
+}
+
+EqVisScriptController _eqvisController;
+EqVisScriptController *eqvisController = &_eqvisController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct EqVisScriptController::exportedFunction[] = {
+ {L"fake", 0, (void*)SEQVis::script_vcpu_fake },
+ };
+
+// --------------------------------------------------------
+
+const wchar_t *EqVisScriptController::getClassName()
+{
+ return L"EqVis";
+}
+
+const wchar_t *EqVisScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *EqVisScriptController::instantiate()
+{
+ SEQVis *eqv = new SEQVis;
+ ASSERT(eqv != NULL);
+ return eqv->getScriptObject();
+}
+
+void EqVisScriptController::destroy(ScriptObject *o)
+{
+ SEQVis *eqv = static_cast<SEQVis *>(o->vcpu_getInterface(eqvisGuid));
+ ASSERT(eqv != NULL);
+ delete eqv;
+}
+
+void *EqVisScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for eqvis yet
+}
+
+void EqVisScriptController::deencapsulate(void *o)
+{}
+
+int EqVisScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *EqVisScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID EqVisScriptController::getClassGuid()
+{
+ return eqvisGuid;
+}
+
+// -----------------------------------------------------------------------
+
+
+scriptVar SEQVis::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/seqvis.h b/Src/Wasabi/api/skin/widgets/seqvis.h
new file mode 100644
index 00000000..0562c8a2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/seqvis.h
@@ -0,0 +1,104 @@
+#ifndef _SEQVIS_H
+#define _SEQVIS_H
+
+#include <api/wnd/basewnd.h>
+#include <api/wnd/virtualwnd.h>
+#include <api/syscb/callbacks/corecbi.h>
+#include <api/service/svc_enum.h>
+#include <api/service/svcs/svc_skinfilter.h>
+#include <api/script/objects/guiobj.h>
+
+// {8D1EBA38-489E-483e-B960-8D1F43C5C405}
+static const GUID eqvisGuid =
+{ 0x8d1eba38, 0x489e, 0x483e, { 0xb9, 0x60, 0x8d, 0x1f, 0x43, 0xc5, 0xc4, 0x5 } };
+
+#define SEQVIS_PARENT GuiObjectWnd
+
+class EqVisScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern EqVisScriptController *eqvisController;
+
+class SEQVis : public SEQVIS_PARENT, public CoreCallbackI {
+public:
+ SEQVis();
+ virtual ~SEQVis();
+
+ virtual int setXuiParam(int xiuhandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue);
+
+ int onInit();
+ void DrawEQVis();
+ int onPaint(Canvas *canvas);
+
+ virtual int onResize();
+
+protected:
+/*static */void CreateXMLParameters(int master_handle);
+ typedef struct {
+ float *keys; /* Key data, keyWidth*numKeys */
+ signed int keyWidth; /* Number of floats per key */
+ signed int numKeys; /* Number of keys */
+ float cont; /* Continuity. Should be -1.0 -> 1.0 */
+ float bias; /* Bias. -1.0 -> 1.0 */
+ float tens; /* Tension. -1.0 -> 1.0 */
+ } spline_struct;
+
+ void splineGetPoint(spline_struct *s, float frame, float *out);
+
+ virtual int corecb_onEQPreampChange(int newval);
+ virtual int corecb_onEQBandChange(int band, int newval);
+
+ virtual void reloadResources();
+
+ enum {
+ SEQVIS_SETALPHA=0,
+ SEQVIS_SETCOLORTOP,
+ SEQVIS_SETCOLORMIDDLE,
+ SEQVIS_SETCOLORBOTTOM,
+ SEQVIS_SETCOLORPREAMP,
+ };
+
+
+private:
+ static XMLParamPair params[];
+ BltCanvas *bc;
+ int *specData;
+ int cur_w, cur_h;
+ int colortop, colormid, colorbottom;
+ int colorpreamp;
+ int *shadedColors;
+ int invalidated;
+ PtrList<svc_skinFilter>filters;
+ SkinFilterEnum *sfe;
+ int xuihandle;
+
+public:
+
+ static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static void instantiate(SEQVis *s);
+
+};
+
+extern const wchar_t eqVisXuiStr[];
+extern char eqVisXuiSvcName[];
+class EqVisXuiSvc : public XuiObjectSvc<SEQVis, eqVisXuiStr, eqVisXuiSvcName> {};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/spanbar.cpp b/Src/Wasabi/api/skin/widgets/spanbar.cpp
new file mode 100644
index 00000000..b377f88e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/spanbar.cpp
@@ -0,0 +1,58 @@
+#include <precomp.h>
+#include "spanbar.h"
+#include <api/core/api_core.h>
+
+const wchar_t panBarXuiStr[] = L"PanBar"; // This is the xml tag
+char panBarXuiSvcName[] = "PanBar xui object"; // this is the name of the xuiservice
+
+
+#define SPANBAR_NOTIFY_MSG NUM_NOTIFY_MESSAGES+0x1000
+
+SPanBar::SPanBar() {
+ setDrawOnBorders(TRUE);
+ setEnable(TRUE);
+ setHotPosition(127);
+ locked = 0;
+}
+
+SPanBar::~SPanBar() {
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SPanBar::onInit() {
+ SPANBAR_PARENT::onInit();
+
+ corecb_onPanChange(WASABI_API_MEDIACORE->core_getPan(0));
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+
+ return 1;
+}
+
+int SPanBar::onSetPosition() {
+ setHotPosition((Std::keyDown(VK_SHIFT) ? -1 : 127));
+ SPANBAR_PARENT::onSetPosition();
+ int pos = getSliderPosition(); // get slider pos
+ int p=pos-127;
+ WASABI_API_MEDIACORE->core_setPan(0,p);
+ return 1;
+}
+
+int SPanBar::corecb_onPanChange(int newpan) {
+ if (getSeekStatus()) return 0;
+ int pos = newpan+127;
+ setPosition(pos,0);
+ onPostedPosition(pos);
+ return 0;
+}
+
+void SPanBar::lock() {
+ if (locked) return;
+ locked = 1;
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+void SPanBar::unlock() {
+ if (!locked) return;
+ locked = 0;
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/spanbar.h b/Src/Wasabi/api/skin/widgets/spanbar.h
new file mode 100644
index 00000000..63d40941
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/spanbar.h
@@ -0,0 +1,31 @@
+#ifndef _SPANBAR_H
+#define _SPANBAR_H
+
+#include "pslider.h"
+#include <api/syscb/callbacks/corecbi.h>
+
+#define SPANBAR_PARENT PSliderWnd
+#define SPANBAR_XMLPARENT PSliderWnd
+
+class SPanBar : public SPANBAR_PARENT, public CoreCallbackI {
+public:
+ SPanBar();
+ virtual ~SPanBar();
+
+ virtual int onInit();
+ virtual void lock();
+ virtual void unlock();
+
+protected:
+ int locked;
+ virtual int onSetPosition();
+
+ virtual int corecb_onPanChange(int newpan);
+};
+
+extern const wchar_t panBarXuiStr[];
+extern char panBarXuiSvcName[];
+class PanBarXuiSvc : public XuiObjectSvc<SPanBar, panBarXuiStr, panBarXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/sseeker.cpp b/Src/Wasabi/api/skin/widgets/sseeker.cpp
new file mode 100644
index 00000000..fb2cbe5b
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/sseeker.cpp
@@ -0,0 +1,128 @@
+#include <precomp.h>
+
+#include "sseeker.h"
+#include <api/script/scriptmgr.h>
+#include <api/core/api_core.h>
+
+#define SSeeker_TIMER_POS 1
+#define SSEEKER_INTERVAL 500
+
+const wchar_t seekBarXuiStr[] = L"SeekBar"; // This is the xml tag
+char seekBarXuiSvcName[] = "SeekBar xui object"; // this is the name of the xuiservice
+
+XMLParamPair SSeeker::params[] = {
+ {SSEEKER_SETINTERVAL, L"INTERVAL"},
+};
+SSeeker::SSeeker() {
+ setDrawOnBorders(TRUE);
+ status = STOP;
+ update_interval = SSEEKER_INTERVAL;
+ locked = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ setLimits(0, 65535);
+}
+
+void SSeeker::CreateXMLParameters(int master_handle)
+{
+ //SSEEKER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+SSeeker::~SSeeker() {
+ killTimer(SSeeker_TIMER_POS);
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SSeeker::setXuiParam(int _xuihandle, int attribid, const wchar_t *name, const wchar_t *strval) {
+ if (xuihandle != _xuihandle) return SSEEKER_PARENT::setXuiParam(_xuihandle, attribid, name, strval);
+ switch (attribid) {
+ case SSEEKER_SETINTERVAL:
+ if ((update_interval = WTOI(strval)) <= 20)
+ update_interval = SSEEKER_INTERVAL;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int SSeeker::onInit() {
+ SSEEKER_PARENT::onInit();
+
+ timerCallback(SSeeker_TIMER_POS);
+ setTimer(SSeeker_TIMER_POS, update_interval);
+
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+
+ return 1;
+}
+
+int SSeeker::onSetFinalPosition() {
+ SSEEKER_PARENT::onSetFinalPosition();
+ if (WASABI_API_MEDIACORE->core_getPosition(0) == -1) return 1;
+ int pos = getSliderPosition(); // get slider pos
+ int len = WASABI_API_MEDIACORE->core_getLength(0);
+ int corepos = (int)(((double)pos * (double)len) / 65535.f);
+ WASABI_API_MEDIACORE->core_setPosition(0,corepos);
+ return 1;
+}
+
+void SSeeker::timerCallback(int id) {
+ switch (id) {
+ case SSeeker_TIMER_POS: {
+ if (getSeekStatus()) return;
+
+ int playpos = WASABI_API_MEDIACORE->core_getPosition(0);
+ int len = WASABI_API_MEDIACORE->core_getLength(0);
+ if (playpos < 0 || len <= 0) {
+ setVisible(0);
+ status=STOP;
+ return;
+ }
+ int newpos = (int)(((double)playpos / (double)len) * 65535.f);
+ if (getSliderPosition() != newpos) {
+ setPosition(newpos, 0);
+ onPostedPosition(newpos / scriptDivisor());
+ }
+ if (len > 0 && !isVisible()) {
+ status=PLAY;
+ setVisible(1);
+ }
+ }
+ break;
+ default:
+ SSEEKER_PARENT::timerCallback(id);
+ }
+}
+
+int SSeeker::corecb_onStarted() {
+ timerCallback(SSeeker_TIMER_POS);
+ return 0;
+}
+
+int SSeeker::corecb_onStopped() {
+ timerCallback(SSeeker_TIMER_POS);
+ return 0;
+}
+
+int SSeeker::corecb_onSeeked(int newpos) {
+ timerCallback(SSeeker_TIMER_POS);
+ return 0;
+}
+
+void SSeeker::lock() {
+ if (locked) return;
+ locked = 1;
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+void SSeeker::unlock() {
+ if (!locked) return;
+ locked = 0;
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/sseeker.h b/Src/Wasabi/api/skin/widgets/sseeker.h
new file mode 100644
index 00000000..ee948059
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/sseeker.h
@@ -0,0 +1,56 @@
+#ifndef _SSEEKER_H
+#define _SSEEKER_H
+
+#include "pslider.h"
+#include <api/syscb/callbacks/corecbi.h>
+
+#define SSEEKER_PARENT PSliderWnd
+#define SSEEKER_XMLPARENT PSliderWnd
+
+#define STOP 0
+#define PLAY 1
+
+class SSeeker : public SSEEKER_PARENT, public CoreCallbackI {
+public:
+ SSeeker();
+ virtual ~SSeeker();
+
+ virtual int onInit();
+
+ virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *val);
+ virtual void lock();
+ virtual void unlock();
+
+ virtual int scriptDivisor() { return 256; }
+
+ enum {
+ SSEEKER_SETINTERVAL=0,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ virtual int onSetFinalPosition();
+
+ // from BaseWnd
+ virtual void timerCallback(int id);
+
+ // from CoreCallbackI
+ virtual int corecb_onSeeked(int newpos);
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+
+ int status;
+
+private:
+ static XMLParamPair params[];
+ int update_interval;
+ int locked;
+ int xuihandle;
+};
+
+extern const wchar_t seekBarXuiStr[];
+extern char seekBarXuiSvcName[];
+class SeekBarXuiSvc : public XuiObjectSvc<SSeeker, seekBarXuiStr, seekBarXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/sstatus.cpp b/Src/Wasabi/api/skin/widgets/sstatus.cpp
new file mode 100644
index 00000000..e17d4da2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/sstatus.cpp
@@ -0,0 +1,172 @@
+#include <precomp.h>
+#include <api/wndmgr/layout.h>
+#include "sstatus.h"
+#include <api/core/api_core.h>
+
+const wchar_t statusXuiStr[] = L"Status"; // This is the xml tag
+char statusXuiSvcName[] = "Status xui object"; // this is the name of the xuiservice
+XMLParamPair SStatus::params[] = {
+ {SSTATUS_SETPLAYBITMAP, L"PLAYBITMAP"},
+ {SSTATUS_SETSTOPBITMAP, L"STOPBITMAP"},
+ {SSTATUS_SETPAUSEBITMAP, L"PAUSEBITMAP"},
+};
+
+SStatus::SStatus() {
+ getScriptObject()->vcpu_setInterface(statusGuid, (void *)static_cast<SStatus *>(this));
+ getScriptObject()->vcpu_setClassName(L"Status");
+ getScriptObject()->vcpu_setController(statusController);
+ currentStatus = -666;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+}
+
+void SStatus::CreateXMLParameters(int master_handle)
+{
+ //SSTATUS_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+SStatus::~SStatus() {
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SStatus::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval) {
+ if (_xuihandle != xuihandle) return SSTATUS_PARENT::setXuiParam(_xuihandle, attrid, name, strval);
+ switch (attrid) {
+ case SSTATUS_SETPLAYBITMAP:
+ setPlayBitmap(strval);
+ break;
+ case SSTATUS_SETSTOPBITMAP:
+ setStopBitmap(strval);
+ break;
+ case SSTATUS_SETPAUSEBITMAP:
+ setPauseBitmap(strval);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int SStatus::getPreferences(int what) {
+ if (what == SUGGESTED_W) return getWidth();
+ if (what == SUGGESTED_H) return getHeight();
+ return SSTATUS_PARENT::getPreferences(what);
+}
+
+int SStatus::getWidth() {
+ if (!playBitmap.getBitmap()) return 16;
+ return playBitmap.getWidth();
+}
+
+int SStatus::getHeight() {
+ if (!playBitmap.getBitmap()) return 16;
+ return playBitmap.getHeight();
+}
+
+int SStatus::onInit() {
+ SSTATUS_PARENT::onInit();
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ currentStatus=WASABI_API_MEDIACORE->core_getStatus(0);
+ return 1;
+}
+
+int SStatus::onPaint(Canvas *canvas) {
+ PaintBltCanvas paintcanvas;
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+
+ SSTATUS_PARENT::onPaint(canvas);
+
+ RECT r;
+ getClientRect(&r);
+
+ AutoSkinBitmap *rb = NULL;
+ switch(currentStatus) {
+ case -1: rb = &pauseBitmap; break;
+ case 0: rb = &stopBitmap; break;
+ case 1: rb = &playBitmap; break;
+ }
+ if (rb != NULL && rb->getBitmap() != NULL) rb->stretchToRect(canvas, &r);
+
+ return 1;
+}
+
+int SStatus::corecb_onStarted() { currentStatus=1; invalidate(); return 0; }
+int SStatus::corecb_onStopped() { currentStatus=0; invalidate(); return 0; }
+int SStatus::corecb_onPaused() { currentStatus=-1; invalidate(); return 0; }
+int SStatus::corecb_onUnpaused() { currentStatus=1; invalidate(); return 0; }
+
+void SStatus::setPlayBitmap(const wchar_t *name)
+{
+ playBitmap=name;
+}
+
+void SStatus::setPauseBitmap(const wchar_t *name) {
+ pauseBitmap=name;
+}
+
+void SStatus::setStopBitmap(const wchar_t *name) {
+ stopBitmap=name;
+}
+
+StatusScriptController _statusController;
+StatusScriptController *statusController=&_statusController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct StatusScriptController::exportedFunction[] = {
+ {L"fake", 0, (void*)SStatus::script_vcpu_fake },
+};
+
+// --------------------------------------------------------
+
+const wchar_t *StatusScriptController::getClassName() {
+ return L"Status";
+}
+
+const wchar_t *StatusScriptController::getAncestorClassName() {
+ return L"GuiObject";
+}
+
+ScriptObject *StatusScriptController::instantiate() {
+ SStatus *st = new SStatus;
+ ASSERT(st != NULL);
+ return st->getScriptObject();
+}
+
+void StatusScriptController::destroy(ScriptObject *o) {
+ SStatus *st = static_cast<SStatus*>(o->vcpu_getInterface(statusGuid));
+ ASSERT(st != NULL);
+ delete st;
+}
+
+void *StatusScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for status yet
+}
+
+void StatusScriptController::deencapsulate(void *o) {
+}
+
+int StatusScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *StatusScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID StatusScriptController::getClassGuid() {
+ return statusGuid;
+}
+
+scriptVar SStatus::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/sstatus.h b/Src/Wasabi/api/skin/widgets/sstatus.h
new file mode 100644
index 00000000..eec7b38d
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/sstatus.h
@@ -0,0 +1,100 @@
+//PORTABLE
+#ifndef _SSTATUS_H
+#define _SSTATUS_H
+
+#include <api/wnd/basewnd.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <api/wnd/virtualwnd.h>
+#include <api/syscb/callbacks/corecbi.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+// {0F08C940-AF39-4b23-80F3-B8C48F7EBB59}
+static const GUID statusGuid =
+{ 0xf08c940, 0xaf39, 0x4b23, { 0x80, 0xf3, 0xb8, 0xc4, 0x8f, 0x7e, 0xbb, 0x59 } };
+
+#define SSTATUS_PARENT GuiObjectWnd
+
+class StatusScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern StatusScriptController *statusController;
+
+
+#ifndef _NOSTUDIO
+class SStatus : public SSTATUS_PARENT, public CoreCallbackI {
+public:
+ SStatus();
+ virtual ~SStatus();
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *canvas);
+
+ void setPlayBitmap(const wchar_t *name);
+ void setPauseBitmap(const wchar_t *name);
+ void setStopBitmap(const wchar_t *name);
+
+ virtual int getWidth();
+ virtual int getHeight();
+
+ virtual int setXuiParam(int xuihandle, int attrid, const wchar_t *name, const wchar_t *strval);
+ virtual int getPreferences(int what);
+
+ // core callbacks
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+ virtual int corecb_onPaused();
+ virtual int corecb_onUnpaused();
+
+ enum {
+ SSTATUS_SETPLAYBITMAP=0,
+ SSTATUS_SETSTOPBITMAP,
+ SSTATUS_SETPAUSEBITMAP,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+/*protected:
+ virtual void timerCallback(int id);*/
+
+private:
+ AutoSkinBitmap playBitmap,pauseBitmap,stopBitmap;
+
+ int currentStatus;
+ int xuihandle;
+ static XMLParamPair params[];
+
+#else
+
+class SStatus : public SSTATUS_SCRIPTPARENT {
+
+#endif
+
+public:
+
+ static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+};
+
+extern const wchar_t statusXuiStr[];
+extern char statusXuiSvcName[];
+class StatusXuiSvc : public XuiObjectSvc<SStatus, statusXuiStr, statusXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/stats/statswnd.cpp b/Src/Wasabi/api/skin/widgets/stats/statswnd.cpp
new file mode 100644
index 00000000..116c6c95
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/stats/statswnd.cpp
@@ -0,0 +1,38 @@
+#include <precomp.h>
+#include "statswnd.h"
+#include <bfc/string/StringW.h>
+
+StatsWnd::StatsWnd()
+{
+ registerXml();
+ WASABI_API_WNDMGR->autopopup_registerGroupId(L"statswnd.group", L"Internal Statistics");
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+StatsWnd::~StatsWnd()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int StatsWnd::skincb_onBeforeLoadingElements()
+{
+ registerXml();
+ return 1;
+}
+
+void StatsWnd::registerXml()
+{
+ StringW xml;
+
+ xml = L"buf:";
+
+ xml += L"<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>\n";
+ xml += L"<WasabiXml version=\"1.0\">\n";
+ xml += L"<groupdef id=\"statswnd.group\" name=\"Internal Statistics\">\n";
+ xml += L" <Wasabi:Stats fitparent=\"1\" />\n";
+ xml += L"</groupdef>\n";
+ xml += L"</WasabiXml>\n";
+
+ WASABI_API_SKIN->loadSkinFile(xml);
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/stats/statswnd.h b/Src/Wasabi/api/skin/widgets/stats/statswnd.h
new file mode 100644
index 00000000..8b66ad14
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/stats/statswnd.h
@@ -0,0 +1,18 @@
+#ifndef __STATSWND_H
+#define __STATSWND_H
+
+#include <api/syscb/callbacks/skincb.h>
+
+class StatsWnd : public SkinCallbackI {
+ public:
+ StatsWnd();
+ virtual ~StatsWnd();
+
+ virtual int skincb_onBeforeLoadingElements();
+
+ private:
+ void registerXml();
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/stats/xuistats.cpp b/Src/Wasabi/api/skin/widgets/stats/xuistats.cpp
new file mode 100644
index 00000000..dd4f2927
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/stats/xuistats.cpp
@@ -0,0 +1,149 @@
+#include <precomp.h>
+#include "xuistats.h"
+#include <tataki/canvas/ifc_canvas.h>
+#include <tataki/color/skinclr.h>
+#include <api.h>
+
+#include <api/imgldr/imgldr.h>
+#include <api/skin/skinparse.h>
+#include <api/skin/gammamgr.h>
+#include <api/skin/skinelem.h>
+#include <api/skin/regioncache.h>
+#include <api/wnd/wndtrack.h>
+#include <api/font/font.h>
+#include <api/wnd/wndapi.h>
+#include <api/skin/guitree.h>
+#include <api/xml/xmlreader.h>
+#include <api/skin/groupwndcreate.h>
+#include <api/skin/groupmgr.h>
+#include <api/script/script.h>
+#include "bfc/ptrlist.h"
+#include "bfc/memblock.h"
+
+// -----------------------------------------------------------------------
+const wchar_t XuiStatsXuiObjectStr[] = L"Wasabi:Stats"; // This is the xml tag
+char XuiStatsXuiSvcName[] = "Wasabi:Stats xui object";
+
+
+// -----------------------------------------------------------------------
+XuiStats::XuiStats() {
+ hastimer = 0;
+ line = 0;
+ col = 0;
+ curcanvas = NULL;
+}
+
+// -----------------------------------------------------------------------
+XuiStats::~XuiStats() {
+ if (hastimer)
+ killTimer(0x10);
+}
+
+// -----------------------------------------------------------------------
+int XuiStats::onInit() {
+ XUISTATS_PARENT::onInit();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+#define MARGIN 10
+#define FONTSIZE 15
+#define LINEMUL 15
+#define COLMUL 200
+void XuiStats::doTextOut(Canvas *canvas, const wchar_t *text, int line, int col, const Wasabi::FontInfo *fontInfo)
+{
+ RECT r;
+ getClientRect(&r);
+ if (!canvas || !text || !*text) return;
+ canvas->textOutEllipsed(r.left+MARGIN+col*COLMUL, r.top+MARGIN+line*LINEMUL, COLMUL-MARGIN/2, LINEMUL, text, fontInfo);
+}
+
+// -----------------------------------------------------------------------
+void XuiStats::addLine(const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
+{
+ if (!curcanvas) return;
+ RECT r;
+ getClientRect(&r);
+ if (line * LINEMUL + MARGIN + FONTSIZE + r.top > r.bottom)
+ { col++; line = 0; if (*txt == 0) return; }
+ doTextOut(curcanvas, txt, line++, col, fontInfo);
+}
+
+// -----------------------------------------------------------------------
+int XuiStats::onPaint(Canvas *canvas)
+{
+ XUISTATS_PARENT::onPaint(canvas);
+ curcanvas = canvas;
+ line = 0;
+ col = 0;
+
+ Wasabi::FontInfo fontInfo;
+ fontInfo.face = wasabi_default_fontnameW;
+ fontInfo.pointSize = FONTSIZE;
+ fontInfo.color = SkinColor(L"wasabi.list.text");
+
+ addLine(L"---------------------------- System ------", &fontInfo);
+ //addLine( StringPrintfW(L"entries in ptrlists : %d", ptrlist_totalnitems) );
+#ifdef _DEBUG
+ addLine( StringPrintfW(L"total memblocks size : %d", memblocks_totalsize) , &fontInfo);
+#endif
+
+ // TODO: add to api_timer - addLine( StringPrintfW(L"timers : %d/%d", mainmultiplex->getNumTimers(), mainmultiplex->getNumTimersLP()) , &fontInfo);
+
+ addLine(L"", &fontInfo);
+ addLine(L"----------------------------- Wnds -------", &fontInfo);
+ addLine( StringPrintfW(L"rootwnds : %d", windowTracker->getNumAllWindows()) , &fontInfo);
+ addLine( StringPrintfW(L"desktop rootwnds : %d", windowTracker->getNumWindows()) , &fontInfo);
+
+ addLine(L"", &fontInfo);
+ addLine(L"--------------------------- ImgLdr -------", &fontInfo);
+ addLine( StringPrintfW(L"bytes in imgldr : %d", imageLoader::getMemUsage()) , &fontInfo);
+ addLine( StringPrintfW(L"cached imgldr entries : %d", imageLoader::getNumCached()) , &fontInfo);
+ addLine( StringPrintfW(L"region caches : %d", RegionCache::getNumCaches()) , &fontInfo);
+
+ addLine(L"", &fontInfo);
+ addLine(L"----------------------------- Skin -------", &fontInfo);
+ addLine( StringPrintfW(L"skin bitmap elements : %d", WASABI_API_PALETTE->getNumBitmapElement()) , &fontInfo);
+ addLine( StringPrintfW(L"skin color elements : %d", WASABI_API_PALETTE->getNumColorElements()) , &fontInfo);
+ addLine( StringPrintfW(L"containers loaded : %d", SkinParser::getNumContainers()) , &fontInfo);
+ addLine( StringPrintfW(L"gamma sets : %d", WASABI_API_COLORTHEMES->getNumGammaSets()) , &fontInfo);
+ addLine( StringPrintfW(L"fonts : %d", Font::getNumFonts()) , &fontInfo);
+ addLine( StringPrintfW(L"base textures : %d", WndApi::getNumBaseTextures()) , &fontInfo);
+ addLine( StringPrintfW(L"guitree entries : %d", guiTree->getNumObject()) , &fontInfo);
+ addLine( StringPrintfW(L"wndtype groups : %d", GroupWndCreateSvc::num_group_list) , &fontInfo);
+ addLine( StringPrintfW(L"hosted groups : %d", GroupMgr::getNumGroups()) , &fontInfo);
+ addLine( StringPrintfW(L"scripts : %d", Script::getNumScripts()) , &fontInfo);
+
+ addLine(L"", &fontInfo);
+ addLine(L"----------------------------- Misc -------", &fontInfo);
+ addLine( StringPrintfW(L"registered cfgitems : %d", WASABI_API_CONFIG->config_getNumCfgItems()) , &fontInfo);
+
+ if (WASABI_API_THREADPOOL)
+ {
+ addLine(L"", &fontInfo);
+ addLine(L"----------------------------- ThreadPool -------", &fontInfo);
+ addLine( StringPrintfW(L"active threads : %d", WASABI_API_THREADPOOL->GetNumberOfActiveThreads()) , &fontInfo);
+ addLine( StringPrintfW(L"threads in pool : %d", WASABI_API_THREADPOOL->GetNumberOfThreads()) , &fontInfo);
+ }
+
+ curcanvas = NULL;
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void XuiStats::onSetVisible(int show) {
+ XUISTATS_PARENT::onSetVisible(show);
+ if (show) {
+ setTimer(0x10, 250);
+ } else {
+ killTimer(0x10);
+ }
+ hastimer = show;
+}
+
+// -----------------------------------------------------------------------
+void XuiStats::timerCallback(int p1) {
+ if (p1 == 0x10) invalidate();
+ else XUISTATS_PARENT::timerCallback(p1);
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/stats/xuistats.h b/Src/Wasabi/api/skin/widgets/stats/xuistats.h
new file mode 100644
index 00000000..c6b91a6a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/stats/xuistats.h
@@ -0,0 +1,43 @@
+#ifndef __XUISTATS_H
+#define __XUISTATS_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define XUISTATS_PARENT GuiObjectWnd
+
+// {12D9C377-A981-4b77-95E0-242AF7226960}
+static const GUID COLOREDIT_PREVIEWRECT_GUID =
+{ 0x12d9c377, 0xa981, 0x4b77, { 0x95, 0xe0, 0x24, 0x2a, 0xf7, 0x22, 0x69, 0x60 } };
+
+class ColorEditorInstance;
+
+// -----------------------------------------------------------------------
+class XuiStats : public XUISTATS_PARENT {
+
+ public:
+
+ XuiStats();
+ virtual ~XuiStats();
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *c);
+ virtual void onSetVisible(int show);
+ virtual void timerCallback(int p1);
+
+ virtual void addLine(const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
+
+ private:
+ void doTextOut(Canvas *canvas, const wchar_t *text, int line, int col, const Wasabi::FontInfo *fontInfo);
+ int hastimer;
+
+ int line ;
+ int col;
+ Canvas *curcanvas;
+};
+
+// -----------------------------------------------------------------------
+extern const wchar_t XuiStatsXuiObjectStr[];
+extern char XuiStatsXuiSvcName[];
+class XuiStatsXuiSvc : public XuiObjectSvc<XuiStats, XuiStatsXuiObjectStr, XuiStatsXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/svolbar.cpp b/Src/Wasabi/api/skin/widgets/svolbar.cpp
new file mode 100644
index 00000000..5152224a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/svolbar.cpp
@@ -0,0 +1,55 @@
+#include <precomp.h>
+#include "svolbar.h"
+#include <api/core/api_core.h>
+
+const wchar_t volBarXuiStr[] = L"VolBar"; // This is the xml tag
+char volBarXuiSvcName[] = "VolBar xui object"; // this is the name of the xuiservice
+
+
+#define SVOLBAR_NOTIFY_MSG NUM_NOTIFY_MESSAGES+0x1000
+
+SVolBar::SVolBar() {
+ setDrawOnBorders(TRUE);
+ setEnable(TRUE);
+ locked = 0;
+ setLimits(0,255);
+}
+
+SVolBar::~SVolBar() {
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+int SVolBar::onInit() {
+ SVOLBAR_PARENT::onInit();
+
+ corecb_onVolumeChange(WASABI_API_MEDIACORE->core_getVolume(0));
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+
+ return 1;
+}
+
+int SVolBar::onSetPosition() {
+ SVOLBAR_PARENT::onSetPosition();
+ int pos = getSliderPosition(); // get slider pos
+ WASABI_API_MEDIACORE->core_setVolume(0,pos);
+ return 1;
+}
+
+int SVolBar::corecb_onVolumeChange(int newvol) {
+ if (getSeekStatus()) return 0;
+ setPosition(newvol, 0);
+ onPostedPosition(newvol);
+ return 0;
+}
+
+void SVolBar::lock() {
+ if (locked) return;
+ locked = 1;
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+void SVolBar::unlock() {
+ if (!locked) return;
+ locked = 0;
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/svolbar.h b/Src/Wasabi/api/skin/widgets/svolbar.h
new file mode 100644
index 00000000..30f2f18d
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/svolbar.h
@@ -0,0 +1,30 @@
+#ifndef _SVOLBAR_H
+#define _SVOLBAR_H
+
+#include "pslider.h"
+#include <api/syscb/callbacks/corecbi.h>
+
+#define SVOLBAR_PARENT PSliderWnd
+#define SVOLBAR_XMLPARENT PSliderWnd
+
+class SVolBar : public SVOLBAR_PARENT, public CoreCallbackI {
+public:
+ SVolBar();
+ virtual ~SVolBar();
+
+ virtual int onInit();
+ virtual void lock();
+ virtual void unlock();
+
+protected:
+ int locked;
+ virtual int onSetPosition();
+
+ virtual int corecb_onVolumeChange(int newvol);
+};
+
+extern const wchar_t volBarXuiStr[];
+extern char volBarXuiSvcName[];
+class VolBarXuiSvc : public XuiObjectSvc<SVolBar, volBarXuiStr, volBarXuiSvcName> {};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/text.cpp b/Src/Wasabi/api/skin/widgets/text.cpp
new file mode 100644
index 00000000..fd7a16f4
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/text.cpp
@@ -0,0 +1,1767 @@
+#include <precomp.h>
+#include "text.h"
+#include <api.h>
+#include <api/wndmgr/layout.h>
+#ifdef WASABI_WIDGETS_COMPBUCK
+#include <api/skin/widgets/compbuck2.h>
+#endif
+#include <api/skin/skinparse.h>
+#if defined(WA3COMPATIBILITY) || defined(WASABI_STATICVARMGR)
+#include <api/util/varmgr.h>
+#endif
+#include <api/core/sequence.h>
+#include <api/script/vcpu.h>
+#ifdef WA3COMPATIBILITY
+#include <core/corehandle.h>
+#endif
+#include <api/wnd/notifmsg.h>
+#include <api/locales/xlatstr.h>
+#include <api/skin/feeds/TextFeedEnum.h>
+#include <bfc/parse/pathparse.h>
+#include <bfc/util/timefmt.h>
+#ifdef WASABI_COMPILE_MEDIACORE
+#include <api/core/api_core.h>
+#endif
+#include <api/service/svcs/svc_font.h>
+#include <api/config/items/attribs.h>
+#include <api/skin/skinelem.h>
+#include <api/service/svcs/svc_action.h>
+#include <tataki/blending/blending.h>
+#include <tataki/canvas/bltcanvas.h>
+
+
+const wchar_t textXuiObjectStr[] = L"Text"; // This is the xml tag
+char textXuiSvcName[] = "Text xui object"; // this is the name of the xuiservice
+
+#define TTS_DELAY 4000
+
+#define TICKER_TIMER_POS 1
+#define TICKER_RESET_ALTNAME 2
+#define TIMER_SKIPCFG 0x987
+
+#define COLORMODE_RGB 0
+#define COLORMODE_SKINCOLOR 1
+
+XMLParamPair Text::params[] =
+{
+ {TEXT_SETALTSHADOWCOLOR, L"ALTSHADOWCOLOR"},
+ {TEXT_SETALTSHADOWX, L"ALTSHADOWX"},
+ {TEXT_SETALTSHADOWY, L"ALTSHADOWY"},
+ {TEXT_SETALTVALIGN, L"ALTVALIGN"},
+ {TEXT_SETCBSOURCE, L"CBSOURCE"},
+ {TEXT_SETTEXT, L"DEFAULT"},
+ {TEXT_SETDISPLAY, L"DISPLAY"},
+ {TEXT_SETFORCEFIXED, L"FORCEFIXED"},
+ {TEXT_SETFORCELOCASE, L"FORCELOWERCASE"},
+ {TEXT_SETFORCELOCASE, L"FORCELOCASE"},
+ {TEXT_SETFORCEUPCASE, L"FORCEUPCASE"},
+ {TEXT_SETFORCEUPCASE, L"FORCEUPPERCASE"},
+
+ {TEXT_SETNOGRAB, L"NOGRAB"},
+ {TEXT_SETOFFSETX, L"OFFSETX"},
+ {TEXT_SETOFFSETY, L"OFFSETY"},
+
+ {TEXT_SETSHADOWCOLOR, L"SHADOWCOLOR"},
+ {TEXT_SETSHADOWX, L"SHADOWX"},
+ {TEXT_SETSHADOWY, L"SHADOWY"},
+ {TEXT_SETSHOWLEN, L"SHOWLEN"},
+ {TEXT_SETTEXT, L"TEXT"},
+ {TEXT_SETTICKER, L"TICKER"},
+ {TEXT_SETTICKERSTEP, L"TICKERSTEP"},
+ {TEXT_SETTIMECOLONWIDTH, L"TIMECOLONWIDTH"},
+ {TEXT_SETTIMERHOURS, L"TIMERHOURS"},
+ {TEXT_SETTIMEROFFSTYLE, L"TIMEROFFSTYLE"},
+ {TEXT_SETVALIGN, L"VALIGN"},
+ {TEXT_SETWRAPPED, L"WRAP"},
+ {TEXT_SETTIMERHOURSROLLOVER, L"TIMERHOURSROLLOVER"},
+};
+
+Text::Text()
+{
+ getScriptObject()->vcpu_setInterface(textGuid, (void *)static_cast<Text *>(this));
+ getScriptObject()->vcpu_setClassName(L"Text");
+ getScriptObject()->vcpu_setController(textController);
+
+ //isbitmapfont = iswinfontrender = 0;
+ bufferinvalid = 1;
+ cachedsizew = 0;
+ size[0] = size[1] = 0;
+ textpos = 0;
+ time_tts = 20;
+ tts = time_tts;
+ sens = 0;
+ grab_x = 0;
+ cur_len = 0;
+ ticker = 0;
+ timerhours = 0;
+ timerhoursRollover = 0;
+ display = DISPLAY_NONE;
+ elapsed = 1;
+ fixedTimerStyle = 0;
+
+ shadowcolor[0].setColorGroup(L"Text backgrounds");
+ shadowcolor[0].setColor(RGB(0, 0, 0));
+ shadowcolor[1].setColorGroup(L"Text backgrounds");
+ shadowcolor[1].setColor(RGB(0, 0, 0));
+
+ shadowcolor_mode[0] = COLORMODE_RGB;
+ shadowcolor_mode[1] = COLORMODE_RGB;
+ shadowx[0] = shadowx[1] = shadowy[0] = shadowy[1] = 0;
+ timecolonw = -1;
+
+ timeroffstyle = 0;
+
+ nograb = 0;
+ showlen = 0;
+ forcefixed = 0;
+
+ forceupcase = 0;
+ forcelocase = 0;
+ lastautowidth = 32;
+ textfeed = NULL;
+ wrapped = 0;
+ valign[0] = ALIGN_CENTER;
+ valign[1] = ALIGN_CENTER;
+ offsetx = 0;
+ offsety = 0;
+ tickerstep = 1;
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if (item != NULL)
+ {
+ float f = (float)item->getDataAsFloat(L"Text Ticker Speed", 1.0f / 2.0f);
+ skipn = (int)((1.0f / f) - 1 + 0.5f);
+ }
+ skip = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+ registered_syscb = 0;
+}
+
+void Text::CreateXMLParameters(int master_handle)
+{
+ //TEXT_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Text::~Text()
+{
+ killTimer(TICKER_TIMER_POS);
+ killTimer(TICKER_RESET_ALTNAME);
+ killTimer(TIMER_SKIPCFG);
+
+ if (registered_syscb) WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SvcCallbackI*>(this));
+
+#ifdef WASABI_WIDGETS_COMPBUCK
+ if (display == DISPLAY_CB)
+ if (mycbid.getNumItems() == 0)
+ ComponentBucket2::unRegisterText(this);
+ else
+ for (int i = 0;i < mycbid.getNumItems();i++)
+ ComponentBucket2::unRegisterText(this, mycbid.enumItem(i)->getValue());
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+#endif
+ if (textfeed)
+ {
+ viewer_delViewItem(textfeed->getDependencyPtr());
+ SvcEnum::release(textfeed);
+ textfeed = NULL;
+ }
+ mycbid.deleteAll();
+}
+
+int Text::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval)
+{
+ if (xuihandle != _xuihandle) return TEXT_PARENT::setXuiParam(_xuihandle, attrid, name, strval);
+ switch (attrid)
+ {
+#ifdef WASABI_COMPILE_MEDIACORE
+ case TEXT_SETDISPLAY:
+ displaystr = strval;
+ setDisplay(SkinParser::getDisplay(strval));
+ if (!_wcsicmp(strval, L"TIMEREMAINING"))
+ {
+ fixedTimerStyle = 1;
+ elapsed = 0;
+ }
+ else if (!_wcsicmp(strval, L"TIMEELAPSED"))
+ {
+ fixedTimerStyle = 1;
+ elapsed = 1;
+ }
+ break;
+#endif
+ case TEXT_SETTICKER:
+ setTickering(WTOI(strval));
+ break;
+
+ case TEXT_SETTEXT:
+ {
+ StringW old = getPrintedText();
+ deftext = parseText(strval);
+ if (!WCSCASEEQLSAFE(old, getPrintedText()))
+ {
+
+ if (WCSCASEEQLSAFE(L":componentname", deftext) || WCSCASEEQLSAFE(L"@COMPONENTNAME@", deftext))
+ {
+ Container *container = getGuiObject()->guiobject_getParentGroup()->getParentContainer();
+ viewer_addViewItem(container);
+ }
+
+ StringW str = getPrintedText();
+ onTextChanged(str);
+ }
+ break;
+ }
+
+ case TEXT_SETSHADOWCOLOR:
+ if (WASABI_API_PALETTE->getColorElementRef(strval))
+ {
+ shadowcolor_mode[0] = COLORMODE_SKINCOLOR;
+ sshadowcolor[0] = strval;
+ shadowcolor_mode[1] = COLORMODE_SKINCOLOR;
+ sshadowcolor[1] = strval;
+ }
+ else
+ setShadowColor(SkinParser::parseColor(strval), 0);
+ break;
+
+ case TEXT_SETALTSHADOWCOLOR:
+ if (WASABI_API_PALETTE->getColorElementRef(strval))
+ {
+ shadowcolor_mode[1] = COLORMODE_SKINCOLOR;
+ sshadowcolor[1] = strval;
+ }
+ else
+ setShadowColor(SkinParser::parseColor(strval), 1);
+ break;
+
+ case TEXT_SETSHADOWX:
+ setShadowX(WTOI(strval));
+ break;
+
+ case TEXT_SETALTSHADOWX:
+ setShadowX(WTOI(strval), 1);
+ break;
+
+ case TEXT_SETSHADOWY:
+ setShadowY(WTOI(strval));
+ break;
+
+ case TEXT_SETALTSHADOWY:
+ setShadowY(WTOI(strval), 0);
+ break;
+
+ case TEXT_SETTIMEROFFSTYLE:
+ setTimerOffStyle(WTOI(strval));
+ break;
+
+ case TEXT_SETTIMERHOURS:
+ setTimerHours(WTOI(strval));
+ break;
+
+ case TEXT_SETTIMERHOURSROLLOVER:
+ setTimerHoursRollover(WTOI(strval));
+ break;
+
+ case TEXT_SETTIMECOLONWIDTH:
+ setTimeColonWidth(WTOI(strval));
+ break;
+
+ case TEXT_SETNOGRAB:
+ nograb = WTOI(strval);
+ break;
+
+ case TEXT_SETSHOWLEN:
+ showlen = WTOI(strval);
+ break;
+
+ case TEXT_SETFORCEFIXED:
+ forcefixed = WTOI(strval);
+ break;
+
+ case TEXT_SETFORCEUPCASE:
+ forceupcase = WTOI(strval);
+ break;
+
+ case TEXT_SETFORCELOCASE:
+ forcelocase = WTOI(strval);
+ break;
+
+ case TEXT_SETCBSOURCE:
+ addCBSource(strval);
+ break;
+
+ case TEXT_SETWRAPPED:
+ wrapped = WTOI(strval);
+ if (isPostOnInit())
+ invalidateTextBuffer();
+ break;
+
+ case TEXT_SETVALIGN:
+ valign[0] = SkinParser::getAlign(strval);
+ valign[1] = valign[0];
+ if (isPostOnInit())
+ invalidateTextBuffer();
+ break;
+
+ case TEXT_SETALTVALIGN:
+ valign[1] = SkinParser::getAlign(strval);
+ if (isPostOnInit())
+ invalidateTextBuffer();
+ break;
+
+ case TEXT_SETOFFSETX:
+ offsetx = WTOI(strval);
+ if (isPostOnInit())
+ invalidateTextBuffer();
+ break;
+
+ case TEXT_SETTICKERSTEP:
+ tickerstep = WTOI(strval);
+ break;
+
+ case TEXT_SETOFFSETY:
+ offsety = WTOI(strval);
+ if (isPostOnInit())
+ invalidateTextBuffer();
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int Text::getPreferences(int what)
+{
+ StringW thaname = getPrintedText();
+ if (thaname.isempty())
+ {
+ return 32;
+ }
+ switch(wantTranslation())
+ {
+ case 1:
+ thaname = _(thaname);
+ break;
+ case 2:
+ thaname = __(thaname);
+ break;
+ }
+
+ int alt = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ if (item != NULL)
+ {
+ alt = item->getDataAsInt(L"Alternate Fonts", 0);
+ if (alt < 0 || alt > 1) alt = 0;
+ }
+ if (alt)
+ {
+ if (item && item->getDataAsInt(L"No 7-bit TTF AltFonts", 1))
+ {
+ const wchar_t *p = (const wchar_t *)thaname.getValue();
+ while (p && *p)
+ {
+ if (*p > 127) break;
+ p++;
+ }
+ if (p && !*p) alt = 0;
+ }
+ }
+#endif
+ switch (what)
+ {
+ case SUGGESTED_W:
+ {
+ int min_w = 0;
+ if (forceupcase)
+ thaname.toupper();
+ if (forcelocase)
+ thaname.tolower();
+ TextInfoCanvas canvas(this);
+ Wasabi::FontInfo fontInfo;
+ GetFontInfo(&fontInfo, alt);
+
+ const wchar_t *p = wcschr(thaname, ':');
+ if (display == DISPLAY_TIME && p)
+ {
+ wchar_t secs[256] = {0};
+ wchar_t mins[256] = {0};
+ WCSCPYN(mins, thaname, p - thaname);
+
+ wcsncpy(secs, p + 1, 256);
+ int fixw = canvas.getTextWidth(L"0", &fontInfo);
+ int _ws = forcefixed ? fixw * wcslen(secs) : canvas.getTextWidth(secs, &fontInfo);
+ int _wm = forcefixed ? fixw * wcslen(mins) : canvas.getTextWidth(mins, &fontInfo);
+ int _wc = forcefixed ? fixw * wcslen(L":") : canvas.getTextWidth(L":", &fontInfo);
+ min_w = _ws + _wm + getTimeColonWidth(_wc);
+ }
+ else
+ {
+ PathParserW ppg(thaname, L"\n");
+ for (int i = 0;i < ppg.getNumStrings();i++)
+ {
+ PathParserW pp(ppg.enumString(i), L"\t");
+ int w = 0;
+ for (int j = 0; j < pp.getNumStrings(); j++)
+ {
+ w += canvas.getTextWidth(pp.enumString(j), &fontInfo) + 4;
+ }
+ min_w = MAX(min_w, w);
+ }
+ }
+
+ return min_w + lpadding + rpadding;
+ }
+ case SUGGESTED_H:
+ PathParserW pp(thaname, L"\n");
+ return fontsize[alt] * pp.getNumStrings();
+ }
+ return TEXT_PARENT::getPreferences(what);
+}
+
+// supermegafucko! corehandle should mirror bitrate/samplerate/channels functions instead of text having to know about gen_ff ! -- will do that real soon
+#if defined(GEN_FF) & defined(WA5)
+#include "../../../../Plugins/General/gen_ff/wa2frontend.h"
+#endif
+
+int Text::onInit()
+{
+ TEXT_PARENT::onInit();
+ registered_syscb++;
+ initDisplay();
+ return 1;
+}
+
+void Text::initDisplay()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ setTimer(TIMER_SKIPCFG, 1000);
+#endif
+ switch (display)
+ {
+#ifdef WASABI_COMPILE_MEDIACORE
+ case DISPLAY_SONGNAME:
+ setName(WASABI_API_APP->main_getVersionString());
+ case DISPLAY_SONGARTIST:
+ case DISPLAY_SONGALBUM:
+ case DISPLAY_SONGLENGTH:
+ case DISPLAY_SONGTITLE:
+#ifndef WASABI_COMPILE_METADB
+ case DISPLAY_SONGINFO:
+ case DISPLAY_SONGINFO_TRANSLATED:
+#endif
+ setTimer(TICKER_TIMER_POS, 25);
+ setTimeTTS(TTS_DELAY / 25);
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ timerCallback(TICKER_TIMER_POS);
+#ifdef GEN_FF // supermegafucko!
+ if(WASABI_API_MEDIACORE->core_getStatus(0) != 0){
+ if (display == DISPLAY_SONGINFO)
+ {
+ StringW txt;
+ GET_SONG_INFO_TEXT(txt);
+ corecb_onInfoChange(txt);
+ }
+ else if (display == DISPLAY_SONGINFO_TRANSLATED)
+ {
+ StringW txt;
+ GET_SONG_INFO_TEXT_TRANSLATED(txt);
+ corecb_onInfoChange(txt);
+ }
+ }
+#endif
+ break;
+
+ case DISPLAY_SONGBITRATE:
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ corecb_onBitrateChange(wa2.getBitrate());
+ break;
+
+ case DISPLAY_SONGSAMPLERATE:
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ corecb_onSampleRateChange(wa2.getSamplerate());
+ break;
+
+ case DISPLAY_TIME:
+#ifdef WASABI_COMPILE_CONFIG
+
+ if (getGuiObject())
+ {
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l && l->getId()) elapsed = WASABI_API_CONFIG->getIntPrivate(StringPrintfW(L"%s/timer_elapsed%s", l->getId(), (fixedTimerStyle ? StringPrintfW(L".%s", this->getId()) : L"")), elapsed);
+ else elapsed = WASABI_API_CONFIG->getIntPrivate(L"timer_elapsed", elapsed);
+ }
+ else elapsed = WASABI_API_CONFIG->getIntPrivate(L"timer_elapsed", elapsed);
+
+#endif
+ setTimer(TICKER_TIMER_POS, 250);
+ setTimeTTS(TTS_DELAY / 250);
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ timerCallback(TICKER_TIMER_POS);
+ break;
+#endif
+#ifdef WASABI_WIDGETS_COMPBUCK
+ case DISPLAY_CB:
+ setTimer(TICKER_TIMER_POS, 50);
+ setTimeTTS(TTS_DELAY / 50);
+ postDeferredCallback(DISPLAY_CB, 0);
+ break;
+#endif
+ case DISPLAY_SERVICE:
+ registerToTextFeedService();
+ break;
+ break;
+ }
+}
+
+int Text::onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+#ifdef WASABI_WIDGETS_COMPBUCK
+ switch (p1)
+ {
+ case DISPLAY_CB:
+ if (mycbid.getNumItems() == 0)
+ ComponentBucket2::registerText(this);
+ else
+ for (int i = 0;i < mycbid.getNumItems();i++)
+ ComponentBucket2::registerText(this, mycbid.enumItem(i)->getValue());
+ return 0;
+ }
+#endif
+ return TEXT_PARENT::onDeferredCallback(p1, p2);
+}
+
+void Text::setShadowColor(COLORREF c, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ shadowcolor_mode[alt] = COLORMODE_RGB;
+ shadowcolor[alt].setColor(c);
+ invalidateTextBuffer();
+ if (alt == 0) setShadowColor(c, 1);
+}
+
+void Text::setShadowX(int x, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ shadowx[alt] = x;
+ invalidateTextBuffer();
+ if (alt == 0) setShadowX(x, 1);
+}
+
+void Text::setShadowY(int y, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ shadowy[alt] = y;
+ invalidateTextBuffer();
+ if (alt == 0) setShadowY(y, 1);
+}
+
+void Text::getBufferPaintSize(int *w, int *h)
+{
+ RECT r;
+ getClientRect(&r);
+ int _w = r.right - r.left;
+ int _h = r.bottom - r.top;
+
+ if (bufferinvalid)
+ {
+ cachedsizew = getPreferences(SUGGESTED_W);
+ }
+
+ if (w) *w = MAX(_w, cachedsizew);
+ if (h) *h = _h;
+}
+
+void Text::getBufferPaintSource(RECT *r)
+{
+ if (r)
+ {
+ RECT cr;
+ getClientRect(&cr);
+ r->left = textpos;
+ r->right = cr.right - cr.left + textpos;
+ r->top = 0;
+ r->bottom = cr.bottom - cr.top;
+ }
+}
+
+#include <bfc/util/profiler.h>
+
+// this is a temporary buffer, it should not be painted over with the painting alpha value, since it is going
+// to be hanled in the actual blit by our ancestor
+int Text::onBufferPaint(BltCanvas *canvas, int _w, int _h)
+{
+ int h, x, y=0;
+
+ TEXT_PARENT::onBufferPaint(canvas, _w, _h);
+
+ if (bufferinvalid)
+ {
+ cachedsizew = getPreferences(SUGGESTED_W);
+
+ StringW thaname = getPrintedText();
+
+ if (thaname.isempty())
+ {
+ RECT r = {0, 0, _w, _h};
+ canvas->fillRect(&r, RGB(0, 0, 0));
+ }
+ onTextChanged(thaname); // don't remove, skipped if unnecessary
+
+ switch(wantTranslation())
+ {
+ case 1:
+ thaname = _(thaname);
+ break;
+ case 2:
+ thaname = __(thaname);
+ break;
+ }
+
+ int alt = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ if (item != NULL)
+ {
+ alt = item->getDataAsInt(L"Alternate Fonts", 0);
+ if (alt < 0 || alt > 1) alt = 0;
+ }
+ if (alt)
+ {
+ if (item && item->getDataAsInt(L"No 7-bit TTF AltFonts", 1))
+ {
+ const wchar_t *p = (const wchar_t *)thaname.getValue();
+ while (p && *p)
+ {
+ if (*p > 127) break;
+ p++;
+ }
+ if (p && !*p) alt = 0;
+ }
+ }
+#endif
+
+ // canvas may have changed because of onTextChanged !
+ canvas = render_canvas;
+ canvas->getDim(&_w, &_h, NULL);
+
+ RECT r = {0, 0, _w, _h};
+
+ canvas->fillRect(&r, RGB(0, 0, 0));
+
+ if (forceupcase)
+ CharUpperW(thaname.getNonConstVal());
+ if (forcelocase)
+ CharLowerW(thaname.getNonConstVal());
+
+ wchar_t secs[256] = {0};
+ wchar_t mins[256] = {0};
+ wchar_t hours[256] = {0};
+
+ Wasabi::FontInfo fontInfo;
+ GetFontInfo(&fontInfo, alt);
+
+ const wchar_t *p = wcschr(thaname, L':');
+
+ if (display != DISPLAY_TIME || !p)
+ {
+ int wantpadding = 0;
+ int w = canvas->getTextWidth(thaname, &fontInfo);
+ if (w <= r.right - r.left - 2 - lpadding - rpadding)
+ {
+ // if text is wider than area, don't try to align it or it'll screw up the scroll
+ if (fontInfo.alignFlags != DT_CENTER) wantpadding = 1;
+ }
+ else
+ {
+ fontInfo.alignFlags = STDFONT_LEFT;
+ wantpadding = 1;
+ }
+ h = canvas->getTextHeight(thaname, &fontInfo);
+ x = r.left + 2 /*-textpos*/;
+ if (wantpadding)
+ x += lpadding;
+ switch (valign[alt])
+ {
+ case ALIGN_CENTER:
+ y = r.top + ((r.bottom - r.top - h) / 2);
+ break;
+ case ALIGN_TOP:
+ y = r.top;
+ break;
+ }
+ x += offsetx;
+ y += offsety;
+ cur_len = 0;
+ PathParserW pp(thaname, L"\t");
+ for (int i = 0; i < pp.getNumStrings(); i++)
+ {
+ if (i > 0)
+ fontInfo.alignFlags = ALIGN_RIGHT;
+
+ if (shadowx[alt] != 0 || shadowy[alt] != 0)
+ {
+ fontInfo.color = getShadowColor(alt);
+ if (wrapped)
+ canvas->textOutWrapped(x + shadowx[alt], y + shadowy[alt], r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo);
+ else
+ canvas->textOut(x + shadowx[alt], y + shadowy[alt], r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo);
+ fontInfo.color = GetColor(alt);
+ }
+ if (wrapped)
+ canvas->textOutWrapped(x, y, r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo);
+ else
+ canvas->textOut(x, y, r.right - r.left - 2 /*+textpos*/, r.bottom - r.top, pp.enumString(i), &fontInfo);
+ cur_len = canvas->getTextWidth(pp.enumString(i), &fontInfo) + (wantpadding ? (lpadding + rpadding) : 0);
+ }
+ }
+ else
+ {
+ if(timerhours)
+ {
+ WCSCPYN(hours, thaname, (p - thaname)+1);
+ const wchar_t* p2 = wcschr(p + 1, L':');
+ WCSCPYN(mins, p + 1, (p2 - p));
+ if(p2 && *(p2 + 1))
+ wcsncpy(secs, p2 + 1, 256);
+ else
+ {
+ wcsncpy(secs, mins, 256);
+ wcsncpy(mins, hours, 256);
+ hours[0] = 0;
+ }
+ }
+ else
+ {
+ WCSCPYN(mins, thaname, (p - thaname)+1);
+ wcsncpy(secs, p + 1, 256);
+ }
+
+ h = canvas->getTextHeight(thaname, &fontInfo);
+ int fixw = canvas->getTextWidth(L"0", &fontInfo);
+ int _ws = forcefixed ? fixw * wcslen(secs) : canvas->getTextWidth(secs, &fontInfo);
+ int _wm = forcefixed ? fixw * wcslen(mins) : canvas->getTextWidth(mins, &fontInfo);
+ int _wh = forcefixed ? fixw * wcslen(hours) : canvas->getTextWidth(hours, &fontInfo);
+ int _wc = forcefixed ? fixw * wcslen(L":") : canvas->getTextWidth(L":", &fontInfo);
+ wchar_t widthchar = forcefixed ? '0' : 0;
+ if (fontInfo.alignFlags == ALIGN_RIGHT)
+ {
+ x = (r.right - 2) - shadowx[alt] - rpadding;
+ switch (valign[alt])
+ {
+ case ALIGN_CENTER:
+ y = r.top + ((r.bottom - r.top - h) / 2);
+ break;
+ case ALIGN_TOP:
+ y = r.top;
+ break;
+ }
+ x += offsetx;
+ y += offsety;
+ if (shadowx[alt] != 0 || shadowy[alt] != 0)
+ {
+ fontInfo.color = getShadowColor(alt);
+ textOut(canvas, x - _ws, y, secs, widthchar, &fontInfo);
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo);
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm, y, mins, widthchar, &fontInfo);
+ if(timerhours && hours[0])
+ {
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo);
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc) - _wh, y, hours, widthchar, &fontInfo);
+ }
+ fontInfo.color = GetColor(alt);
+ }
+
+ x += shadowx[alt]; y += shadowy[alt];
+ textOut(canvas, x - _ws, y, secs, widthchar, &fontInfo);
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo);
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm, y, mins, widthchar, &fontInfo);
+ if(timerhours && hours[0])
+ {
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc), y, L":", widthchar, &fontInfo);
+ textOut(canvas, x - _ws - getTimeColonWidth(_wc) - _wm - getTimeColonWidth(_wc) - _wh, y, hours, widthchar, &fontInfo);
+ }
+ }
+ else if (fontInfo.alignFlags == ALIGN_LEFT)
+ {
+ x = (r.left + 2) - shadowx[alt] + lpadding;
+ switch (valign[alt])
+ {
+ case ALIGN_CENTER:
+ y = r.top + ((r.bottom - r.top - h) / 2);
+ break;
+ case ALIGN_TOP:
+ y = r.top;
+ break;
+ }
+ x += offsetx;
+ y += offsety;
+ if (shadowx != 0 || shadowy != 0)
+ {
+ fontInfo.color = getShadowColor(alt);
+ if(timerhours && hours[0])
+ {
+ textOut(canvas, x, y, hours, widthchar, &fontInfo);
+ textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ else
+ {
+ textOut(canvas, x, y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ fontInfo.color = GetColor(alt);
+
+ }
+ x += shadowx[alt]; y += shadowy[alt];
+ if(timerhours && hours[0])
+ {
+ textOut(canvas, x, y, hours, widthchar, &fontInfo);
+ textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ else{
+ textOut(canvas, x, y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ }
+ else if (fontInfo.alignFlags == ALIGN_CENTER)
+ {
+ if(timerhours && hours[0])
+ x = (r.left + ((r.right - r.left - _ws - _wm - _wh - getTimeColonWidth(_wc)) / 3)) - shadowx[alt];
+ else
+ x = (r.left + ((r.right - r.left - _ws - _wm - getTimeColonWidth(_wc)) / 2)) - shadowx[alt];
+ switch (valign[alt])
+ {
+ case ALIGN_CENTER:
+ y = r.top + ((r.bottom - r.top - h) / 2);
+ break;
+ case ALIGN_TOP:
+ y = r.top;
+ break;
+ }
+ x += offsetx;
+ y += offsety;
+ if (shadowx[alt] != 0 || shadowy[alt] != 0)
+ {
+ fontInfo.color = getShadowColor(alt);
+ if(timerhours && hours[0])
+ {
+ textOut(canvas, x, y, hours, widthchar, &fontInfo);
+ textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ else{
+ textOut(canvas, x, y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ fontInfo.color = GetColor(alt);
+ }
+ x += shadowx[alt]; y += shadowy[alt];
+ if(timerhours && hours[0])
+ {
+ textOut(canvas, x, y, hours, widthchar, &fontInfo);
+ textOut(canvas, x + _wh, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc), y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wh + getTimeColonWidth(_wc) + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ else{
+ textOut(canvas, x, y, mins, widthchar, &fontInfo);
+ textOut(canvas, x + _wm, y, L":", widthchar, &fontInfo);
+ textOut(canvas, x + _wm + getTimeColonWidth(_wc), y, secs, widthchar, &fontInfo);
+ }
+ }
+ cur_len = _ws + _wm + getTimeColonWidth(_wc);
+ }
+
+ bufferinvalid = 0;
+ }
+
+ // alpha is taken care of in our bufferpaintwnd
+ return 1;
+}
+
+void Text::timerCallback(int id)
+{
+ int upd = 0;
+ if (id == TIMER_SKIPCFG)
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
+ if (item != NULL)
+ {
+ float f = (float)item->getDataAsFloat(L"Text Ticker Speed", 1.0f / 2.0f);
+ skipn = (int)((1.0f / f) - 1 + 0.5f);
+ }
+#endif
+
+ }
+ if (id == TICKER_RESET_ALTNAME)
+ {
+ killTimer(id);
+ setAlternateName(NULL);
+ }
+
+ if (getAlternateName() == NULL || !*getAlternateName())
+ {
+
+ if (id == TICKER_TIMER_POS)
+ {
+
+#ifdef WASABI_COMPILE_MEDIACORE
+
+ wchar_t txt[4096] = {0};
+
+ // TODO: Change the way to get the current status text
+ switch (display)
+ {
+#ifdef WASABI_COMPILE_METADB
+ case DISPLAY_SONGALBUM:
+ {
+ const char *cur = WASABI_API_CORE->core_getCurrent(0);
+ if (cur && (WASABI_API_METADB->metadb_getMetaData(cur, MT_ALBUM, txt, 4095, MDT_STRINGZ)))
+ {
+ if (!lastText.getValue() || STRCMP(txt, lastText.getValue()))
+ {
+ upd = 1;
+ setName(txt);
+ }
+ }
+ if (upd)
+ {
+ lastText = txt;
+ resetTicker();
+ }
+ }
+ break;
+#endif
+ case DISPLAY_SONGLENGTH:
+ {
+ int len = -1;
+#ifdef WASABI_COMPILE_METADB
+ const char *cur = WASABI_API_CORE->core_getCurrent(0);
+ if (cur && (WASABI_API_METADB->metadb_getMetaData(cur, MT_LENGTH, (char *)&len, 4, MDT_TIME)) && len != -1)
+ {
+#else
+ len = WASABI_API_MEDIACORE->core_getLength(0);
+ if (len != -1)
+ {
+#endif
+ if (timerhours)
+ TimeFmt::printHourMinSec(len / 1000, txt, 4096, timerhoursRollover);
+ else
+ TimeFmt::printMinSec(len / 1000, txt, 4096);
+
+ if (!lastText.getValue() || wcscmp(txt, lastText.getValue()))
+ {
+ upd = 1;
+ setName(txt);
+ }
+ }
+ if (upd)
+ {
+ lastText = txt;
+ resetTicker();
+ }
+ }
+ break;
+#ifdef WASABI_COMPILE_METADB
+ case DISPLAY_SONGARTIST:
+ {
+ const char *cur = WASABI_API_CORE->core_getCurrent(0);
+ if (cur && (WASABI_API_METADB->metadb_getMetaData(cur, MT_ARTIST, txt, 4095, MDT_STRINGZ)))
+ {
+ if (!lastText.getValue() || STRCMP(txt, lastText.getValue()))
+ {
+ upd = 1;
+ setName(txt);
+ }
+ }
+ if (upd)
+ {
+ lastText = txt;
+ resetTicker();
+ }
+ }
+ break;
+#endif
+
+
+ case DISPLAY_SONGNAME:
+
+ case DISPLAY_SONGTITLE:
+ {
+ WCSCPYN(txt, WASABI_API_MEDIACORE->core_getTitle(0), 4096);
+ {
+ if (showlen)
+ {
+ int length = wa2.getLength();
+ if (length != 0 && length != -1)
+ {
+ length /= 1000;
+ if (wcslen(txt) < 4095 - 25)
+ wcscat(txt, StringPrintfW(L" (%d:%02d)", length / 60, length % 60));
+ }
+ }
+
+ if (!lastText.getValue() || wcscmp(txt, lastText.getValue()))
+ {
+ upd = 1;
+ setName(txt);
+ }
+ }
+ if (upd)
+ {
+ lastText = txt;
+ resetTicker();
+ }
+ }
+ break;
+ case DISPLAY_TIME:
+ {
+ int cp = WASABI_API_MEDIACORE->core_getPosition(0);
+ if (cp < 0)
+ {
+ switch (timeroffstyle)
+ {
+ case 0:
+ wcsncpy(txt, L" : ", 4096);
+ break;
+ case 1:
+ StringCbPrintfW(txt, sizeof(txt), L"%s00:00", elapsed ? L"" : L"-");
+ break;
+ case 2:
+ *txt = 0;
+ break;
+ case 3:
+ StringCbPrintfW(txt, sizeof(txt), L"%s0:00:00", elapsed ? L"" : L"-");
+ break;
+ case 4:
+ wcsncpy(txt, L" : : ", 4096);
+ break;
+ }
+ }
+ else
+ {
+ int p;
+ int len = WASABI_API_MEDIACORE->core_getLength(0);
+ int el = elapsed;
+ if (len == -1000 || el == -1)
+ el = 1; // no remaining time on http streams, etc...
+ if (el)
+ p = cp / 1000;
+ else
+ p = (len - cp) / 1000;
+ if (!el) p = -p;
+ if (timerhours)
+ TimeFmt::printHourMinSec(p, txt, 4096, timerhoursRollover);
+ else
+ TimeFmt::printMinSec(p, txt, 4096);
+ }
+ if (!lastText.getValue() || wcscmp(txt, lastText.getValue()))
+ {
+ setName(txt);
+ upd = 1;
+ lastText = txt;
+ }
+ }
+ break;
+ }
+ int u = 0;
+ advanceTicker(&u);
+ if (u) invalidateBuffer();
+#endif
+
+ }
+ else
+ {
+ TEXT_PARENT::timerCallback(id);
+ }
+ }
+
+ if (upd)
+ {
+ invalidateTextBuffer();
+ }
+}
+
+void Text::advanceTicker(int *upd)
+{
+ // update tts stuff
+ if (ticker && !grab && isVisible())
+ {
+ int oldpos = textpos;
+ RECT re = clientRect();
+ if (cur_len < (re.right - re.left - 2)) textpos = 0;
+ else if (tts > 0) tts -= (timerclient_getSkipped() + 1);
+ else
+ {
+ if (skip < skipn) skip++;
+ else
+ {
+ skip = 0;
+ if (!sens) textpos += tickerstep * (timerclient_getSkipped() + 1); else textpos -= tickerstep * (timerclient_getSkipped() + 1);
+ if (textpos < 0) textpos = 0;
+ if (textpos > cur_len - (re.right - re.left - 2)) textpos = cur_len - (re.right - re.left - 2);
+ if (cur_len <= (textpos + re.right - re.left - 2))
+ {
+ sens = 1;
+ tts = time_tts;
+ }
+ if (textpos <= 0)
+ {
+ sens = 0;
+ textpos = 0;
+ tts = time_tts;
+ }
+ }
+ }
+ if (textpos != oldpos && upd != NULL) *upd = 1;
+ }
+}
+
+void Text::setTimeDisplayMode(int remaining)
+{
+ if (fixedTimerStyle)
+ return;
+
+ elapsed = !remaining;
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l && l->getId())
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"%s/timer_elapsed", l->getId()), elapsed);
+ else
+ WASABI_API_CONFIG->setIntPrivate(L"timer_elapsed", elapsed);
+ invalidateTextBuffer();
+}
+
+int Text::onLeftButtonDown(int x, int y)
+{
+ if (!TEXT_PARENT::onLeftButtonDown(x, y))
+ {
+ grab = 0;
+ return 0;
+ }
+ if (nograb || wrapped) return 0;
+ if (display == DISPLAY_TIME)
+ {
+ elapsed = !elapsed;
+#ifdef WIN32
+ // HACK! lone needs to make that a cfg attrib, but no time, a build needs to go out :D
+#define WINAMP_OPTIONS_ELAPSED 40037
+#define WINAMP_OPTIONS_REMAINING 40038
+ if (!fixedTimerStyle) SendMessageW(WASABI_API_WND->main_getRootWnd()->gethWnd(), WM_COMMAND, elapsed ? WINAMP_OPTIONS_ELAPSED : WINAMP_OPTIONS_REMAINING, 0);
+#endif
+#ifdef WASABI_COMPILE_WNDMGR
+#ifdef WASABI_COMPILE_CONFIG
+ if (getGuiObject())
+ {
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l && l->getId()) WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"%s/timer_elapsed%s", l->getId(), (fixedTimerStyle ? StringPrintfW(L".%s", this->getId()) : L"")), elapsed);
+ else WASABI_API_CONFIG->setIntPrivate(L"timer_elapsed", elapsed);
+ }
+ else WASABI_API_CONFIG->setIntPrivate(L"timer_elapsed", elapsed);
+#endif
+#endif
+ timerCallback(TICKER_TIMER_POS);
+ return 1;
+ }
+
+ grab = 1;
+ grab_x = x + textpos;
+ // onMouseMove(x,y);
+ return 1;
+}
+
+int Text::onMouseMove(int x, int y)
+{
+
+ if (!TEXT_PARENT::onMouseMove(x, y))
+ {
+ grab = 0;
+ }
+
+ //POINT pos = {x, y};
+ //clientToScreen(&pos);
+
+ if (!grab) return 1;
+
+ textpos = grab_x - x;
+
+ RECT re;
+ getClientRect(&re);
+ textpos = min(textpos, cur_len - ((re.right - re.left) - 2) - 1);
+ if (textpos < 0) textpos = 0;
+ invalidateBuffer();
+ return 1;
+}
+
+int Text::onLeftButtonUp(int x, int y)
+{
+ if (!TEXT_PARENT::onLeftButtonUp(x, y))
+ {
+ grab = 0;
+ return 0;
+ }
+ if (nograb) return 0;
+ grab = 0;
+ tts = time_tts;
+ return 1;
+}
+
+
+#ifdef WASABI_COMPILE_MEDIACORE
+int Text::corecb_onStatusMsg(const wchar_t *text)
+{
+ if (display == DISPLAY_SONGNAME)
+ setAlternateName(text);
+ return 0;
+}
+
+int Text::corecb_onBitrateChange(int kbps)
+{
+ if (display == DISPLAY_SONGBITRATE)
+ {
+ if (kbps)
+ {
+ wchar_t bitrate[64] = {0};
+ WCSNPRINTF(bitrate, 64, L"%d", kbps);
+ setName(bitrate);
+ }
+ else
+ setName(L"");
+
+ }
+ return 0;
+}
+
+int Text::corecb_onSampleRateChange(int hz)
+{
+ if (display == DISPLAY_SONGSAMPLERATE)
+ {
+ if (hz)
+ {
+ wchar_t sampleRate[64] = {0};
+ WCSNPRINTF(sampleRate, 64, L"%d", hz);
+ setName(sampleRate);
+ }
+ else
+ setName(L"");
+
+ }
+ return 0;
+}
+
+int Text::corecb_onInfoChange(const wchar_t *text)
+{
+ switch (display)
+ {
+ case DISPLAY_SONGINFO:
+ case DISPLAY_SONGINFO_TRANSLATED:
+ setName(text);
+ break;
+ case DISPLAY_TIME:
+ timerCallback(TICKER_TIMER_POS);
+ break;
+ }
+ return 0;
+}
+
+int Text::corecb_onStopped()
+{
+ switch (display)
+ {
+ case DISPLAY_SONGINFO:
+ case DISPLAY_SONGINFO_TRANSLATED:
+ case DISPLAY_SONGBITRATE:
+ case DISPLAY_SONGSAMPLERATE:
+ setName(L"");
+ break;
+ case DISPLAY_TIME:
+ timerCallback(TICKER_TIMER_POS);
+ break;
+ }
+ return 0;
+}
+
+int Text::corecb_onStarted()
+{
+ /* if (display == DISPLAY_TIME) {
+ timerCallback(TICKER_TIMER_POS);
+ }*/
+ return 0;
+}
+
+int Text::corecb_onSeeked(int newpos)
+{
+ if (display == DISPLAY_TIME)
+ timerCallback(TICKER_TIMER_POS);
+ return 0;
+}
+
+#endif //mediacore
+
+void Text::invalidateTextBuffer()
+{
+ bufferinvalid = 1;
+ invalidateBuffer();
+}
+
+int Text::setTextSize(int newsize, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ if (newsize < 1 || newsize > 72) return 0;
+ size[alt] = newsize;
+ invalidateTextBuffer();
+ return 1;
+}
+
+void Text::setTickering(int enable)
+{
+ ticker = enable;
+ if (!enable) textpos = 0;
+ invalidateTextBuffer();
+}
+
+void Text::setDisplay(int disp)
+{
+ if (disp == display) return ;
+ if (textfeed)
+ {
+ viewer_delViewItem(textfeed->getDependencyPtr());
+ feed_id = L"";
+ SvcEnum::release(textfeed);
+ textfeed = NULL;
+ }
+ display = disp;
+ if (isPostOnInit()) initDisplay();
+ if (disp == DISPLAY_SERVICE && isPostOnInit())
+ registerToTextFeedService();
+ invalidateTextBuffer();
+}
+
+void Text::setAlternateName(const wchar_t *s)
+{
+ if (((!s || !*s) && alternatename.isempty()) || WCSCASEEQLSAFE(alternatename, s)) return ;
+ killTimer(TICKER_RESET_ALTNAME);
+ alternatename = parseText(s);
+ onTextChanged(getPrintedText());
+ resetTicker();
+ invalidate();
+ setTimer(TICKER_RESET_ALTNAME, 1000);
+}
+
+void Text::setText(const wchar_t *t)
+{
+ deftext = parseText(t);
+ invalidate();
+ onTextChanged(getPrintedText());
+}
+
+const wchar_t *Text::parseText(const wchar_t *s)
+{
+ static wchar_t t[4096];
+ if (!s) return NULL;
+ WCSCPYN(t, s, 4096);
+ wchar_t *p = t;
+ while (p && *p && *(p + 1))
+ {
+ if (*p == '\\' && *(p + 1) == 'n')
+ {
+ // TODO check
+ wcscpy(p, p + 1);
+ t[wcslen(t)] = 0;
+ *p = '\n';
+ }
+ p++;
+ }
+ return t;
+}
+
+void Text::onTextChanged(const wchar_t *txt)
+{
+ if (WCSCASEEQLSAFE(lasttxt, txt)) return ;
+ lasttxt = txt;
+ invalidate();
+ int w = getTextWidth();
+ if (w != lastautowidth)
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ lastautowidth = w;
+ script_vcpu_onTextChanged(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(lasttxt));
+ invalidateTextBuffer();
+}
+
+const wchar_t *Text::getPrintedText()
+{
+ const wchar_t *name = getAlternateName();
+ if (!name || !*name)
+ name = deftext.getValue();
+ if (!name || !*name)
+ name = getName();
+ if (name == NULL)
+ return L"";
+
+#if defined(WASABI_STATICVARMGR) || !defined(WASABINOMAINAPI)
+
+ if (wantTranslation())
+ {
+ StringW *s = PublicVarManager::translate(name, getGuiObject());
+ if (s != NULL)
+ {
+ printedtxt.swap(s);
+ delete s;
+ return printedtxt.getValueSafe();
+ }
+ }
+
+ return name;
+#else
+ return name;
+
+#endif
+}
+
+void Text::onSetName()
+{
+ invalidateTextBuffer();
+ onTextChanged(getPrintedText());
+}
+
+const wchar_t *Text::getAlternateName(void)
+{
+ if (alternatename.isempty()) return NULL;
+ return alternatename;
+}
+
+void Text::setTimerOffStyle(int o)
+{
+ if (timeroffstyle == o) return ;
+ timeroffstyle = o;
+ invalidateTextBuffer();
+}
+
+void Text::setTimerHours(int o)
+{
+ if (timerhours == o) return ;
+ timerhours = o;
+ invalidateTextBuffer();
+}
+
+void Text::setTimerHoursRollover(int o)
+{
+ if (timerhoursRollover == o) return ;
+ timerhoursRollover = o;
+ invalidateTextBuffer();
+}
+
+void Text::setTimeTTS(int tts)
+{
+ time_tts = tts;
+ invalidateTextBuffer();
+}
+
+void Text::resetTicker()
+{
+ sens = 0;
+ textpos = 0;
+ tts = time_tts;
+ invalidateBuffer();
+}
+
+void Text::setTimeColonWidth(int w)
+{
+ timecolonw = w;
+ invalidateTextBuffer();
+}
+
+int Text::getTimeColonWidth(int def)
+{
+ return timecolonw == -1 ? def : timecolonw;
+}
+
+void Text::textOut(Canvas *canvas, int x, int y, const wchar_t *txt, wchar_t widthchar, const Wasabi::FontInfo *fontInfo)
+{
+ if (widthchar == 0)
+ {
+ canvas->textOut(x, y, txt, fontInfo);
+ return ;
+ }
+ wchar_t wc[2] = { widthchar, 0 };
+ int cwidth = canvas->getTextWidth(wc, fontInfo);
+ int slen = wcslen(txt);
+
+ for (int i = 0; i < slen; i++)
+ {
+ wc[0] = txt[i];
+ int dw = cwidth - canvas->getTextWidth(wc, fontInfo); // get difference
+ canvas->textOut(x + dw / 2, y, wc, fontInfo);
+ x += cwidth;
+ }
+}
+
+void Text::addCBSource(const wchar_t *cbsource)
+{
+ StringW *s = new StringW(cbsource);
+ mycbid.addItem(s);
+}
+
+int Text::getTextWidth()
+{
+ const wchar_t *txt = getAlternateName() ? getAlternateName() : isInited() ? getName() : NULL;
+ if (!txt) txt = deftext.getValue();
+ if (!txt) return 0;
+#ifdef WA3COMPATIBILITY
+ /*
+ String *translate = PublicVarManager::translate(thaname, getGuiObject());
+ if (translate)
+ thanme = translate->getValueSafe();
+ */
+#endif
+ //txt = _(txt);
+ int alt = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *item = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ if (item != NULL)
+ {
+ alt = item->getDataAsInt(L"Alternate Fonts", 0);
+ if (alt < 0 || alt > 1) alt = 0;
+ }
+ if (alt)
+ {
+ if (item && item->getDataAsInt(L"No 7-bit TTF AltFonts", 1))
+ {
+ const wchar_t *p = (const wchar_t *)txt;
+ while (p && *p)
+ {
+ if (*p > 127) break;
+ p++;
+ }
+ if (p && !*p) alt = 0;
+ }
+ }
+#endif
+ TextInfoCanvas canvas(this);
+ Wasabi::FontInfo fontInfo;
+ GetFontInfo(&fontInfo, alt);
+ int w = canvas.getTextWidth(txt, &fontInfo) + 4;
+// delete txt;
+ return w;
+}
+
+void Text::registerToTextFeedService()
+{
+ if (!registered_syscb++) WASABI_API_SYSCB->syscb_registerCallback(static_cast<SvcCallbackI*>(this));
+
+ if (textfeed)
+ {
+ viewer_delViewItem(textfeed->getDependencyPtr());
+ feed_id = L"";
+ SvcEnum::release(textfeed);
+ textfeed = NULL;
+ }
+
+ if (!displaystr.isempty()) textfeed = TextFeedEnum(displaystr).getFirst();
+
+ if (textfeed != NULL)
+ {
+ feed_id = displaystr;
+ viewer_addViewItem(textfeed->getDependencyPtr());
+ }
+}
+
+void Text::svccb_onSvcRegister(FOURCC type, waServiceFactory *svc)
+{
+ if (type == WaSvc::TEXTFEED)
+ {
+ //CUTif (!displaystr.isempty()) {
+ //CUTDebugString("RERERERER %s", displaystr.v());
+ //CUT}
+ registerToTextFeedService();
+ }
+}
+
+int Text::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (textfeed && item == textfeed->getDependencyPtr())
+ {
+ if (event == svc_textFeed::Event_TEXTCHANGE && WCSCASEEQLSAFE((const wchar_t *)param, feed_id))
+ {
+ //CUTDebugString("got feed '%s'", (const char *)ptr);
+ setName((const wchar_t *)ptr);
+ return 1;
+ }
+ }
+
+ else if (classguid && *classguid == *Container::depend_getClassGuid())
+ {
+ onSetName();
+ return 1;
+ }
+ return 0;
+}
+
+int Text::triggerEvent(int event, intptr_t p1, intptr_t p2)
+{
+ int r = TEXT_PARENT::triggerEvent(event, p1, p2);
+ if (event == TRIGGER_ONRESIZE)
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ if (event == TRIGGER_INVALIDATE)
+ invalidateTextBuffer();
+ return r;
+}
+
+COLORREF Text::getShadowColor(int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ if (shadowcolor_mode[alt] == COLORMODE_SKINCOLOR) return sshadowcolor[alt];
+ return shadowcolor[alt].getColor();
+}
+
+TextScriptController _textController;
+TextScriptController *textController = &_textController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct TextScriptController::exportedFunction[] =
+{
+ {L"setText", 1, (void*)Text::script_vcpu_setText },
+ {L"setAlternateText", 1, (void*)Text::script_vcpu_setAlternateText },
+ {L"getText", 0, (void*)Text::script_vcpu_getText },
+ {L"getTextWidth", 0, (void*)Text::script_vcpu_getTextWidth },
+ {L"onTextChanged", 1, (void*)Text::script_vcpu_onTextChanged },
+};
+// --------------------------------------------------------
+
+const wchar_t *TextScriptController::getClassName()
+{
+ return L"Text";
+}
+
+const wchar_t *TextScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *TextScriptController::instantiate()
+{
+ Text *t = new Text;
+ ASSERT(t != NULL);
+ return t->getScriptObject();
+}
+
+void TextScriptController::destroy(ScriptObject *o)
+{
+ Text *t = static_cast<Text *>(o->vcpu_getInterface(textGuid));
+ ASSERT(t != NULL);
+ delete t;
+}
+
+void *TextScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for text yet
+}
+
+void TextScriptController::deencapsulate(void *o)
+{}
+
+int TextScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *TextScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID TextScriptController::getClassGuid()
+{
+ return textGuid;
+}
+
+const wchar_t *Text::vcpu_getClassName()
+{
+ return L"Text";
+}
+
+scriptVar Text::script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(t.type == SCRIPT_STRING);
+ Text *tx = static_cast<Text *>(o->vcpu_getInterface(textGuid));
+ if (tx) tx->setText(GET_SCRIPT_STRING(t));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Text::script_vcpu_setAlternateText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(t.type == SCRIPT_STRING);
+ Text *tx = static_cast<Text *>(o->vcpu_getInterface(textGuid));
+ if (tx) tx->setAlternateName(GET_SCRIPT_STRING(t));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Text::script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Text *t = static_cast<Text *>(o->vcpu_getInterface(textGuid));
+ if (t)
+ {
+ const wchar_t *from = t->getPrintedText();
+ // BU rewrote in response to talkback for 489
+ if (from == NULL || *from == '\0') from = t->getLastText();
+ if (from == NULL || *from == '\0') from = L"";
+ WCSCPYN(s_txt, from, 4096);
+ return MAKE_SCRIPT_STRING(s_txt);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Text::script_vcpu_getTextWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Text *t = static_cast<Text *>(o->vcpu_getInterface(textGuid));
+ if (t) return MAKE_SCRIPT_INT(t->getTextWidth());
+ return MAKE_SCRIPT_INT(0);
+}
+
+scriptVar Text::script_vcpu_onTextChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newtxt)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, textController, newtxt);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newtxt);
+}
+
+wchar_t Text::s_txt[WA_MAX_PATH] = {0}; \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/text.h b/Src/Wasabi/api/skin/widgets/text.h
new file mode 100644
index 00000000..1435e8fa
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/text.h
@@ -0,0 +1,240 @@
+//PORTABLE
+#ifndef _TEXT_H
+#define _TEXT_H
+
+#include <api/script/script.h>
+#include <api/script/objects/guiobj.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/string/StringW.h>
+#include <bfc/depend.h>
+#include "textbase.h"
+#include <api/syscb/callbacks/svccbi.h>
+#include <api/syscb/callbacks/skincb.h>
+
+#define TEXT_PARENT TextBase
+
+class svc_textFeed;
+
+class TextScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern TextScriptController *textController;
+
+#include <api/wnd/wndclass/clickwnd.h>
+
+#ifdef WASABI_COMPILE_MEDIACORE
+#include <api/syscb/callbacks/corecbi.h>
+class Text : public TEXT_PARENT, public CoreCallbackI, public DependentViewerI, public SvcCallbackI{
+#else
+class Text : public TEXT_PARENT, public DependentViewerI, public SvcCallbackI {
+#endif
+public:
+ Text();
+ virtual ~Text();
+
+ virtual int onInit();
+ virtual int onBufferPaint(BltCanvas *canvas, int w, int h);
+
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onMouseMove(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+
+ virtual int getPreferences(int what);
+
+ virtual int setXuiParam(int xuihandle, int attribid, const wchar_t *name, const wchar_t *strval);
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return textController; }
+
+ virtual int getTextWidth();
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+
+ virtual void getBufferPaintSize(int *w, int *h);
+ virtual void getBufferPaintSource(RECT *r);
+ virtual void onNewBuffer(int w, int h) { BufferPaintWnd::onNewBuffer(w, h); invalidateTextBuffer(); }
+
+ int setTextSize(int newsize, int alt=0);
+ void setTickering(int enable);
+ void setDisplay(int disp);
+
+
+
+ void setShadowColor(ARGB32 c, int alt=0);
+ void setShadowX(int x, int alt=0); // relative offsets
+ void setShadowY(int y, int alt=0);
+ void setTimeTTS(int tts);
+ void resetTicker();
+ void setTimeColonWidth(int w);
+ int getTimeColonWidth(int def);
+ void setTimerOffStyle(int o);
+ void setTimerHours(int o);
+ void setTimerHoursRollover(int o);
+ const wchar_t *getLastText() { return lasttxt; }
+
+ void setAlternateName(const wchar_t *s);
+ const wchar_t *getAlternateName(void);
+ void setText(const wchar_t *t);
+
+ void addCBSource(const wchar_t *cbsource);
+
+ virtual void onTextChanged(const wchar_t *txt);
+ virtual void onSetName();
+ virtual void advanceTicker(int *upd);
+
+ virtual void setTimeDisplayMode(int remaining); // will only do so if text is displaying time in the first place
+
+ ARGB32 getShadowColor(int alt=0);
+
+#ifdef WASABI_COMPILE_MEDIACORE
+ // core callbacks
+ virtual int corecb_onStatusMsg(const wchar_t *text);
+ virtual int corecb_onInfoChange(const wchar_t *text);
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+ virtual int corecb_onSeeked(int newpos);
+ virtual int corecb_onBitrateChange(int kbps);
+ virtual int corecb_onSampleRateChange(int hz);
+#endif
+
+ static void textOut(Canvas *canvas, int x, int y, const wchar_t *txt, wchar_t widthchar, const Wasabi::FontInfo *fontInfo);
+
+ virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual int triggerEvent(int event, intptr_t p1, intptr_t p2);
+
+ const wchar_t *getPrintedText();
+
+ virtual void svccb_onSvcRegister(FOURCC type, waServiceFactory *svc);
+
+
+ void initDisplay();
+ void invalidateTextBuffer();
+
+ enum {
+ TEXT_SETDISPLAY=0,
+ TEXT_SETTICKER,
+ TEXT_SETTEXT,
+ TEXT_SETSHADOWCOLOR,
+ TEXT_SETALTSHADOWCOLOR,
+ TEXT_SETSHADOWX,
+ TEXT_SETSHADOWY,
+ TEXT_SETALTSHADOWX,
+ TEXT_SETALTSHADOWY,
+ TEXT_SETTIMEROFFSTYLE,
+ TEXT_SETTIMERHOURS,
+ TEXT_SETTIMECOLONWIDTH,
+ TEXT_SETNOGRAB,
+ TEXT_SETSHOWLEN,
+ TEXT_SETFORCEFIXED,
+ TEXT_SETFORCEUPCASE,
+ TEXT_SETFORCELOCASE,
+ TEXT_SETCBSOURCE,
+ TEXT_SETWRAPPED,
+ TEXT_SETVALIGN,
+ TEXT_SETALTVALIGN,
+ TEXT_SETDBLCLKACTION,
+ TEXT_SETRCLKACTION,
+ TEXT_SETOFFSETX,
+ TEXT_SETOFFSETY,
+ TEXT_SETTICKERSTEP,
+ TEXT_SETTIMERHOURSROLLOVER,
+ TEXT_NUMPARAMS,
+ };
+
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ virtual void timerCallback(int id);
+
+private:
+ static XMLParamPair params[];
+
+ const wchar_t *parseText(const wchar_t *s);
+ void registerToTextFeedService();
+ int size[2];
+ int textpos,tts,sens;
+ int time_tts;
+ int grab_x;
+ int cur_len;
+ int ticker;
+ int display;
+ int elapsed;
+ int fixedTimerStyle;
+
+ int nograb;
+ int showlen;
+ int forcefixed;
+ int timeroffstyle;
+
+ StringW displaystr;
+ StringW alternatename;
+ StringW lastText;
+
+ FilteredColor shadowcolor[2];
+
+ SkinColor sshadowcolor[2];
+ int shadowcolor_mode[2];
+ int shadowx[2], shadowy[2];
+ int timecolonw;
+ StringW deftext;
+
+
+
+ PtrList<StringW> mycbid;
+ StringW cbsource;
+ int forceupcase, forcelocase;
+ StringW lasttxt;
+
+
+ int lastautowidth;
+
+ svc_textFeed *textfeed;
+ StringW feed_id;
+ int registered_syscb;
+
+ int wrapped;
+ int valign[2];
+ int xuihandle;
+ int offsetx, offsety;
+
+ StringW printedtxt;
+ int tickerstep;
+ int skipn;
+ int skip;
+ int skipcfgcount;
+
+ int timerhours;
+ int timerhoursRollover;
+ int bufferinvalid;
+ int cachedsizew;
+
+public:
+ static scriptVar script_vcpu_setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t);
+ static scriptVar script_vcpu_setAlternateText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t);
+ static scriptVar script_vcpu_getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getTextWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onTextChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text);
+ static wchar_t s_txt[WA_MAX_PATH];
+};
+
+extern const wchar_t textXuiObjectStr[];
+extern char textXuiSvcName[];
+class TextXuiSvc : public XuiObjectSvc<Text, textXuiObjectStr, textXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/textbase.cpp b/Src/Wasabi/api/skin/widgets/textbase.cpp
new file mode 100644
index 00000000..5fb32e7a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/textbase.cpp
@@ -0,0 +1,345 @@
+#include <precomp.h>
+#include <api.h>
+#include "textbase.h"
+#include <api/skin/skinparse.h>
+#include <api/skin/skinelem.h>
+#include <api/service/svcs/svc_action.h>
+#include <api/script/vcpu.h>
+
+#define COLORMODE_RGB 0
+#define COLORMODE_SKINCOLOR 1
+
+XMLParamPair TextBase::params[] =
+{
+ {TEXTBASE_RCLICKPARAM, L"RCLICKPARAM"},
+ {TEXTBASE_DBLCLICKPARAM, L"DBLCLICKPARAM"},
+ {TEXTBASE_SETALIGN, L"ALIGN"},
+ {TEXTBASE_SETALTANTIALIAS, L"ALTANTIALIAS"},
+ {TEXTBASE_SETALTBOLD, L"ALTBOLD"},
+ {TEXTBASE_SETALTCOLOR, L"ALTCOLOR"},
+ {TEXTBASE_SETALTFONT, L"ALTFONT"},
+ {TEXTBASE_SETALTFONTSIZE, L"ALTFONTSIZE"},
+ {TEXTBASE_SETALTITALIC, L"ALTITALIC"},
+ {TEXTBASE_SETANTIALIAS, L"ANTIALIAS"},
+ {TEXTBASE_SETBOLD, L"BOLD"},
+ {TEXTBASE_SETCOLOR, L"COLOR"},
+ {TEXTBASE_SETDBLCLKACTION, L"DBLCLICKACTION"},
+ {TEXTBASE_SETFONT, L"FONT"},
+ {TEXTBASE_SETFONTSIZE, L"FONTSIZE"},
+ {TEXTBASE_SETITALIC, L"ITALIC"},
+ {TEXTBASE_SETLPADDING, L"LEFTPADDING"},
+ {TEXTBASE_SETRCLKACTION, L"RIGHTCLICKACTION"},
+ {TEXTBASE_SETRPADDING, L"RIGHTPADDING"},
+};
+
+TextBase::TextBase()
+{
+ color[0].setColorGroup(L"Text");
+ color[1].setColorGroup(L"Text");
+ color[0].setColor(RGB(255, 255, 255));
+ color[1].setColor(RGB(255, 255, 255));
+
+ color_mode[0] = COLORMODE_RGB;
+ color_mode[1] = COLORMODE_RGB;
+
+ fontsize[0] = fontsize[1] = 14;
+
+ font[0] = wasabi_default_fontnameW;
+ font[1] = wasabi_default_fontnameW;
+
+ bold[0] = 0;
+ bold[1] = 0;
+
+ italic[0] = 0;
+ italic[1] = 0;
+
+ antialias[0] = 1;
+ antialias[1] = 1;
+
+ align = ALIGN_LEFT;
+
+ lpadding = rpadding = 0;
+
+ grab = 0;
+
+ /* register XML parameters */
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void TextBase::CreateXMLParameters(int master_handle)
+{
+ //TEXTBASE_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+TextBase::~TextBase()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+}
+
+int TextBase::onInit()
+{
+ TEXTBASE_PARENT::onInit();
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+ return 1;
+}
+
+int TextBase::skincb_onColorThemeChanged(const wchar_t *newcolortheme)
+{
+ invalidateTextBuffer();
+ return 0;
+}
+
+
+ARGB32 TextBase::GetColor(int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ if (color_mode[alt] == COLORMODE_SKINCOLOR)
+ return scolor[alt];
+ return color[alt].getColor();
+}
+
+void TextBase::SetTextColor(ARGB32 c, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ color_mode[alt] = COLORMODE_RGB;
+ color[alt].setColor(c);
+ invalidateTextBuffer();
+ if (alt == 0) SetTextColor(c, 1);
+}
+
+void TextBase::SetFontSize(const wchar_t *strvalue, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ if (!strvalue || !*strvalue) return ;
+ if (*strvalue == '+')
+ fontsize[alt] += WTOI(strvalue + 1);
+ else if (*strvalue == '-')
+ fontsize[alt] -= WTOI(strvalue + 1);
+ else if (*strvalue == '*')
+ fontsize[alt] *= WTOI(strvalue + 1);
+ else if (*strvalue == '/')
+ fontsize[alt] /= WTOI(strvalue + 1);
+ else
+ fontsize[alt] = WTOI(strvalue);
+ invalidateTextBuffer();
+ if (alt == 0) SetFontSize(strvalue, 1);
+}
+
+void TextBase::GetFontInfo(Wasabi::FontInfo *_font, int alt)
+{
+ _font->opaque=false;
+ _font->color = GetColor(alt);
+ _font->pointSize = fontsize[alt];
+ _font->face = font[alt];
+ _font->bold = bold[alt];
+ _font->italic = !!italic[alt];
+ _font->antialias = antialias[alt];
+ _font->alignFlags = align;
+}
+
+void TextBase::SetFont(const wchar_t *name, int alt)
+{
+ if (alt < 0 || alt > 1) alt = 0;
+ font[alt] = name;
+ invalidateTextBuffer();
+ if (alt == 0) SetFont(name, 1);
+}
+
+void TextBase::SetAntialias(int a, int alt)
+{
+ antialias[alt] = a;
+ if (alt==0)
+ antialias[1] = antialias[0];
+ invalidateTextBuffer();
+}
+
+void TextBase::SetFontAlign(int al)
+{
+ align = al;
+ invalidateTextBuffer();
+
+}
+
+int TextBase::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval)
+{
+ if (xuihandle != _xuihandle) return TEXTBASE_PARENT::setXuiParam(_xuihandle, attrid, name, strval);
+ switch (attrid)
+ {
+ case TEXTBASE_SETCOLOR:
+ if (WASABI_API_PALETTE->getColorElementRef(strval))
+ {
+ color_mode[0] = COLORMODE_SKINCOLOR;
+ scolor[0] = strval;
+ color_mode[1] = COLORMODE_SKINCOLOR;
+ scolor[1] = strval;
+ }
+ else
+ SetTextColor(SkinParser::parseColor(strval), 0);
+ break;
+
+ case TEXTBASE_SETALTCOLOR:
+ if (WASABI_API_PALETTE->getColorElementRef(strval))
+ {
+ color_mode[1] = COLORMODE_SKINCOLOR;
+ scolor[1] = strval;
+ }
+ else
+ SetTextColor(SkinParser::parseColor(strval), 1);
+ break;
+
+ case TEXTBASE_SETFONTSIZE:
+ SetFontSize(strval);
+ break;
+
+ case TEXTBASE_SETFONT:
+ SetFont(strval);
+ break;
+
+ case TEXTBASE_SETALTFONT:
+ SetFont(strval, 1);
+ break;
+
+ case TEXTBASE_SETALTFONTSIZE:
+ SetFontSize(strval, 1);
+ break;
+
+ case TEXTBASE_SETBOLD:
+ bold[0] = WTOI(strval);
+ bold[1] = bold[0];
+ break;
+
+ case TEXTBASE_SETALTBOLD:
+ bold[1] = WTOI(strval);
+ break;
+
+ case TEXTBASE_SETITALIC:
+ italic[0] = WTOI(strval);
+ italic[1] = italic[0];
+ break;
+
+ case TEXTBASE_SETALTITALIC:
+ italic[1] = WTOI(strval);
+ break;
+
+ case TEXTBASE_SETANTIALIAS:
+ SetAntialias(WTOI(strval));
+ invalidateTextBuffer();
+ break;
+
+ case TEXTBASE_SETALTANTIALIAS:
+ SetAntialias(WTOI(strval), 1);
+ invalidateTextBuffer();
+ break;
+
+ case TEXTBASE_SETDBLCLKACTION:
+ dblClickAction = strval;
+ break;
+
+ case TEXTBASE_DBLCLICKPARAM:
+ setDblClickParam(strval);
+ break;
+
+ case TEXTBASE_RCLICKPARAM:
+ setRClickParam(strval);
+ break;
+
+ case TEXTBASE_SETRCLKACTION:
+ rClickAction = strval;
+ break;
+
+ case TEXTBASE_SETALIGN:
+ SetFontAlign(SkinParser::getAlign(strval));
+ break;
+
+ case TEXTBASE_SETLPADDING:
+ lpadding = WTOI(strval);
+ break;
+ case TEXTBASE_SETRPADDING:
+ rpadding = WTOI(strval);
+ break;
+
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void TextBase::setDblClickParam(const wchar_t *p)
+{
+ dblclickparam=p;
+}
+
+const wchar_t *TextBase::getDblClickParam()
+{
+ return dblclickparam;
+}
+
+void TextBase::setRClickParam(const wchar_t *p)
+{
+ rclickparam=p;
+}
+
+const wchar_t *TextBase::getRClickParam()
+{
+ return rclickparam;
+}
+
+int TextBase::onLeftButtonDblClk(int x, int y)
+{
+ TEXTBASE_PARENT::onLeftButtonDblClk(x, y);
+ int r = 1;
+ grab = 0;
+ if (!dblClickAction.isempty() && !VCPU::getComplete())
+ {
+#ifdef WASABI_COMPILE_WNDMGR
+ const wchar_t *toCheck = L"SWITCH;";
+ if (!_wcsnicmp(dblClickAction, toCheck, 7))
+ {
+ onLeftButtonUp(x, y);
+ getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue() + 7);
+ }
+ else
+ {
+#endif
+ svc_action *act = ActionEnum(dblClickAction).getNext();
+ if (act)
+ {
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ act->onAction(dblClickAction, getDblClickParam(), _x, _y, NULL, 0, this);
+ SvcEnum::release(act);
+ }
+#ifdef WASABI_COMPILE_WNDMGR
+
+ }
+#endif
+
+ }
+ return r;
+}
+
+
+int TextBase::onRightButtonDown(int x, int y)
+{
+ TEXTBASE_PARENT::onRightButtonDown(x, y);
+ if (!rClickAction.isempty())
+ {
+ svc_action *act = ActionEnum(rClickAction).getNext();
+ if (act)
+ {
+ int _x = x;
+ int _y = y;
+ clientToScreen(&_x, &_y);
+ act->onAction(rClickAction, getRClickParam(), _x, _y, NULL, 0, this);
+ SvcEnum::release(act);
+ }
+ }
+ return 1;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/textbase.h b/Src/Wasabi/api/skin/widgets/textbase.h
new file mode 100644
index 00000000..e143cf37
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/textbase.h
@@ -0,0 +1,95 @@
+#ifndef NULLSOFT_WASABI_TEXTBASE_H
+#define NULLSOFT_WASABI_TEXTBASE_H
+
+#include <api/wnd/wndclass/bufferpaintwnd.h>
+#include <tataki/color/filteredcolor.h>
+#include <tataki/color/skinclr.h>
+#include <bfc/string/StringW.h>
+
+#define TEXTBASE_PARENT BufferPaintWnd
+
+class TextBase : public TEXTBASE_PARENT, public SkinCallbackI
+{
+public:
+ TextBase();
+ virtual ~TextBase();
+
+ ARGB32 GetColor(int alt=0);
+ void GetFontInfo(Wasabi::FontInfo *_font, int alt=0);
+
+ void SetTextColor(ARGB32 c, int alt=0);
+ void SetFontSize(const wchar_t *strvalue, int alt=0);
+ void SetFont(const wchar_t *name, int alt=0);
+ void SetAntialias(int a, int alt=0);
+ void SetFontAlign(int al);
+ virtual void setDblClickParam(const wchar_t *p);
+ virtual const wchar_t *getDblClickParam();
+ virtual void setRClickParam(const wchar_t *p);
+ virtual const wchar_t *getRClickParam();
+protected:
+ /* Virtual methods to override */
+ virtual void invalidateTextBuffer()=0;
+
+
+/*static */void CreateXMLParameters(int master_handle);
+private:
+ StringW dblClickAction;
+ StringW rClickAction;
+
+ /* Font Info */
+ FilteredColor color[2];
+ SkinColor scolor[2];
+ int color_mode[2];
+ StringW font[2];
+ int bold[2];
+ int italic[2];
+ int antialias[2];
+ int align;
+
+protected:
+ int fontsize[2];
+ int lpadding, rpadding;
+ int grab;
+
+private:
+ /* XML Parameters */
+ enum
+ {
+ TEXTBASE_SETCOLOR,
+ TEXTBASE_SETALTCOLOR,
+ TEXTBASE_SETFONTSIZE,
+ TEXTBASE_SETFONT,
+ TEXTBASE_SETALTFONT,
+ TEXTBASE_SETALTFONTSIZE,
+ TEXTBASE_SETBOLD,
+ TEXTBASE_SETITALIC,
+ TEXTBASE_SETALTBOLD,
+ TEXTBASE_SETALTITALIC,
+ TEXTBASE_SETANTIALIAS,
+ TEXTBASE_SETALTANTIALIAS,
+ TEXTBASE_SETDBLCLKACTION,
+ TEXTBASE_SETRCLKACTION,
+ TEXTBASE_SETALIGN,
+ TEXTBASE_SETLPADDING,
+ TEXTBASE_SETRPADDING,
+ TEXTBASE_RCLICKPARAM,
+ TEXTBASE_DBLCLICKPARAM,
+
+
+ };
+ static XMLParamPair params[];
+ int xuihandle;
+ StringW dblclickparam;
+ StringW rclickparam;
+protected:
+ /* Methods that TextBase overrides */
+ int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval);
+ int onInit();
+ int skincb_onColorThemeChanged(const wchar_t *newcolortheme);
+ int onLeftButtonDblClk(int x, int y);
+ int onRightButtonDown(int x, int y);
+ virtual int wantAutoContextMenu() { return rClickAction.isempty(); }
+
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/tgbutton.cpp b/Src/Wasabi/api/skin/widgets/tgbutton.cpp
new file mode 100644
index 00000000..1e19d021
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/tgbutton.cpp
@@ -0,0 +1,313 @@
+#include <precomp.h>
+#include "tgbutton.h"
+#include <api/script/scriptmgr.h>
+#include <bfc/parse/paramparser.h>
+
+const wchar_t toggleButtonXuiObjectStr[] = L"ToggleButton"; // This is the xml tag
+char toggleButtonXuiSvcName[] = "ToggleButton xui object"; // this is the name of the xuiservice
+
+XMLParamPair ToggleButton::params[] = {
+ {TOGGLEBUTTON_AUTOTOGGLE, L"AUTOTOGGLE"},
+#ifdef WASABI_COMPILE_CONFIG
+ {TOGGLEBUTTON_CFGVAL, L"CFGVAL"},
+#endif
+ };
+
+ToggleButton::ToggleButton() {
+ param=0;
+getScriptObject()->vcpu_setInterface(toggleButtonGuid, (void *)static_cast<ToggleButton *>(this));
+ getScriptObject()->vcpu_setClassName(L"ToggleButton");
+ getScriptObject()->vcpu_setController(tgbuttonController);
+ autotoggle = 1;
+#ifdef WASABI_COMPILE_CONFIG
+ cfgVal = 1;
+#endif
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+}
+
+void ToggleButton::CreateXMLParameters(int master_handle)
+{
+ //TOGGLEBUTTON_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ToggleButton::~ToggleButton() {
+}
+
+void ToggleButton::onLeftPush(int x, int y) {
+ autoToggle();
+ TOGGLEBUTTON_PARENT::onLeftPush(x, y);
+ onToggle(getActivatedButton());
+}
+
+void ToggleButton::autoToggle() {
+ if (autotoggle) {
+ if (!getActivatedButton())
+ setActivatedButton(1);
+ else
+ setActivatedButton(0);
+ }
+}
+
+void ToggleButton::onToggle(int i) {
+ scriptVar _y = SOM::makeVar(SCRIPT_INT);
+ SOM::assign(&_y, i ? 1 : 0);
+ script_onToggle(SCRIPT_CALL, getScriptObject(), _y);
+#ifdef WASABI_COMPILE_CONFIG
+ getGuiObject()->guiobject_setCfgInt(i ? cfgVal : 0);
+#endif
+}
+
+int ToggleButton::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *name, const wchar_t *value) {
+ if (xuihandle == _xuihandle) {
+ switch (xmlattributeid) {
+ case TOGGLEBUTTON_AUTOTOGGLE: autotoggle = WTOI(value); return 1;
+#ifdef WASABI_COMPILE_CONFIG
+ case TOGGLEBUTTON_CFGVAL:
+ cfgVal = WTOI(value); return 1;
+#endif
+ }
+ }
+ return TOGGLEBUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, name, value);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+int ToggleButton::onReloadConfig() {
+ TOGGLEBUTTON_PARENT::onReloadConfig();
+ setActivatedButton(getGuiObject()->guiobject_getCfgInt());
+ return 1;
+}
+#endif
+
+int ToggleButton::getCurCfgVal() {
+ return cfgVal;
+}
+
+TgButtonScriptController _tgbuttonController;
+TgButtonScriptController *tgbuttonController=&_tgbuttonController;
+
+
+// -- Functions table -------------------------------------
+function_descriptor_struct TgButtonScriptController::exportedFunction[] = {
+ {L"onToggle", 1, (void*)ToggleButton::script_onToggle },
+ {L"getCurCfgVal", 0, (void*)ToggleButton::script_getCurCfgVal},
+};
+// --------------------------------------------------------
+
+const wchar_t *TgButtonScriptController::getClassName() {
+ return L"ToggleButton";
+}
+
+const wchar_t *TgButtonScriptController::getAncestorClassName() {
+ return L"Button";
+}
+
+ScriptObject *TgButtonScriptController::instantiate() {
+ ToggleButton *tb = new ToggleButton;
+ ASSERT(tb != NULL);
+ return tb->getScriptObject();
+}
+
+void TgButtonScriptController::destroy(ScriptObject *o) {
+ ToggleButton *tb = static_cast<ToggleButton *>(o->vcpu_getInterface(toggleButtonGuid));
+ ASSERT(tb != NULL);
+ delete tb;
+}
+
+void *TgButtonScriptController::encapsulate(ScriptObject *o) {
+ return NULL;
+}
+
+void TgButtonScriptController::deencapsulate(void *o) {
+}
+
+int TgButtonScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *TgButtonScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+GUID TgButtonScriptController::getClassGuid() {
+ return toggleButtonGuid;
+}
+
+const wchar_t *ToggleButton::vcpu_getClassName() {
+ return L"ToggleButton";
+}
+
+scriptVar ToggleButton::script_onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar is) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, tgbuttonController, is);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, is);
+}
+
+scriptVar ToggleButton::script_getCurCfgVal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT;
+ ToggleButton *tg = static_cast<ToggleButton*>(o->vcpu_getInterface(toggleButtonGuid));
+ return MAKE_SCRIPT_INT(tg->getCurCfgVal());
+}
+
+//---
+
+const wchar_t nStatesTgButtonXuiObjectStr[] = L"NStatesButton"; // This is the xml tag
+char nStatesTgButtonXuiSvcName[] = "NStatesButton xui object"; // this is the name of the xuiservice
+XMLParamPair NStatesTgButton::params[] = {
+ {NSTATESTGBUTTON_NSTATES, L"NSTATES"},
+ {NSTATESTGBUTTON_ONEVSTATE, L"AUTOELEMENTS"},
+#ifdef WASABI_COMPILE_CONFIG
+ {NSTATESTGBUTTON_CFGVALS, L"CFGVALS"},
+#endif
+};
+NStatesTgButton::NStatesTgButton() {
+ getScriptObject()->vcpu_setInterface(NStatesTgButtonGuid, (void *)static_cast<NStatesTgButton*>(this));
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+ onevstate = 0;
+}
+
+void NStatesTgButton::CreateXMLParameters(int master_handle)
+{
+ //NSTATESTGBUTTON_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+NStatesTgButton::~NStatesTgButton() {
+}
+
+int NStatesTgButton::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue) {
+ if (_xuihandle == btn_getXuiHandle()) {
+ switch (xmlattributeid) {
+ case BUTTON_IMAGE: image = strvalue; break;
+ case BUTTON_HOVERIMAGE: hover = strvalue; break;
+ case BUTTON_DOWNIMAGE: down = strvalue; break;
+ case BUTTON_ACTIVEIMAGE: active = strvalue; break;
+ }
+ }
+ if (xuihandle == _xuihandle) {
+ switch (xmlattributeid) {
+ case NSTATESTGBUTTON_NSTATES:
+ setNStates(WTOI(strvalue));
+ return 1;
+ case NSTATESTGBUTTON_ONEVSTATE:
+ setOneVisualState(!WTOI(strvalue));
+ return 1;
+#ifdef WASABI_COMPILE_CONFIG
+ case NSTATESTGBUTTON_CFGVALS:
+ cfgvals = strvalue;
+ return 1;
+#endif
+ }
+ }
+ return NSTATESTGBUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, paramname, strvalue);
+}
+
+int NStatesTgButton::onInit() {
+ setState(0);
+ return NSTATESTGBUTTON_PARENT::onInit();
+}
+
+void NStatesTgButton::setOneVisualState(int v) {
+ if (!!onevstate == !!v) return;
+ onevstate = v;
+ if (isPostOnInit()) {
+ setupBitmaps();
+ invalidate();
+ }
+}
+
+void NStatesTgButton::setState(int n) {
+ if (nstates <= 1) return;
+ state = n;
+ setupBitmaps();
+#ifdef WASABI_COMPILE_CONFIG
+ if (!cfgvals.isempty()) {
+ ParamParser pp(cfgvals);
+ const wchar_t *p = pp.enumItem(state);
+ if (p != NULL)
+ setXmlParam(L"cfgval", p);
+ } else {
+ // if the skinner doesn't ask for custom config values,
+ // simply use the current state number as the cfgval.
+ setXmlParam(L"cfgval", StringPrintfW(L"%d", state));
+ }
+#endif
+}
+
+int NStatesTgButton::getActivatedButton() {
+ if (nstates <= 1) return NSTATESTGBUTTON_PARENT::getActivatedButton();
+ return (getState() != 0);
+}
+
+void NStatesTgButton::autoToggle() {
+ if (nstates <= 1) {
+ NSTATESTGBUTTON_PARENT::autoToggle();
+ return;
+ } else {
+ int s = (state+1) % nstates;
+ setState(s);
+ }
+}
+
+void NStatesTgButton::setupBitmaps() {
+ if (nstates <= 1 || onevstate)
+ setBitmaps(image, down, hover, active);
+ else
+ setBitmaps(StringPrintfW(L"%s%d", image.v(), state),
+ StringPrintfW(L"%s%d", down.v(), state),
+ StringPrintfW(L"%s%d", hover.v(), state) /*, StringPrintf("%s%d", image.v(), (state+1) % nstates)*/);
+}
+
+void NStatesTgButton::setActivatedButton(int a) {
+ if (nstates <= 1) {
+ NSTATESTGBUTTON_PARENT::setActivatedButton(a);
+ return;
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (!cfgvals.isempty()) {
+ ParamParser pp(cfgvals);
+ wchar_t t[64] = {0};
+ wcsncpy(t, StringPrintfW(L"%d", a), 64);
+ for (int i=0;i<pp.getNumItems();i++) {
+ const wchar_t *p = pp.enumItem(i);
+ if (WCSCASEEQLSAFE(p, t)) {
+ setState(i);
+ return;
+ }
+ }
+ } else {
+ if (!a)
+ setState(0);
+ else
+ setState(a);
+ }
+#endif
+}
+
+int NStatesTgButton::getCurCfgVal() {
+#ifdef WASABI_COMPILE_CONFIG
+ if (!cfgvals.isempty()) {
+ ParamParser pp(cfgvals);
+ const wchar_t *p = pp.enumItem(state);
+ if (p) return WTOI(p);
+ return 0;
+ } else {
+ // if the skinner doesn't ask for custom config values,
+ // simply use the current state number as the cfgval.
+ return state;
+ }
+#else
+ return ToggleButton::getCurCfgVal();
+#endif
+}
diff --git a/Src/Wasabi/api/skin/widgets/tgbutton.h b/Src/Wasabi/api/skin/widgets/tgbutton.h
new file mode 100644
index 00000000..704ce010
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/tgbutton.h
@@ -0,0 +1,136 @@
+#ifndef _TOGGLEBUTTON_H
+#define _TOGGLEBUTTON_H
+
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/skin/widgets/button.h>
+
+#define TOGGLEBUTTON_PARENT Wasabi::Button
+
+class TgButtonScriptController : public ButtonScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return buttonController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern TgButtonScriptController *tgbuttonController;
+
+
+class ToggleButton : public TOGGLEBUTTON_PARENT {
+
+public:
+
+ ToggleButton();
+ virtual ~ToggleButton();
+
+ virtual void onLeftPush(int x, int y);
+ virtual void onToggle(int i);
+
+ virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *name, const wchar_t *value);
+#ifdef WASABI_COMPILE_CONFIG
+ virtual int onReloadConfig();
+#endif
+ virtual void autoToggle();
+
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return tgbuttonController; }
+ virtual int getCurCfgVal();
+
+protected:
+/*static */void CreateXMLParameters(int master_handle);
+ enum {
+ TOGGLEBUTTON_AUTOTOGGLE=0,
+#ifdef WASABI_COMPILE_CONFIG
+ TOGGLEBUTTON_CFGVAL,
+#endif
+ };
+
+
+private:
+ static XMLParamPair params[];
+ wchar_t *param;
+ int autotoggle;
+#ifdef WASABI_COMPILE_CONFIG
+ int cfgVal;
+#endif
+ int xuihandle;
+
+public:
+ static scriptVar script_onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar is);
+ static scriptVar script_getCurCfgVal(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+
+extern const wchar_t toggleButtonXuiObjectStr[];
+extern char toggleButtonXuiSvcName[];
+class ToggleButtonXuiSvc : public XuiObjectSvc<ToggleButton, toggleButtonXuiObjectStr, toggleButtonXuiSvcName> {};
+
+
+// {80F97426-9A10-472c-82E7-8309AA4789E7}
+static const GUID NStatesTgButtonGuid =
+{ 0x80f97426, 0x9a10, 0x472c, { 0x82, 0xe7, 0x83, 0x9, 0xaa, 0x47, 0x89, 0xe7 } };
+
+#define NSTATESTGBUTTON_PARENT ToggleButton
+
+class NStatesTgButton : public NSTATESTGBUTTON_PARENT {
+ public:
+ NStatesTgButton();
+ virtual ~NStatesTgButton();
+
+ virtual int setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue);
+ void setNStates(int n) { nstates = n; }
+ virtual int onInit();
+
+ void setState(int n);
+ virtual int getActivatedButton();
+ virtual void autoToggle();
+ int getState() { return state; }
+ virtual void setActivatedButton(int a);
+ virtual int getCurCfgVal();
+ void setOneVisualState(int v);
+
+ protected:
+/*static */void CreateXMLParameters(int master_handle);
+ virtual void setupBitmaps();
+
+ enum {
+ NSTATESTGBUTTON_NSTATES=0,
+#ifdef WASABI_COMPILE_CONFIG
+ NSTATESTGBUTTON_CFGVALS,
+#endif
+ NSTATESTGBUTTON_ONEVSTATE,
+ };
+
+ StringW image, hover, down, active;
+ int nstates;
+ int state;
+
+ int onevstate;
+#ifdef WASABI_COMPILE_CONFIG
+ StringW cfgvals;
+#endif
+private:
+ static XMLParamPair params[];
+ int xuihandle;
+};
+
+extern const wchar_t nStatesTgButtonXuiObjectStr[];
+extern char nStatesTgButtonXuiSvcName[];
+class nStatesTgButtonXuiSvc : public XuiObjectSvc<NStatesTgButton, nStatesTgButtonXuiObjectStr, nStatesTgButtonXuiSvcName> {};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/title.cpp b/Src/Wasabi/api/skin/widgets/title.cpp
new file mode 100644
index 00000000..92acf4d7
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/title.cpp
@@ -0,0 +1,261 @@
+#include <precomp.h>
+#include "title.h"
+#include <api/wndmgr/layout.h>
+#include <api/wnd/paintset.h>
+#include <api/skin/widgets/text.h>
+#include <api/locales/xlatstr.h>
+#include <api/wnd/cwndtrack.h>
+#include <api/util/varmgr.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define DC_MAXIMIZE 0x9831
+
+const wchar_t titleBarXuiObjectStr[] = L"TitleBar"; // This is the xml tag
+char titleBarXuiSvcName[] = "TitleBar xui object"; // this is the name of the xuiservice
+XMLParamPair Title::params[] = {
+ {TITLE_SETBORDER, L"BORDER"},
+ {TITLE_SETDBLCLKACTION, L"DBLCLICKACTION"},
+ {TITLE_SETMAXIMIZE, L"MAXIMIZE"},
+ {TITLE_SETSTREAKS, L"STREAKS"},
+ {TITLE_SETTITLE, L"TITLE"},
+ };
+Title::Title()
+{
+ getScriptObject()->vcpu_setInterface(titleGuid, (void *)static_cast<Title *>(this));
+ getScriptObject()->vcpu_setClassName(L"Title");
+ getScriptObject()->vcpu_setController(titleController);
+ dostreaks = 1;
+ doborder = 1;
+ m_maximize = 0;
+ getGuiObject()->guiobject_setMover(1);
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void Title::CreateXMLParameters(int master_handle)
+{
+ //TITLE_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Title::~Title()
+{}
+
+int Title::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval)
+{
+ if (xuihandle != _xuihandle) return TITLE_PARENT::setXuiParam(_xuihandle, attrid, name, strval);
+ switch (attrid)
+ {
+ case TITLE_SETTITLE:
+ setTitle(strval);
+ break;
+ case TITLE_SETSTREAKS:
+ setStreaks(WTOI(strval));
+ break;
+ case TITLE_SETBORDER:
+ setBorder(WTOI(strval));
+ break;
+ case TITLE_SETMAXIMIZE:
+ m_maximize = WTOI(strval);
+ break;
+ case TITLE_SETDBLCLKACTION:
+ dblClickAction = strval;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void Title::setStreaks(int s)
+{
+ if (s == dostreaks) return ;
+ dostreaks = s;
+ invalidate();
+}
+
+void Title::setBorder(int b)
+{
+ if (b == doborder) return ;
+ doborder = b;
+ invalidate();
+}
+
+int Title::getPreferences(int what)
+{
+ if (what == SUGGESTED_W) return 128;
+ if (what == SUGGESTED_H) return 22;
+ return TITLE_PARENT::getPreferences(what);
+}
+
+int Title::onPaint(Canvas *canvas)
+{
+ const wchar_t *tempname = title;
+ //StringW tempname(title);
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ TITLE_PARENT::onPaint(canvas);
+
+#ifdef WA3COMPATIBILITY
+ //tempname = PublicVarManager::translate(title, getGuiObject());
+#else
+ tempname = title;
+#endif
+
+
+#ifdef WASABI_COMPILE_PAINTSETS
+ RECT pr(TITLE_PARENT::clientRect());
+ const wchar_t *t = NULL;
+ switch(wantTranslation())
+ {
+ case 0:
+ t = tempname;
+ break;
+ case 1:
+ t = _(tempname);
+ break;
+ case 2:
+ t = __(tempname);
+ break;
+ }
+ paintset_renderTitle(t, canvas, &pr, getPaintingAlpha(), dostreaks, doborder);
+#endif
+
+
+ return 1;
+}
+
+void Title::setTitle(const wchar_t *t)
+{
+ title = t;
+ title.toupper();
+}
+
+const wchar_t *Title::getTitle()
+{
+ return title;
+}
+
+int Title::onLeftButtonDblClk(int x, int y)
+{
+ if (m_maximize)
+ postDeferredCallback(DC_MAXIMIZE, 0);
+ else
+ {
+#ifdef WASABI_COMPILE_WNDMGR
+ if (dblClickAction)
+ {
+ const wchar_t *toCheck = L"SWITCH;";
+ if (!WCSNICMP(dblClickAction, toCheck, 7))
+ {
+ onLeftButtonUp(x, y);
+ getGuiObject()->guiobject_getParentGroup()->getParentContainer()->switchToLayout(dblClickAction.getValue() + 7);
+ }
+ }
+#endif
+
+ }
+ ifc_window *b = getParent();
+ if (b)
+ return b->onLeftButtonDblClk(x, y);
+ return TITLE_PARENT::onLeftButtonDblClk(x, y);
+}
+
+int Title::onDeferredCallback(intptr_t param1, intptr_t param2)
+{
+ switch (param1)
+ {
+#ifdef WASABI_COMPILE_WNDMGR
+ case DC_MAXIMIZE:
+ Container *c = getGuiObject()->guiobject_getParentGroup()->getParentContainer();
+ if (c)
+ {
+ Layout *l = c->getCurrentLayout();
+ if (l)
+ {
+ if (l->isMaximized()) l->restore();
+ else l->maximize();
+ }
+ }
+ return 1;
+#endif
+
+ }
+ return TITLE_PARENT::onDeferredCallback(param1, param2);
+}
+
+TitleScriptController _titleController;
+TitleScriptController *titleController = &_titleController;
+
+
+// -- Functions table -------------------------------------
+function_descriptor_struct TitleScriptController::exportedFunction[] = {
+ {L"fake", 0, (void*)Title::script_vcpu_fake },
+ };
+
+const wchar_t *TitleScriptController::getClassName()
+{
+ return L"Title";
+}
+
+const wchar_t *TitleScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *TitleScriptController::instantiate()
+{
+ Title *t = new Title;
+ ASSERT(t != NULL);
+ return t->getScriptObject();
+}
+
+void TitleScriptController::destroy(ScriptObject *o)
+{
+ Title *t = static_cast<Title *>(o->vcpu_getInterface(titleGuid));
+ ASSERT(t != NULL);
+ delete t;
+}
+
+void *TitleScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for title yet
+}
+
+void TitleScriptController::deencapsulate(void *o)
+{}
+
+int TitleScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *TitleScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID TitleScriptController::getClassGuid()
+{
+ return titleGuid;
+}
+
+
+const wchar_t *Title::vcpu_getClassName()
+{
+ return L"Title";
+}
+
+scriptVar Title::script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/title.h b/Src/Wasabi/api/skin/widgets/title.h
new file mode 100644
index 00000000..bbd9c448
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/title.h
@@ -0,0 +1,87 @@
+//PORTABLE
+#ifndef _TITLE_H
+#define _TITLE_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/objects/guiobj.h>
+
+// {7DFD3244-3751-4e7c-BF40-82AE5F3ADC33}
+static const GUID titleGuid =
+{ 0x7dfd3244, 0x3751, 0x4e7c, { 0xbf, 0x40, 0x82, 0xae, 0x5f, 0x3a, 0xdc, 0x33 } };
+
+#define TITLE_PARENT GuiObjectWnd
+
+class TitleScriptController : public GuiObjectScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern TitleScriptController *titleController;
+
+
+class Title : public TITLE_PARENT {
+public:
+
+ Title();
+ virtual ~Title();
+
+ virtual int onPaint(Canvas *canvas);
+ virtual void setTitle(const wchar_t *title);
+ virtual const wchar_t *getTitle();
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int getPreferences(int what);
+
+ virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *strval);
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return titleController; }
+ virtual int onDeferredCallback(intptr_t param1, intptr_t param2);
+
+ void setBorder(int b);
+ void setStreaks(int s);
+
+ enum {
+ TITLE_SETTITLE=0,
+ TITLE_SETSTREAKS,
+ TITLE_SETBORDER,
+ TITLE_SETMAXIMIZE,
+ TITLE_SETDBLCLKACTION,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+
+private:
+ static XMLParamPair params[];
+ StringW title;
+ int dostreaks, doborder;
+ int m_maximize;
+ StringW dblClickAction;
+ int xuihandle;
+
+public:
+
+ static scriptVar script_vcpu_fake(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+};
+
+extern const wchar_t titleBarXuiObjectStr[];
+extern char titleBarXuiSvcName[];
+class TitleBarXuiSvc : public XuiObjectSvc<Title, titleBarXuiObjectStr, titleBarXuiSvcName> {};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/titlebox.cpp b/Src/Wasabi/api/skin/widgets/titlebox.cpp
new file mode 100644
index 00000000..1c2c931d
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/titlebox.cpp
@@ -0,0 +1,183 @@
+#include <precomp.h>
+#include "titlebox.h"
+#include <api/script/objects/guiobject.h>
+#include <api/script/scriptobj.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/skin/widgets/customobject.h>
+
+TitleBox::TitleBox() {
+ titleleft = NULL;
+ titleright = NULL;
+ titlecenter = NULL;
+ content = NULL;
+ centered = 0;
+}
+
+TitleBox::~TitleBox() {
+ delete titleleft;
+ delete titleright;
+ delete titlecenter;
+ delete content;
+}
+
+int TitleBox::onResize() {
+ int rt = TITLEBOX_PARENT::onResize();
+ if (!isInited()) return 0;
+
+ RECT r, d;
+ getClientRect(&r);
+
+ int textwidth = titlecenter ? titlecenter->getPreferences(SUGGESTED_W) : 0;
+
+ d = r;
+
+ if (titleleft) {
+ if (!getCentered())
+ d.right = d.left + titleleft->getPreferences(SUGGESTED_W);
+ else
+ d.right = d.left + ((r.right-r.left) - textwidth) / 2;
+ d.bottom = d.top + titleleft->getPreferences(SUGGESTED_H);
+ titleleft->resize(d.left, d.top, d.right-d.left, d.bottom-d.top);
+ }
+
+ if (titlecenter) {
+ d.left = d.right;
+ d.right = d.left + titlecenter->getPreferences(SUGGESTED_W);
+ d.bottom = d.top + titlecenter->getPreferences(SUGGESTED_H);
+ titlecenter->resize(d.left, d.top, d.right-d.left, d.bottom-d.top);
+ }
+
+ if (titleright) {
+ d.left = d.right;
+ d.right = r.right;
+ d.bottom = d.top + titleright->getPreferences(SUGGESTED_H);
+ titleright->resize(d.left, d.top, d.right-d.left, d.bottom-d.top);
+ }
+
+ return rt;
+}
+
+int TitleBox::onInit() {
+ int rt = TITLEBOX_PARENT::onInit();
+
+ titleleft = new GuiObjectWnd();
+ titleleft->setContent(L"wasabi.titlebox.left.group");
+ titlecenter = new GuiObjectWnd();
+ titlecenter->setContent(L"wasabi.titlebox.center.group");
+ titleright = new GuiObjectWnd();
+ titleright->setContent(L"wasabi.titlebox.right.group");
+
+ titleleft->setParent(this);
+ titlecenter->setParent(this);
+ titleright->setParent(this);
+
+ titleleft->init(this);
+ titlecenter->init(this);
+ titleright->init(this);
+
+ setContent(L"wasabi.titlebox.main.group");
+ return rt;
+}
+
+void TitleBox::setSubContent(int setcontent) {
+ if (setcontent) {
+ delete content;
+ content = NULL;
+ }
+
+ GuiObject *myself = getContent();
+
+ if (myself != NULL)
+ {
+ if (setcontent)
+ {
+ GuiObject *holder = findObject(L"titlebox.content"); // get the <CustomObject />
+ if (holder != NULL) {
+ CustomObject *obj = static_cast<CustomObject*>(holder->guiobject_getScriptObject()->vcpu_getInterface(customObjectGuid));
+ if (obj != NULL) {
+ content = new GuiObjectWnd();
+ content->setContent(content_id);
+ obj->customobject_setRootWnd(content); // and give it our content, it'll init it as needed
+ }
+ }
+ }
+ GuiObject *text = titlecenter->getContent()->guiobject_findObject(L"titlebox.text");
+ if (text != NULL) {
+ StringW name = getTitle();
+ if (name.isempty()) {
+ ifc_window *cr = content->getContentRootWnd();
+ if (cr != NULL)
+ name = cr->getRootWndName();
+ }
+ if (name.isempty())
+ name = myself->guiobject_getRootWnd()->getRootWndName();
+ if (!name.isempty())
+ {
+ name += suffix;
+ C_Text ctext(*text);
+ ctext.setText(name);
+ }
+ }
+ }
+ if (isPostOnInit())
+ onResize();
+}
+
+void TitleBox::onNewContent() {
+ TITLEBOX_PARENT::onNewContent();
+ setSubContent();
+}
+
+void TitleBox::setCentered(int _centered) {
+ centered = _centered;
+ if (isInited())
+ onResize();
+}
+
+void TitleBox::setTitle(const wchar_t *t) {
+ title = t;
+ setName(title);
+ if (isInited())
+ setSubContent(0);
+}
+
+void TitleBox::setSuffix(const wchar_t *_suffix) {
+ if (!WCSICMPSAFE(suffix, _suffix)) return;
+ suffix = _suffix;
+ if (isInited())
+ setSubContent(0);
+}
+
+void TitleBox::setChildGroup(const wchar_t *grp) {
+ content_id = grp;
+ if (isInited())
+ setSubContent();
+}
+
+int TitleBox::getPreferences(int what) {
+/* GuiObject *contentGuiObj = findObject("titlebox.content");
+ if (contentGuiObj != NULL) {
+ // FUCKO, this is a huge hack but I don't have time to make autowidth/heightsource be a GuiObject thing instead of a group thing right now
+ int x, y, rx, ry, w, rw, h, rh;
+ contentGuiObj->guiobject_getGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh);
+ if (w == AUTOWH) { w = contentGuiObj->guiobject_getAutoWidth(); rw = 0; }
+ if (h == AUTOWH) { h = contentGuiObj->guiobject_getAutoHeight(); rh = 0; }
+ if (what == SUGGESTED_W) {
+ int p = contentGuiObj->guiobject_getRootWnd()->getPreferences(SUGGESTED_W);
+ if (rx == 0 && rw == 1)
+ return p - w;
+ else if (rx == 0 && rw == 0)
+ return p + x + w;
+ } else if (what == SUGGESTED_H) {
+ int p = contentGuiObj->guiobject_getRootWnd()->getPreferences(SUGGESTED_H);
+ if (ry == 0 && rh == 1)
+ return p + y + ((-h)-y);
+ else if (ry == 0 && rh == 0)
+ return p + y + h;
+ }
+ ifc_window *contentGuiRootWnd = contentGuiObj->guiobject_getRootWnd();
+ return contentGuiRootWnd->getPreferences(what);
+ }*/
+ return TITLEBOX_PARENT::getPreferences(what);
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/titlebox.h b/Src/Wasabi/api/skin/widgets/titlebox.h
new file mode 100644
index 00000000..6631657a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/titlebox.h
@@ -0,0 +1,95 @@
+#ifndef __TITLEBOX_H
+#define __TITLEBOX_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define TITLEBOX_PARENT GuiObjectWnd
+
+
+/**
+ Titlebox
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class TitleBox : public TITLEBOX_PARENT {
+
+ public:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ TitleBox();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~TitleBox();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+ virtual int onResize();
+ virtual int getCentered() { return centered; }
+ virtual void setCentered(int _centered);
+ virtual void setTitle(const wchar_t *t);
+ virtual const wchar_t *getTitle() { return title; }
+ virtual void setSuffix(const wchar_t *suffix);
+ const wchar_t *getSuffix() { return suffix; }
+
+ virtual void onNewContent();
+
+
+ virtual void setChildGroup(const wchar_t *grp);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int getPreferences(int what);
+
+ private:
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setSubContent(int insertcontent=1);
+
+ GuiObjectWnd *titleleft;
+ GuiObjectWnd *titleright;
+ GuiObjectWnd *titlecenter;
+ GuiObjectWnd *content;
+ int centered;
+ StringW title;
+ StringW content_id;
+ StringW suffix;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp
new file mode 100644
index 00000000..d4799a06
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.cpp
@@ -0,0 +1,186 @@
+#include <precomp.h>
+
+#include "xuiwa2slider.h"
+#include <tataki/canvas/canvas.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/core/api_core.h>
+
+#define WA2SLIDER_SEEK_INTERVAL 500
+
+const wchar_t Wa2SliderXuiObjectStr[] = L"images"; // This is the xml tag
+char Wa2SliderXuiSvcName[] = "Images XuiObject Service";
+
+XMLParamPair Wa2Slider::params[] =
+ {
+ {WA2SLIDER_IMAGES, L"IMAGES"},
+ {WA2SLIDER_IMAGESSPACING, L"IMAGESSPACING"},
+ {WA2SLIDER_SOURCE, L"SOURCE"},
+ };
+
+Wa2Slider::Wa2Slider()
+ : started(false)
+{
+ realpos = 0;
+ imagesBitmap = 0;
+ spacing = 0;
+ action = ACT_NONE;
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void Wa2Slider::CreateXMLParameters(int master_handle)
+{
+ //WA2SLIDER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Wa2Slider::~Wa2Slider()
+{
+ killTimer(Wa2Slider_TIMER_POS);
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+ delete(imagesBitmap);
+}
+
+int Wa2Slider::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle == _xuihandle)
+ {
+ switch (xmlattributeid)
+ {
+ case WA2SLIDER_IMAGES: images = value; return 1;
+ case WA2SLIDER_IMAGESSPACING: spacing = WTOI(value); return 1;
+ case WA2SLIDER_SOURCE:
+ if (!_wcsicmp(value, L"volume")) action = ACT_VOLUME;
+ if (!_wcsicmp(value, L"balance")) action = ACT_BALANCE;
+ if (!_wcsicmp(value, L"seek")) action = ACT_SEEK;
+ return 1;
+ }
+ }
+ return WA2SLIDER_PARENT::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, value);
+}
+
+int Wa2Slider::onInit()
+{
+ WA2SLIDER_PARENT::onInit();
+
+ imagesBitmap = new SkinBitmap(images);
+
+ if (action == ACT_VOLUME)
+ corecb_onVolumeChange(WASABI_API_MEDIACORE->core_getVolume(0));
+ if (action == ACT_BALANCE)
+ corecb_onPanChange(WASABI_API_MEDIACORE->core_getPan(0));
+ if (action == ACT_SEEK)
+ {
+ corecb_onSeeked(WASABI_API_MEDIACORE->core_getPosition(0));
+ started = (WASABI_API_MEDIACORE->core_getStatus(0) != 0);
+ setTimer(Wa2Slider_TIMER_POS, WA2SLIDER_SEEK_INTERVAL);
+ }
+
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+
+ return 0;
+}
+
+int Wa2Slider::onPaint(Canvas *canvas)
+{
+ if (imagesBitmap->getHeight() && spacing)
+ {
+ RECT r, r2;
+ getClientRect(&r2);
+ int nb = (imagesBitmap->getHeight() / spacing) - 1;
+ int which = 0;
+ switch (action)
+ {
+ case ACT_BALANCE:
+ {
+ int p = realpos;
+ int f = 32768; //FULL/2;
+ if (p > f)
+ {
+ which = (realpos - f) * nb / f;
+ }
+ else if (p < f)
+ {
+ which = (f - realpos) * nb / f;
+ }
+ else which = 0;
+ }
+ break;
+ case ACT_SEEK:
+ if (!started)
+ which = 0;
+ else
+ which = realpos * nb / 65536;
+ break;
+ case ACT_VOLUME:
+ which = realpos * nb / 65536;
+ break;
+ }
+
+ r.left = 0;
+ r.top = which * spacing;
+ r.bottom = which * spacing + (r2.bottom - r2.top);
+ r.right = r2.right - r2.left;
+ imagesBitmap->blitToRect(canvas, &r, &r2);
+ }
+ return WA2SLIDER_PARENT::onPaint(canvas);
+}
+
+int Wa2Slider::corecb_onVolumeChange(int newvol)
+{
+ if (action != ACT_VOLUME) return 0;
+ realpos = (int)(((double)newvol * 65535.f) / 255.f);
+ invalidate();
+ return 0;
+}
+
+int Wa2Slider::corecb_onPanChange(int newpan)
+{
+ if (action != ACT_BALANCE) return 0;
+
+ realpos = (int)(((double)(newpan + 127) * 65535.f) / 255.f);
+invalidate();
+ return 0;
+}
+
+int Wa2Slider::corecb_onSeeked(int newpos)
+{
+ if (action != ACT_SEEK) return 0;
+
+ int len = WASABI_API_MEDIACORE->core_getLength(0);
+
+ realpos = (int)(((float)(newpos) * 65535.f) / (float)len);
+invalidate();
+ return 0;
+}
+
+int Wa2Slider::corecb_onStarted()
+{
+ started = true;
+ corecb_onSeeked(0);
+ invalidate();
+ return 0;
+}
+
+int Wa2Slider::corecb_onStopped()
+{
+ started = false;
+ corecb_onSeeked(0);
+ invalidate();
+ return 0;
+}
+void Wa2Slider::timerCallback(int id)
+{
+ switch (id)
+ {
+ case Wa2Slider_TIMER_POS:
+ corecb_onSeeked(WASABI_API_MEDIACORE->core_getPosition(0));
+ break;
+ default:
+ WA2SLIDER_PARENT::timerCallback(id);
+ }
+}
diff --git a/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h
new file mode 100644
index 00000000..1f24fe9c
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/wa2/xuiwa2slider.h
@@ -0,0 +1,63 @@
+#ifndef _XUIWA2SLIDER_H
+#define _XUIWA2SLIDER_H
+
+#include <api/script/objects/guiobj.h>
+#include <api/skin/widgets.h>
+#include <api/syscb/callbacks/corecbi.h>
+
+#define WA2SLIDER_PARENT GuiObjectWnd
+
+class Wa2Slider : public WA2SLIDER_PARENT, public CoreCallbackI
+{
+public:
+ Wa2Slider();
+ virtual ~Wa2Slider();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *canvas);
+
+ virtual int corecb_onVolumeChange(int newvol);
+ virtual int corecb_onPanChange(int newpan);
+ virtual int corecb_onSeeked(int newpos);
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+ virtual void timerCallback(int id);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ int realpos;
+ StringW images;
+ SkinBitmap *imagesBitmap;
+ int spacing;
+ int action;
+ static XMLParamPair params[];
+ int xuihandle;
+ bool started;
+
+ enum {
+ ACT_NONE = 0,
+ ACT_VOLUME,
+ ACT_BALANCE,
+ ACT_SEEK,
+ };
+
+ enum {
+ Wa2Slider_TIMER_POS = 1,
+ };
+ enum {
+ WA2SLIDER_IMAGES,
+ WA2SLIDER_IMAGESSPACING,
+ WA2SLIDER_SOURCE,
+ WA2SLIDER_NUMPARAMS,
+ };
+};
+
+// -----------------------------------------------------------------------
+extern const wchar_t Wa2SliderXuiObjectStr[];
+extern char Wa2SliderXuiSvcName[];
+class Wa2SliderXuiSvc : public XuiObjectSvc<Wa2Slider, Wa2SliderXuiObjectStr, Wa2SliderXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuiaddparams.cpp b/Src/Wasabi/api/skin/widgets/xuiaddparams.cpp
new file mode 100644
index 00000000..aa6d5daa
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiaddparams.cpp
@@ -0,0 +1,41 @@
+#include <precomp.h>
+
+#include "xuiaddparams.h"
+#include <api/script/scriptguid.h>
+
+// -----------------------------------------------------------------------
+const wchar_t AddParamsXuiObjectStr[] = L"AddParams"; // This is the xml tag
+char AddParamsXuiSvcName[] = "AddParams xui object";
+
+// -----------------------------------------------------------------------
+AddParams::AddParams():myxuihandle(0) {
+}
+
+// -----------------------------------------------------------------------
+AddParams::~AddParams() {
+ pastlist.deleteAll();
+}
+
+// -----------------------------------------------------------------------
+int AddParams::setXmlParam(const wchar_t *param, const wchar_t *value)
+{
+ int r = ADDPARAMS_PARENT::setXmlParam(param, value);
+ if (!WCSCASEEQLSAFE(param, L"group") && !WCSCASEEQLSAFE(param, L"target")) {
+ Pair<StringW, StringW> *pair = new Pair<StringW, StringW>(param, value);
+ pastlist.addItem(pair);
+ }
+ return r;
+}
+
+// -----------------------------------------------------------------------
+void AddParams::actuator_onPerform(GuiObject *target) { // guaranteed non NULL
+ ADDPARAMS_PARENT::actuator_onPerform(target);
+ XmlObject *xtarget = static_cast<XmlObject *>(target->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ foreach(pastlist)
+ const wchar_t *a = pastlist.getfor()->a;
+ int xp = xtarget->getXmlParam(a);
+ StringW newval((xp == -1) ? L"" : xtarget->getXmlParamValue(xp));
+ newval.cat(pastlist.getfor()->b);
+ xtarget->setXmlParam(a, newval);
+ endfor;
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuiaddparams.h b/Src/Wasabi/api/skin/widgets/xuiaddparams.h
new file mode 100644
index 00000000..1d41e36e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiaddparams.h
@@ -0,0 +1,34 @@
+#ifndef __ADDPARAMS_H
+#define __ADDPARAMS_H
+
+#include <api/skin/objectactuator.h>
+#include <bfc/pair.h>
+
+#define ADDPARAMS_PARENT ObjectActuator
+
+extern const wchar_t AddParamsXuiObjectStr[];
+extern char AddParamsXuiSvcName[];
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+class AddParams: public ADDPARAMS_PARENT {
+public:
+
+ AddParams();
+ virtual ~AddParams();
+
+ virtual int setXmlParam(const wchar_t *param, const wchar_t *value);
+ virtual void actuator_onPerform(GuiObject *target);
+ virtual const wchar_t *getActuatorTag() { return AddParamsXuiObjectStr; } // for error msgs purposes
+
+private:
+ int myxuihandle;
+ PtrList< Pair<StringW, StringW> > pastlist;
+};
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+class AddParamsXuiSvc : public XuiObjectSvc<AddParams, AddParamsXuiObjectStr, AddParamsXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp b/Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp
new file mode 100644
index 00000000..abcfacfd
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuibookmarklist.cpp
@@ -0,0 +1,50 @@
+#include <precomp.h>
+#include "xuibookmarklist.h"
+
+// -----------------------------------------------------------------------
+const wchar_t BookmarkListXuiObjectStr[] = L"BookmarkList"; // This is the xml tag
+char BookmarkListXuiSvcName[] = "BookmarkList xui object";
+
+XMLParamPair BookmarkList::params[] = {
+ {BOOKMARKLIST_SET, L""},
+};
+
+
+// -----------------------------------------------------------------------
+BookmarkList::BookmarkList() {
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+void BookmarkList::CreateXMLParameters(int master_handle)
+{
+ //BOOKMARKLIST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+BookmarkList::~BookmarkList()
+{
+}
+
+// -----------------------------------------------------------------------
+int BookmarkList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return BOOKMARKLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case BOOKMARKLIST_SET:
+ set(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void BookmarkList::set(const wchar_t *elementname) {
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuibookmarklist.h b/Src/Wasabi/api/skin/widgets/xuibookmarklist.h
new file mode 100644
index 00000000..277899f8
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuibookmarklist.h
@@ -0,0 +1,36 @@
+#ifndef __BOOKMARKLIST_H
+#define __BOOKMARKLIST_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define BOOKMARKLIST_PARENT GuiObjectWnd
+
+// -----------------------------------------------------------------------
+class BookmarkList : public BOOKMARKLIST_PARENT {
+
+ public:
+
+ BookmarkList();
+ virtual ~BookmarkList();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void set(const wchar_t *elementname);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ enum {
+ BOOKMARKLIST_SET = 0,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+};
+
+// -----------------------------------------------------------------------
+extern const wchar_t BookmarkListXuiObjectStr[];
+extern char BookmarkListXuiSvcName[];
+class BookmarkListXuiSvc : public XuiObjectSvc<BookmarkList, BookmarkListXuiObjectStr, BookmarkListXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuicheckbox.cpp b/Src/Wasabi/api/skin/widgets/xuicheckbox.cpp
new file mode 100644
index 00000000..599c52e7
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuicheckbox.cpp
@@ -0,0 +1,165 @@
+#include <precomp.h>
+#include "xuicheckbox.h"
+#include <bfc/parse/paramparser.h>
+#include <api/script/objects/c_script/c_text.h>
+
+// -----------------------------------------------------------------------
+const wchar_t ScriptCheckBoxXuiObjectStr[] = L"Wasabi:CheckBox"; // This is the xml tag
+char ScriptCheckBoxXuiSvcName[] = "Wasabi:CheckBox xui object";
+
+XMLParamPair ScriptCheckBox::params[] = {
+ {SCRIPTCHECKBOX_ACTION, L"ACTION"},
+ {SCRIPTCHECKBOX_ACTIONTARGET, L"ACTION_TARGET"},
+ {SCRIPTCHECKBOX_ACTIONPARAM, L"PARAM"},
+{SCRIPTCHECKBOX_RADIOID, L"RADIOID"},
+ {SCRIPTCHECKBOX_RADIOVAL, L"RADIOVAL"},
+ {SCRIPTCHECKBOX_TEXT, L"TEXT"},
+
+ };
+// -----------------------------------------------------------------------
+ScriptCheckBox::ScriptCheckBox() : SCRIPTCHECKBOX_PARENT() {
+ getScriptObject()->vcpu_setInterface(checkBoxGuid, (void *)static_cast<ScriptCheckBox*>(this));
+ getScriptObject()->vcpu_setClassName(L"CheckBox"); // this is the script class name
+ getScriptObject()->vcpu_setController(checkBoxController);
+
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+
+void ScriptCheckBox::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTCHECKBOX_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ScriptCheckBox::~ScriptCheckBox() {
+}
+
+// -----------------------------------------------------------------------
+int ScriptCheckBox::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return SCRIPTCHECKBOX_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ // Parcel the values out to the window object we multiply inherit from
+ switch (xmlattributeid) {
+ case SCRIPTCHECKBOX_TEXT:
+ setText(value);
+ break;
+ case SCRIPTCHECKBOX_RADIOID:
+ setRadioid(value);
+ break;
+ case SCRIPTCHECKBOX_RADIOVAL:
+ setRadioVal(value);
+ break;
+ case SCRIPTCHECKBOX_ACTION:
+ setAction(value);
+ break;
+ case SCRIPTCHECKBOX_ACTIONPARAM:
+ setActionParam(value);
+ break;
+ case SCRIPTCHECKBOX_ACTIONTARGET:
+ setActionTarget(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void ScriptCheckBox::onToggle() {
+ SCRIPTCHECKBOX_PARENT::onToggle();
+ Accessible *a = getAccessibleObject();
+ if (a != NULL) {
+ a->onStateChange();
+ }
+ CheckBoxController::onToggle(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(isActivated()));
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+CheckBoxController _checkBoxController;
+CheckBoxController *checkBoxController = &_checkBoxController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct CheckBoxController::exportedFunction[] = {
+ {L"onToggle", 1, (void*)CheckBoxController::onToggle},
+ {L"setChecked", 1, (void*)CheckBoxController::setChecked},
+ {L"isChecked", 0, (void*)CheckBoxController::isChecked},
+ {L"setText", 1, (void*)CheckBoxController::setText},
+ {L"getText", 0, (void*)CheckBoxController::getText},
+};
+
+ScriptObject *CheckBoxController::instantiate() {
+ ScriptCheckBox *sb = new ScriptCheckBox;
+ ASSERT(sb != NULL);
+ return sb->getScriptObject();
+}
+
+void CheckBoxController::destroy(ScriptObject *o) {
+ ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid));
+ ASSERT(sb != NULL);
+ delete sb;
+}
+
+void *CheckBoxController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for checkboxes yet
+}
+
+void CheckBoxController::deencapsulate(void *o) {
+}
+
+int CheckBoxController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *CheckBoxController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar CheckBoxController::onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newstate) {
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, checkBoxController, newstate);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newstate);
+}
+
+scriptVar CheckBoxController::setChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar state) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid));
+ if (sb) sb->setActivated(GET_SCRIPT_INT(state));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar CheckBoxController::isChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ int a = 0;
+ ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid));
+ if (sb) a = sb->isActivated();
+ return MAKE_SCRIPT_INT(a);
+}
+
+scriptVar CheckBoxController::setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid));
+ if (sb)
+ sb->setText(GET_SCRIPT_STRING(text));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar CheckBoxController::getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptCheckBox *sb = static_cast<ScriptCheckBox *>(o->vcpu_getInterface(checkBoxGuid));
+ if (sb)
+ {
+ return MAKE_SCRIPT_STRING(sb->getText());
+
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuicheckbox.h b/Src/Wasabi/api/skin/widgets/xuicheckbox.h
new file mode 100644
index 00000000..295ad4e9
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuicheckbox.h
@@ -0,0 +1,81 @@
+#ifndef __SCRIPTCHECKBOX_H
+#define __SCRIPTCHECKBOX_H
+
+#include <api/skin/widgets/checkbox.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+#include <api/script/objcontroller.h>
+#include <api/wnd/accessible.h>
+
+#define SCRIPTCHECKBOX_PARENT CheckBox
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+class ScriptCheckBox : public SCRIPTCHECKBOX_PARENT {
+
+ public:
+
+ ScriptCheckBox();
+ virtual ~ScriptCheckBox();
+
+ // XuiObject automatically calls this back for all parameters registered using addParam
+ // encountered in the xml source
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void onToggle();
+
+ virtual int accessibility_getState() { return CHECKBOX_PARENT::accessibility_getState() | (isActivated() ? STATE_SYSTEM_CHECKED : 0); }
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ // a list of IDs for our xml attributes, we use them in addParam() in the constructor
+ enum {
+ SCRIPTCHECKBOX_TEXT = 0,
+ SCRIPTCHECKBOX_RADIOID,
+ SCRIPTCHECKBOX_RADIOVAL,
+ SCRIPTCHECKBOX_ACTION,
+ SCRIPTCHECKBOX_ACTIONPARAM,
+ SCRIPTCHECKBOX_ACTIONTARGET,
+ };
+ int myxuihandle;
+ static XMLParamPair params[];
+};
+
+// -----------------------------------------------------------------------------------------------------
+class CheckBoxController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"Checkbox"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return checkBoxGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar onToggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newstate);
+ static scriptVar setChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar state);
+ static scriptVar isChecked(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar setText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar text);
+ static scriptVar getText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern CheckBoxController *checkBoxController;
+
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+extern const wchar_t ScriptCheckBoxXuiObjectStr[];
+extern char ScriptCheckBoxXuiSvcName[];
+class ScriptCheckBoxXuiSvc : public XuiObjectSvc<ScriptCheckBox, ScriptCheckBoxXuiObjectStr, ScriptCheckBoxXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuicombobox.cpp b/Src/Wasabi/api/skin/widgets/xuicombobox.cpp
new file mode 100644
index 00000000..0e9af71c
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuicombobox.cpp
@@ -0,0 +1,7 @@
+#include <precomp.h>
+#include "xuicombobox.h"
+
+// -----------------------------------------------------------------------
+const wchar_t ComboBoxXuiObjectStr[] = L"Wasabi:ComboBox";
+char ComboBoxXuiSvcName[] = "Wasabi:ComboBox xui object";
+
diff --git a/Src/Wasabi/api/skin/widgets/xuicombobox.h b/Src/Wasabi/api/skin/widgets/xuicombobox.h
new file mode 100644
index 00000000..4d60e0ad
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuicombobox.h
@@ -0,0 +1,10 @@
+#ifndef __XUICOMBOBOX_H
+#define __XUICOMBOBOX_H
+
+#include <api/skin/widgets/combobox.h>
+
+extern const wchar_t ComboBoxXuiObjectStr[];
+extern char ComboBoxXuiSvcName[];
+class ComboBoxXuiSvc : public XuiObjectSvc<ComboBox, ComboBoxXuiObjectStr, ComboBoxXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuicustomobject.cpp b/Src/Wasabi/api/skin/widgets/xuicustomobject.cpp
new file mode 100644
index 00000000..559dd4f4
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuicustomobject.cpp
@@ -0,0 +1,64 @@
+#include <precomp.h>
+#include "xuicustomobject.h"
+#include <api/wnd/notifmsg.h>
+
+// -----------------------------------------------------------------------
+const wchar_t CustomObjectXuiObjectStr[] = L"CustomObject"; // This is the xml tag
+char CustomObjectXuiSvcName[] = "CustomObject xui object";
+
+XMLParamPair XuiCustomObject::params[] = {
+ {CUSTOMOBJECT_SETGROUP, L"GROUPID"},
+};
+
+// -----------------------------------------------------------------------
+XuiCustomObject::XuiCustomObject()
+{
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ ScriptObject *o = getGuiObject()->guiobject_getScriptObject();
+ o->vcpu_setInterface(customObjectGuid, static_cast<CustomObject *>(this));
+
+}
+
+void XuiCustomObject::CreateXMLParameters(int master_handle)
+{
+ //CUSTOMOBJECT_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+
+}
+// -----------------------------------------------------------------------
+XuiCustomObject::~XuiCustomObject() {
+}
+
+// -----------------------------------------------------------------------
+int XuiCustomObject::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return CUSTOMOBJECT_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case CUSTOMOBJECT_SETGROUP:
+ setContent(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void XuiCustomObject::setGroup(const wchar_t *elementname) {
+ setContent(elementname);
+}
+
+// -----------------------------------------------------------------------
+void XuiCustomObject::customobject_setRootWnd(ifc_window *w) {
+ rootwndholder_setRootWnd(NULL);
+ groupid = L"";
+ setContent(groupid);
+ if (w != NULL) rootwndholder_setRootWnd(w);
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuicustomobject.h b/Src/Wasabi/api/skin/widgets/xuicustomobject.h
new file mode 100644
index 00000000..28f5227e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuicustomobject.h
@@ -0,0 +1,40 @@
+#ifndef __CustomObject_H
+#define __CustomObject_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/skin/widgets/customobject.h>
+
+#define CUSTOMOBJECT_PARENT GuiObjectWnd
+
+// -----------------------------------------------------------------------
+class XuiCustomObject : public CUSTOMOBJECT_PARENT, public CustomObjectI {
+
+ public:
+
+ XuiCustomObject();
+ virtual ~XuiCustomObject();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setGroup(const wchar_t *elementname);
+ virtual void customobject_setRootWnd(ifc_window *w);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ enum {
+ CUSTOMOBJECT_SETGROUP = 0,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+ StringW groupid;
+};
+
+
+// -----------------------------------------------------------------------
+
+extern const wchar_t CustomObjectXuiObjectStr[];
+extern char CustomObjectXuiSvcName[];
+class CustomObjectXuiSvc : public XuiObjectSvc<XuiCustomObject, CustomObjectXuiObjectStr, CustomObjectXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp b/Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp
new file mode 100644
index 00000000..d79b834b
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuidownloadslist.cpp
@@ -0,0 +1,411 @@
+#include <precomp.h>
+#include "xuidownloadslist.h"
+#include "wa2frontend.h"
+#include <api/wnd/popup.h>
+#include <bfc/parse/pathparse.h>
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(DownloadsList_Svc);
+DECLARE_SERVICE(XuiObjectCreator<DownloadsListXuiSvc>);
+END_SERVICES(DownloadsList_Svc, _DownloadsList_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_DownloadsListXuiSvc; }
+#else
+extern "C" { int __link_DownloadsListXuiSvc; }
+#endif
+
+#endif
+
+// -----------------------------------------------------------------------
+const wchar_t DownloadsListXuiObjectStr[] = L"DownloadsList"; // This is the xml tag
+char DownloadsListXuiSvcName[] = "DownloadsList xui object";
+
+XMLParamPair DownloadsList::params[] = {
+ {CTLIST_NOHSCROLL, L"NOHSCROLL"},
+ };
+
+// -----------------------------------------------------------------------
+DownloadsList::DownloadsList ()
+{
+ setPreventMultipleSelection(1);
+ ensure_on_paint = -1;
+ nohscroll = 1;
+
+ setAutoSort(false);
+ setVirtual(0);
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ DownloadsList::skinObjects.addItem(this);
+}
+
+void DownloadsList::CreateXMLParameters(int master_handle)
+{
+ //DOWNLOADSLIST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+DownloadsList::~DownloadsList() {
+ for (int i = 0; i != this->getNumItems(); i++)
+ {
+ const wchar_t * w = (const wchar_t *) this->getItemData(i);
+ delete w;
+ }
+ DownloadsList::skinObjects.removeItem(this);
+}
+
+// -----------------------------------------------------------------------
+int DownloadsList::onInit()
+{
+ DOWNLOADSLIST_PARENT::onInit();
+
+ addColumn(LocalesManager::GetString(L"nullsoft.browser", 19),100);
+ addColumn(LocalesManager::GetString(L"nullsoft.browser", 18), 95);
+
+ ListColumn *urlCol = new ListColumn(LocalesManager::GetString(L"nullsoft.browser", 17), 0);
+ insertColumn(urlCol);
+
+ ListColumn *tCol = new ListColumn(LocalesManager::GetString(L"nullsoft.browser", 20), 0);
+ insertColumn(tCol);
+
+ // Load all previous downloads - we must begin from the end of our list
+ for (int i = activeDownloads.getNumItems()-1; i != -1; i--)
+ {
+ if (activeDownloads.enumItem(i) == NULL)
+ {
+ activeDownloads.removeByPos(i);
+ continue; // Next loop
+ }
+ newItem(STATUS_WAITING, activeDownloads.enumItem(i));
+ }
+
+ return 1;
+}
+
+// Prohibit list sorting ;)
+int DownloadsList::onColumnLabelClick (int col, int x, int y)
+{
+ //do nothing
+ return 1;
+}
+int DownloadsList::onColumnDblClick (int col, int x, int y)
+{
+ //do nothing
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int DownloadsList::onResize() {
+ DOWNLOADSLIST_PARENT::onResize();
+ if (nohscroll) {
+ RECT r;
+ getClientRect(&r);
+ int nw = r.right-r.left - getColumn(0)->getWidth() - getColumn(1)->getWidth();
+ ListColumn *cLoc = getColumn(2);
+ ListColumn *cTit = getColumn(3);
+ cLoc->setWidth((int)(nw*0.65));
+ cTit->setWidth((int)(nw*0.35));
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void DownloadsList::onDoubleClick(int itemnum)
+{
+ if (getItemData(itemnum) != NULL) wa2.playFile(this->getSubitemText(itemnum, 2));
+}
+
+// -----------------------------------------------------------------------
+int DownloadsList::onRightClick(int itemnum)
+{
+ DOWNLOADSLIST_PARENT::onRightClick(itemnum);
+
+ PopupMenu p;
+ if (this->getItemData(itemnum) == NULL)
+ p.addCommand(L"Wait for file to be transferred", 666, 0 , 1);
+ else
+ {
+ p.addCommand(L"Play", 1, 0 , 0);
+ p.addCommand(L"Enqueue", 2, 0 , 0);
+ }
+
+ int result = p.popAtMouse();
+
+ switch (result)
+ {
+ case 1: wa2.playFile(this->getSubitemText(itemnum, 2)); break;
+ case 2: wa2.enqueueFile(this->getSubitemText(itemnum, 2)); break;
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int DownloadsList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (!_wcsicmp(action, L"play_selected"))
+ {
+ int sel = getFirstItemSelected();
+
+ if (sel > -1)
+ {
+ if (getItemData(sel) != NULL) wa2.playFile(this->getSubitemText(sel, 2));
+ }
+ else
+ {
+ boolean enq = false;
+ for (int i = 0; i != getNumItems(); i++)
+ {
+ if (getItemData(i) != NULL)
+ {
+ if (!enq)
+ {
+ wa2.playFile(this->getSubitemText(i, 2));
+ enq = true;
+ }
+ else
+ wa2.enqueueFile(this->getSubitemText(i, 2));
+ }
+ }
+ }
+ return 1;
+ }
+
+ return DOWNLOADSLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
+// -----------------------------------------------------------------------
+/*int DownloadsList::getTextBold(LPARAM lParam) {
+ if (WCSCASEEQLSAFE(WASABI_API_SKIN->colortheme_enumColorSet(lParam & 0xFFFF), WASABI_API_SKIN->colortheme_getColorSet())) return 1;
+ return DOWNLOADSLIST_PARENT::getTextBold(lParam);
+}*/
+
+// -----------------------------------------------------------------------
+void DownloadsList::onSetVisible(int show) {
+ DOWNLOADSLIST_PARENT::onSetVisible(show);
+ /*if (show) loadThemes();
+ else getDesktopParent()->setFocus();*/
+}
+
+// -----------------------------------------------------------------------
+int DownloadsList::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) {
+ if (xuihandle == _xuihandle) {
+ switch (xmlattrid) {
+ case CTLIST_NOHSCROLL: nohscroll = WTOI(value); return 1;
+ }
+ }
+ return DOWNLOADSLIST_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value);
+}
+
+int DownloadsList::onPaint(Canvas *canvas) {
+ if (ensure_on_paint > -1) ensureItemVisible(ensure_on_paint);
+ ensure_on_paint = -1;
+ DOWNLOADSLIST_PARENT::onPaint(canvas);
+ return 1;
+}
+
+void DownloadsList::newItem(int status, DownloadToken token)
+{
+ uint64_t total=0;
+ const char *url = 0;
+ api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token);
+ if (http)
+ {
+ total = http->content_length();
+ if (url == NULL)
+ {
+ url = http->get_url();//WAC_API_DOWNLOADMANAGER->GetUrl(token);
+ if (!url)
+ {
+ url = "";
+ }
+ }
+ }
+ else
+ {
+ url = "";
+ }
+
+ uint64_t downloaded = WAC_API_DOWNLOADMANAGER->GetBytesDownloaded(token);
+ wchar_t text[256] = {0};
+
+ if (total)
+ {
+ if (total == downloaded)
+ return; // Delete from list on skin-reload
+ }
+
+ StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded, total, _(L"bytes"));
+
+ switch (status)
+ {
+ case STATUS_WAITING:
+ insertItem(0, _(L"Waiting"), 0);
+ break;
+ case STATUS_TRANSFERRING:
+ insertItem(0, _(L"Transferring"), 0);
+ break;
+ case STATUS_FINISHED:
+ insertItem(0, _(L"Finished"), 0);
+ break;
+ case STATUS_ERROR:
+ insertItem(0, _(L"Error"), 0);
+ break;
+ default:
+ insertItem(0, L"", 0);
+ break;
+ }
+
+ setSubItem(0, 1, text);
+ setSubItem(0, 2, AutoWide(url));
+}
+
+/**
+ * Static Managing of downloadlist
+ * handled via callbacks from MediaDownloader
+ */
+void DownloadsList::onDownloadStart (const char *url, DownloadToken token)
+{
+ for(int i=0; i<skinObjects.getNumItems(); i++)
+ {
+ DownloadsList *tmp = skinObjects.enumItem(i);
+ tmp->newItem(STATUS_WAITING, token);
+ activeDownloads.addItem(token, 0); // dunno if we will need this later on...
+ }
+}
+
+void DownloadsList::onDownloadTick (DownloadToken token)
+{
+ int n = activeDownloads.searchItem(token);
+ if (n < 0) return;
+
+ uint64_t total=0;
+ api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token);
+ if (http)
+ {
+ total = http->content_length();
+ }
+
+ uint64_t downloaded = WAC_API_DOWNLOADMANAGER->GetBytesDownloaded(token);
+ uint64_t percent = 0;
+
+ wchar_t text[256] = {0};
+ wchar_t text2[64] = {0};
+
+ if (total)
+ {
+ percent=downloaded*100;
+ if (total)
+ percent/=total;
+ else
+ percent=0;
+ StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded/1024, total/1024, _(L"KB"));
+ StringCchPrintfW(text2, 64, L"%s %d%%", _(L"Transferring"), percent);
+ }
+ else
+ {
+ StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded, total, _(L"KB"));
+ StringCchPrintfW(text2, 64, _(L"Transferring"));
+ }
+
+ for(int i=0; i!=skinObjects.getNumItems(); i++)
+ {
+ DownloadsList *tmp = skinObjects.enumItem(i);
+
+ tmp->setSubItem(n, 1, text);
+ tmp->setItemLabel(n, text2);
+ }
+}
+
+void DownloadsList::onDownloadEnd (DownloadToken token, const wchar_t * filename)
+{
+ int n = activeDownloads.searchItem(token);
+ if (n < 0) return;
+
+ activeDownloads.setItem(NULL, n); // So we know the download is done!
+
+ wchar_t artist[256] = {0};
+ wchar_t title[256] = {0};
+ wa2.getMetaData(filename, L"artist", artist, 256);
+ wa2.getMetaData(filename, L"title", title, 256);
+
+ StringW display;
+ bool hasArtist = !!WCSICMP(artist, L"");
+ bool hasTitle= !!WCSICMP(title, L"");
+
+ StringW url = L"";
+
+ for(int i=0; i!=skinObjects.getNumItems(); i++)
+ {
+ DownloadsList *tmp = skinObjects.enumItem(i);
+
+ if (!WCSICMP(url, L""))
+ url = tmp->getSubitemText(n, 2);
+
+ tmp->setItemLabel(n, _(L"Finished"));
+ tmp->setSubItem(n, 2, filename);
+
+ if (!hasArtist && !hasTitle)
+ {
+ PathParserW pp(filename);
+ display = pp.getLastString();
+ }
+ else if (!hasArtist)
+ display = title;
+ else if (!hasTitle)
+ display = artist;
+ else
+ display = StringPrintfW(L"%s - %s",artist,title);
+
+ tmp->setSubItem(n, 3, display);
+ tmp->setItemParam(n, STATUS_FINISHED);
+ }
+}
+
+void DownloadsList::onDownloadCancel(DownloadToken token)
+{
+ int n = activeDownloads.searchItem(token);
+ if (n < 0) return;
+
+ activeDownloads.setItem(NULL, n); // So we know the download is done/cancelled!
+ const wchar_t * url = 0;
+
+ for(int i=0; i!=skinObjects.getNumItems(); i++)
+ {
+ DownloadsList *tmp = skinObjects.enumItem(i);
+ tmp->setItemLabel(n, _(L"Cancelled"));
+ if (!url) url = tmp->getSubitemText(n, 2);
+ }
+
+ SystemObject::onDownloadFinished((!url ? L"" : url), false, L"");
+}
+
+void DownloadsList::onDownloadError(DownloadToken token, int code)
+{
+ int n = activeDownloads.searchItem(token);
+ if (n < 0) return;
+
+ activeDownloads.setItem(NULL, n); // So we know the download is done/cancelled!
+
+ const wchar_t * url = 0;
+
+ for(int i=0; i!=skinObjects.getNumItems(); i++)
+ {
+ DownloadsList *tmp = skinObjects.enumItem(i);
+ wchar_t buf[64] = {0};
+ StringCchPrintfW(buf, 64, L"%s: %i", _(L"Error"), code);
+ tmp->setItemLabel(n, buf);
+ if (!url) url = tmp->getSubitemText(n, 2);
+ }
+
+ SystemObject::onDownloadFinished((!url ? L"" : url), false, L"");
+}
+
+PtrList<void> DownloadsList::activeDownloads;
+PtrList<DownloadsList> DownloadsList::skinObjects; \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/xuidownloadslist.h b/Src/Wasabi/api/skin/widgets/xuidownloadslist.h
new file mode 100644
index 00000000..88458462
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuidownloadslist.h
@@ -0,0 +1,77 @@
+#ifndef __THEMESLIST_H
+#define __THEMESLIST_H
+
+#include "api/wnd/wndclass/listwnd.h"
+#include "main.h"
+//#include "../Components/wac_downloads/wac_downloads_download_manager.h"
+#include "../../../../Components/wac_network/wac_network_http_receiver_api.h"
+#include "../nu/AutoWide.h"
+#include "api/script/objects/systemobj.h"
+
+#define DOWNLOADSLIST_PARENT ListWnd
+
+// -----------------------------------------------------------------------
+class DownloadsList : public DOWNLOADSLIST_PARENT
+{
+
+ public:
+
+ DownloadsList();
+ virtual ~DownloadsList();
+
+ virtual int onInit();
+ virtual void onDoubleClick(int itemnum);
+ virtual int onPaint(Canvas *canvas);
+ virtual int onRightClick(int itemnum);
+ virtual int onColumnDblClick(int col, int x, int y);
+ virtual int onColumnLabelClick(int col, int x, int y);
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+ virtual int onResize();
+ virtual int wantResizeCols() { return 0; }
+ virtual int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value);
+ virtual int wantHScroll() { return !nohscroll; }
+
+ // virtual int getTextBold(LPARAM lParam);
+ virtual void onSetVisible(int show);
+
+ // Callbacks from MediaDownloader
+ static void onDownloadStart(const char *url, DownloadToken token);
+ static void onDownloadTick(DownloadToken token);
+ static void onDownloadEnd(DownloadToken token, const wchar_t * filename);
+ static void onDownloadError(DownloadToken token, int code);
+ static void onDownloadCancel(DownloadToken token);
+
+ enum {
+ CTLIST_NOHSCROLL = 0,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+ static XMLParamPair params[];
+ int xuihandle;
+ int nohscroll;
+ int ensure_on_paint;
+
+ void newItem(int status, DownloadToken token);
+
+ static PtrList<void> activeDownloads;
+ static PtrList<DownloadsList> skinObjects;
+
+ enum DOWNLOAD_STATUS
+ {
+ STATUS_WAITING = 0,
+ STATUS_TRANSFERRING = 1,
+ STATUS_FINISHED = 2,
+ STATUS_ERROR = -1,
+ STATUS_CANCEL = -2,
+ };
+};
+
+// -----------------------------------------------------------------------
+extern const wchar_t DownloadsListXuiObjectStr[];
+extern char DownloadsListXuiSvcName[];
+class DownloadsListXuiSvc : public XuiObjectSvc<DownloadsList, DownloadsListXuiObjectStr, DownloadsListXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp b/Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp
new file mode 100644
index 00000000..4cdc2bd6
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuidropdownlist.cpp
@@ -0,0 +1,7 @@
+#include <precomp.h>
+#include "xuidropdownlist.h"
+
+// -----------------------------------------------------------------------
+const wchar_t DropDownListXuiObjectStr[] = L"Wasabi:DropDownList";
+char DropDownListXuiSvcName[] = "Wasabi:DropDownList xui object";
+
diff --git a/Src/Wasabi/api/skin/widgets/xuidropdownlist.h b/Src/Wasabi/api/skin/widgets/xuidropdownlist.h
new file mode 100644
index 00000000..6e4e55af
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuidropdownlist.h
@@ -0,0 +1,10 @@
+#ifndef __XUIDROPDOWNLIST_H
+#define __XUIDROPDOWNLIST_H
+
+#include <api/skin/widgets/dropdownlist.h>
+
+extern const wchar_t DropDownListXuiObjectStr[];
+extern char DropDownListXuiSvcName[];
+class DropDownListXuiSvc : public XuiObjectSvc<DropDownList, DropDownListXuiObjectStr, DropDownListXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuieditbox.cpp b/Src/Wasabi/api/skin/widgets/xuieditbox.cpp
new file mode 100644
index 00000000..22436de2
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuieditbox.cpp
@@ -0,0 +1,6 @@
+#include <precomp.h>
+#include "xuititlebox.h"
+
+char EditBoxXuiObjectStr[] = "Wasabi:EditBox";
+char EditBoxXuiSvcName[] = "Wasabi:EditBox xui object";
+
diff --git a/Src/Wasabi/api/skin/widgets/xuieditbox.h b/Src/Wasabi/api/skin/widgets/xuieditbox.h
new file mode 100644
index 00000000..6a9265ec
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuieditbox.h
@@ -0,0 +1,21 @@
+#ifndef __EDITBOX_H
+#define __EDITBOX_H
+
+#include <api/wnd/wndclass/embeddedxui.h>
+
+#define EDITBOX_PARENT EmbeddedXuiObject
+
+// -----------------------------------------------------------------------
+class EditBox : public EDITBOX_PARENT {
+ public:
+
+ virtual const wchar_t *embeddedxui_getContentId() { return "wasabi.edit"; }
+ virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return "wasabi.edit.box"; }
+};
+
+// -----------------------------------------------------------------------
+extern char EditBoxXuiObjectStr[];
+extern char EditBoxXuiSvcName[];
+class EditBoxXuiSvc : public XuiObjectSvc<EditBox, EditBoxXuiObjectStr, EditBoxXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuiframe.cpp b/Src/Wasabi/api/skin/widgets/xuiframe.cpp
new file mode 100644
index 00000000..919baad1
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiframe.cpp
@@ -0,0 +1,241 @@
+#include <precomp.h>
+#include "xuiframe.h"
+#include <tataki/canvas/ifc_canvas.h>
+#include <api/script/scriptguid.h>
+
+const wchar_t ScriptFrameXuiObjectStr[] = L"Wasabi:Frame"; // This is the xml tag
+char ScriptFrameXuiSvcName[] = "Wasabi:ScriptFrame xui object";
+XMLParamPair ScriptFrame::params[] = {
+ {SCRIPTFRAME_SETORIENTATION, L"ORIENTATION"},
+ {SCRIPTFRAME_SETLEFT, L"LEFT"}, // TOP/BOTTOM IS ALIAS FOR LEFT/RIGHT
+ {SCRIPTFRAME_SETLEFT, L"TOP"},
+ {SCRIPTFRAME_SETRIGHT, L"RIGHT"},
+ {SCRIPTFRAME_SETRIGHT, L"BOTTOM"},
+ {SCRIPTFRAME_SETFROM, L"FROM"},
+ {SCRIPTFRAME_SETWIDTH, L"WIDTH"},
+ {SCRIPTFRAME_SETWIDTH, L"HEIGHT"}, // HEIGHT IS AN ALIAS FOR WIDTH
+ {SCRIPTFRAME_SETRESIZEABLE, L"RESIZABLE"},
+ {SCRIPTFRAME_SETMAXWIDTH, L"MAXWIDTH"},
+ {SCRIPTFRAME_SETMAXWIDTH, L"MAXHEIGHT"}, //ALIAS
+ {SCRIPTFRAME_SETMINWIDTH, L"MINWIDTH"},
+ {SCRIPTFRAME_SETMINWIDTH, L"MINHEIGHT"}, //ALIAS
+ {SCRIPTFRAME_SETV_BITMAP, L"VBITMAP"}, // to override wasabi.framewnd.verticaldivider
+ {SCRIPTFRAME_SETV_GRABBER, L"VGRABBER"}, // to override wasabi.framewnd.verticalgrabber
+};
+
+ScriptFrame::ScriptFrame()
+{
+ getScriptObject()->vcpu_setInterface(scriptFrameGuid, (void *)static_cast<ScriptFrame *>(this));
+ getScriptObject()->vcpu_setClassName(L"Frame");
+ getScriptObject()->vcpu_setController(frameController);
+
+ setVirtual(1);
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ orientation = DIVIDER_VERTICAL;
+ from = SDP_FROMLEFT;
+ resizable = 1;
+ width = 128;
+ rootwndleft = rootwndright = NULL;
+}
+
+void ScriptFrame::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTFRAME_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ScriptFrame::~ScriptFrame() {
+ if (rootwndright) {
+ WASABI_API_SKIN->group_destroy(rootwndright);
+ rootwndright = NULL;
+ }
+ if (rootwndleft) {
+ WASABI_API_SKIN->group_destroy(rootwndleft);
+ rootwndleft = NULL;
+ }
+}
+
+// XuiObject automatically calls this back for all parameters registered using addParam
+// encountered in the xml source
+int ScriptFrame::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+
+ if (xuihandle != myxuihandle)
+ return SCRIPTFRAME_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case SCRIPTFRAME_SETORIENTATION: setOrientation(value); break;
+ case SCRIPTFRAME_SETLEFT: setLeft(value); break;
+ case SCRIPTFRAME_SETRIGHT: setRight(value); break;
+ case SCRIPTFRAME_SETFROM: setFrom(value); break;
+ case SCRIPTFRAME_SETWIDTH: setWidth(value); break;
+ case SCRIPTFRAME_SETRESIZEABLE: setResize(value); break;
+ case SCRIPTFRAME_SETMAXWIDTH: setMaxWidth((!_wcsicmp(value, L"null")) ? 0 : WTOI(value)); break;
+ case SCRIPTFRAME_SETMINWIDTH: setMinWidth(WTOI(value)); break;
+ case SCRIPTFRAME_SETSNAP: setSnap(WTOI(value)); break;
+ case SCRIPTFRAME_SETV_BITMAP:
+ Set_v_bitmap(value);
+ break;
+ case SCRIPTFRAME_SETV_GRABBER:
+ Set_v_grabber(value);
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int ScriptFrame::onInit()
+{
+
+ if (!left.isempty()) rootwndleft = WASABI_API_SKIN->group_create(left);
+ if (!right.isempty()) rootwndright = WASABI_API_SKIN->group_create(right);
+
+/* GuiObject *gl = rootwndleft ? static_cast<GuiObject *>(rootwndleft->getInterface(guiObjectGuid)) : NULL;
+ GuiObject *gr = rootwndright ? static_cast<GuiObject *>(rootwndleft->getInterface(guiObjectGuid)) : NULL;
+
+ if (gl) gl->guiobject_setParentGroup(getGuiObject()->guiobject_getParentGroup());
+ if (gr) gr->guiobject_setParentGroup(getGuiObject()->guiobject_getParentGroup());*/
+
+ if (rootwndleft) rootwndleft->setParent(this);
+ if (rootwndright) rootwndright->setParent(this);
+
+ setChildrenRootWnd(rootwndleft, rootwndright);
+ setDividerType(static_cast<FrameWndDividerType>(orientation));
+ setDividerPos(from, width);
+ setResizeable(resizable);
+
+
+ SCRIPTFRAME_PARENT::onInit();
+ return 1;
+}
+
+void ScriptFrame::onResizeChildren(RECT leftr, RECT rightr) {
+/* if (rootwndleft) rootwndleft->invalidate();
+ if (rootwndright) rootwndright->invalidate();*/
+ invalidate();
+}
+
+void ScriptFrame::setOrientation(const wchar_t *orient) {
+ if (!WCSICMP(orient, L"v") || !WCSICMP(orient, L"vertical"))
+ orientation = DIVIDER_VERTICAL;
+ if (!WCSICMP(orient, L"h") || !WCSICMP(orient, L"horizontal"))
+ orientation = DIVIDER_HORIZONTAL;
+}
+
+void ScriptFrame::setLeft(const wchar_t *groupname) {
+ left = groupname;
+}
+
+void ScriptFrame::setRight(const wchar_t *groupname) {
+ right = groupname;
+}
+
+void ScriptFrame::setFrom(const wchar_t *f) {
+ if (!WCSICMP(f, L"l") || !WCSICMP(f, L"left") || !WCSICMP(f, L"t") || !WCSICMP(f, L"top"))
+ from = SDP_FROMLEFT;
+ if (!WCSICMP(f, L"r") || !WCSICMP(f, L"right") || !WCSICMP(f, L"b") || !WCSICMP(f, L"bottom"))
+ from = SDP_FROMRIGHT;
+}
+
+void ScriptFrame::setWidth(const wchar_t *w) {
+ width = WTOI(w);
+}
+
+void ScriptFrame::setResize(const wchar_t *w) {
+ resizable = WTOI(w);
+ if (isInited())
+ setResizeable(resizable);
+}
+
+FrameScriptController _frameController;
+FrameScriptController *frameController = &_frameController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct FrameScriptController::exportedFunction[] =
+{
+ {L"setPosition", 1, (void*)ScriptFrame::script_vcpu_setPosition },
+ {L"getPosition", 0, (void*)ScriptFrame::script_vcpu_getPosition },
+};
+// --------------------------------------------------------
+
+const wchar_t *FrameScriptController::getClassName()
+{
+ return L"Frame";
+}
+
+const wchar_t *FrameScriptController::getAncestorClassName()
+{
+ return L"GuiObject";
+}
+
+ScriptObject *FrameScriptController::instantiate()
+{
+ ScriptFrame *t = new ScriptFrame;
+ ASSERT(t != NULL);
+ return t->getScriptObject();
+}
+
+void FrameScriptController::destroy(ScriptObject *o)
+{
+ ScriptFrame *t = static_cast<ScriptFrame *>(o->vcpu_getInterface(scriptFrameGuid));
+ ASSERT(t != NULL);
+ delete t;
+}
+
+void *FrameScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for Wasabi:Frame yet
+}
+
+void FrameScriptController::deencapsulate(void *o)
+{}
+
+int FrameScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *FrameScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID FrameScriptController::getClassGuid()
+{
+ return scriptFrameGuid;
+}
+
+const wchar_t *ScriptFrame::vcpu_getClassName()
+{
+ return L"Frame";
+}
+
+scriptVar ScriptFrame::script_vcpu_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(t.type == SCRIPT_INT);
+ ScriptFrame *fr = static_cast<ScriptFrame *>(o->vcpu_getInterface(scriptFrameGuid));
+ if (fr)
+ fr->setDividerPosNoCfg(fr->from, ::GET_SCRIPT_INT(t));
+
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptFrame::script_vcpu_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptFrame *fr = static_cast<ScriptFrame *>(o->vcpu_getInterface(scriptFrameGuid));
+ if (fr)
+ {
+ int pos, from;
+ fr->getDividerPos(&from, &pos);
+ return MAKE_SCRIPT_INT(pos);
+ }
+ return MAKE_SCRIPT_INT(0);
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuiframe.h b/Src/Wasabi/api/skin/widgets/xuiframe.h
new file mode 100644
index 00000000..0a16e4b4
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiframe.h
@@ -0,0 +1,97 @@
+#ifndef __XUIFRAME_H
+#define __XUIFRAME_H
+
+#include <api/wnd/wndclass/framewnd.h>
+#include <api/script/objects/guiobj.h>
+
+#define SCRIPTFRAME_PARENT FrameWnd
+
+/* --------- Script Object for ScriptFrame --------- */
+class FrameScriptController : public GuiObjectScriptController
+{
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return guiController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern FrameScriptController *frameController;
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+
+class ScriptFrame : public SCRIPTFRAME_PARENT {
+
+ public:
+
+ ScriptFrame();
+ virtual ~ScriptFrame();
+
+ virtual int onInit();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setOrientation(const wchar_t *elementname);
+ void setLeft(const wchar_t *groupname);
+ void setRight(const wchar_t *groupname);
+ void setFrom(const wchar_t *from);
+ void setWidth(const wchar_t *w);
+ void setResize(const wchar_t *r);
+
+ virtual int wantRenderBaseTexture() { return 0; }
+
+ void onResizeChildren(RECT leftr, RECT rightr);
+
+ virtual const wchar_t *vcpu_getClassName();
+ virtual ScriptObjectController *vcpu_getController() { return frameController; }
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ // a list of IDs for our xml attributes, we use them in addParam() in the constructor
+ enum {
+ SCRIPTFRAME_SETORIENTATION = 0,
+ SCRIPTFRAME_SETLEFT,
+ SCRIPTFRAME_SETRIGHT,
+ SCRIPTFRAME_SETFROM,
+ SCRIPTFRAME_SETWIDTH,
+ SCRIPTFRAME_SETRESIZEABLE,
+ SCRIPTFRAME_SETMAXWIDTH,
+ SCRIPTFRAME_SETMINWIDTH,
+ SCRIPTFRAME_SETSNAP,
+ SCRIPTFRAME_SETV_BITMAP,
+ SCRIPTFRAME_SETV_GRABBER,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+ StringW left, right;
+ ifc_window *rootwndleft, *rootwndright;
+ int from, orientation, resizable;
+ int width;
+ public:
+ static scriptVar script_vcpu_setPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar t);
+ static scriptVar script_vcpu_getPosition(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+extern const wchar_t ScriptFrameXuiObjectStr[];
+extern char ScriptFrameXuiSvcName[];
+class FrameXuiSvc : public XuiObjectSvc<ScriptFrame, ScriptFrameXuiObjectStr, ScriptFrameXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp b/Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp
new file mode 100644
index 00000000..141e6e48
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuigradientwnd.cpp
@@ -0,0 +1,66 @@
+#include <precomp.h>
+
+#include "xuigradientwnd.h"
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(XuiGradient_Svc);
+DECLARE_SERVICE(XuiObjectCreator<GradientWndXuiSvc>);
+END_SERVICES(XuiGradient_Svc, _XuiGradient_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_GradientXuiSvc; }
+#else
+extern "C" { int __link_GradientXuiSvc; }
+#endif
+
+#endif
+
+
+enum { P_X1, P_Y1, P_X2, P_Y2, P_POINTS, P_GG };
+
+XMLParamPair XuiGradientWnd::params[] = {
+ {P_X1, L"GRADIENT_X1"},
+ {P_Y1, L"GRADIENT_Y1"},
+ {P_X2, L"GRADIENT_X2"},
+ {P_Y2, L"GRADIENT_Y2"},
+ {P_POINTS, L"POINTS"},
+ {P_GG, L"GAMMAGROUP"},
+ };
+XuiGradientWnd::XuiGradientWnd()
+{
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+void XuiGradientWnd::CreateXMLParameters(int master_handle)
+{
+ //XUIGRADIENTWND_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ {
+ if (params[i].id == P_GG)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+ else
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_REQUIRED);
+ }
+}
+
+int XuiGradientWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return XUIGRADIENTWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+ switch (xmlattributeid)
+ {
+ case P_X1: setX1((float)WTOF(value)); break;
+ case P_Y1: setY1((float)WTOF(value)); break;
+ case P_X2: setX2((float)WTOF(value)); break;
+ case P_Y2: setY2((float)WTOF(value)); break;
+ case P_POINTS: setPoints(value); break;
+ case P_GG: setGammaGroup(value); break;
+ default:
+ return 0;
+ }
+ invalidate(); // what the hell
+ return 1;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/xuigradientwnd.h b/Src/Wasabi/api/skin/widgets/xuigradientwnd.h
new file mode 100644
index 00000000..36aaed84
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuigradientwnd.h
@@ -0,0 +1,26 @@
+#ifndef _XUIGRADIENTWND_H
+#define _XUIGRADIENTWND_H
+
+#include <api/wnd/wndclass/gradientwnd.h>
+
+#define XUIGRADIENTWND_PARENT GradientWnd
+class XuiGradientWnd : public XUIGRADIENTWND_PARENT {
+public:
+ static const wchar_t *xuiobject_getXmlTag() { return L"Gradient"; }
+ static const char *xuiobject_getServiceName() { return "Gradient XuiObject"; }
+ XuiGradientWnd();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void parsePoints(const wchar_t *pointlist);
+protected:
+ void CreateXMLParameters(int master_handle);
+private:
+ int myxuihandle;
+ static XMLParamPair params[];
+
+};
+
+class GradientWndXuiSvc : public XuiObjectSvc2<XuiGradientWnd> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuigrid.cpp b/Src/Wasabi/api/skin/widgets/xuigrid.cpp
new file mode 100644
index 00000000..4961a0ad
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuigrid.cpp
@@ -0,0 +1,297 @@
+#include <precomp.h>
+#include "xuigrid.h"
+#include <tataki/canvas/canvas.h>
+// -----------------------------------------------------------------------
+
+const wchar_t GridXuiObjectStr[] = L"Grid"; // xml tag
+char GridXuiSvcName[] = "Grid xui object";
+
+XMLParamPair Grid::params[] = {
+ { GRID_SETTOPLEFT, L"TOPLEFT"},
+ { GRID_SETTOP, L"TOP"},
+ { GRID_SETTOPRIGHT, L"TOPRIGHT"},
+ { GRID_SETLEFT, L"LEFT"},
+ { GRID_SETMIDDLE, L"MIDDLE"},
+ { GRID_SETRIGHT, L"RIGHT"},
+ { GRID_SETBOTTOMLEFT, L"BOTTOMLEFT"},
+ { GRID_SETBOTTOM, L"BOTTOM"},
+ { GRID_SETBOTTOMRIGHT, L"BOTTOMRIGHT"},
+};
+// -----------------------------------------------------------------------
+Grid::Grid() {
+ setRectRgn(1);
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+}
+
+void Grid::CreateXMLParameters(int master_handle)
+{
+ //GRID_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+Grid::~Grid() {
+}
+
+// -----------------------------------------------------------------------
+int Grid::onInit() {
+ GRID_PARENT::onInit();
+ doPaint(NULL, 1); // computes the region
+ invalidateWindowRegion();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int Grid::onResize() {
+ GRID_PARENT::onResize();
+ doPaint(NULL, 1);
+ invalidateWindowRegion();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int Grid::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return GRID_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case GRID_SETTOPLEFT:
+ case GRID_SETTOP:
+ case GRID_SETTOPRIGHT:
+ case GRID_SETLEFT:
+ case GRID_SETMIDDLE:
+ case GRID_SETRIGHT:
+ case GRID_SETBOTTOMLEFT:
+ case GRID_SETBOTTOM:
+ case GRID_SETBOTTOMRIGHT:
+ setGridImage(value, xmlattributeid);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void Grid::setGridImage(const wchar_t *elementname, int what) {
+ switch (what) {
+ case GRID_SETTOPLEFT: topleft = elementname; break;
+ case GRID_SETTOP: top = elementname; break;
+ case GRID_SETTOPRIGHT: topright = elementname; break;
+ case GRID_SETLEFT: left = elementname; break;
+ case GRID_SETMIDDLE: middle = elementname; break;
+ case GRID_SETRIGHT: right = elementname; break;
+ case GRID_SETBOTTOMLEFT: bottomleft = elementname; break;
+ case GRID_SETBOTTOM: bottom = elementname; break;
+ case GRID_SETBOTTOMRIGHT: bottomright = elementname; break;
+ default: return;
+ }
+ if (isInited()) invalidate();
+}
+
+// -----------------------------------------------------------------------
+int Grid::onPaint(Canvas *canvas) {
+ GRID_PARENT::onPaint(canvas);
+
+ doPaint(canvas, 0);
+
+ return 1;
+}
+
+
+void Grid::doPaint(Canvas *canvas, int dorgn) {
+
+ RECT r;
+ getGridRect(&r);
+
+ SkinBitmap *left_bm = left.getBitmap();
+ SkinBitmap *middle_bm = middle.getBitmap();
+ SkinBitmap *right_bm = right.getBitmap();
+
+ SkinBitmap *topleft_bm = topleft.getBitmap();
+ SkinBitmap *top_bm = top.getBitmap();
+ SkinBitmap *topright_bm = topright.getBitmap();
+
+ SkinBitmap *bottomleft_bm = bottomleft.getBitmap();
+ SkinBitmap *bottom_bm = bottom.getBitmap();
+ SkinBitmap *bottomright_bm = bottomright.getBitmap();
+
+ int left_w = left_bm ? left_bm->getWidth() : 0;
+ int left_h = left_bm ? left_bm->getHeight() : 0;
+ int top_h = top_bm ? top_bm->getHeight() : 0;
+ int top_w = top_bm ? top_bm->getWidth() : 0;
+ int topleft_h = topleft_bm ? topleft_bm->getHeight() : 0;
+ int topright_h = topright_bm ? topright_bm->getHeight() : 0;
+ int topleft_w = topleft_bm ? topleft_bm->getWidth() : 0;
+ int topright_w = topright_bm ? topright_bm->getWidth() : 0;
+ int right_w = right_bm ? right_bm->getWidth() : 0;
+ int right_h = right_bm ? right_bm->getHeight() : 0;
+ int bottom_h = bottom_bm ? bottom_bm->getHeight() : 0;
+ int bottom_w = bottom_bm ? bottom_bm->getWidth() : 0;
+ int bottomleft_h = bottomleft_bm ? bottom_bm->getHeight() : 0;
+ int bottomright_h = bottomright_bm ? bottom_bm->getHeight() : 0;
+ int bottomleft_w = bottomleft_bm ? bottomleft_bm->getWidth() : 0;
+ int bottomright_w = bottomright_bm ? bottomright_bm->getWidth() : 0;
+ int middle_w = middle_bm ? middle_bm->getWidth() : 0;
+ int middle_h = middle_bm ? middle_bm->getHeight() : 0;
+
+ RECT cell;
+
+ if (dorgn) reg.empty();
+
+ int paintingAlpha = 0;
+ if (canvas)
+ paintingAlpha = getPaintingAlpha();
+
+ // topleft
+ if (topleft_bm) {
+ cell.left = r.left;
+ cell.top = r.top;
+ cell.right = cell.left + topleft_w;
+ cell.bottom = r.top + topleft_h;
+
+ if (canvas) topleft_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn) {
+ RegionI _r(topleft);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // top
+ if (top_bm) {
+ cell.left = r.left + topleft_w;
+ cell.top = r.top;
+ cell.right = r.right - topright_w;
+ cell.bottom = r.top + top_h;
+
+ if (canvas) top_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn && cell.left != cell.right) {
+ RegionI _r(top);
+ _r.scale((double)(cell.right-cell.left) / top_w, 1);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // topright
+
+ if (topright_bm) {
+ cell.left = r.right - topright_w;
+ cell.top = r.top;
+ cell.right = r.right;
+ cell.bottom = r.top + topright_h;
+
+ if (canvas) topright_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn) {
+ RegionI _r(topright);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // left
+
+ if (left_bm) {
+ cell.left = r.left;
+ cell.top = r.top + topleft_h;
+ cell.right = r.left + left_w;
+ cell.bottom = r.bottom - bottomleft_h;
+
+ if (canvas) left_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn && cell.bottom != cell.top) {
+ RegionI _r(left);
+ _r.scale(1, (double)(cell.bottom-cell.top) / left_h);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // middle
+
+ if (middle_bm) {
+ cell.left = r.left + left_w;
+ cell.top = r.top + top_h;
+ cell.right = r.right - right_w;
+ cell.bottom = r.bottom - bottom_h;
+
+ if (canvas) middle_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn && cell.left != cell.right && cell.bottom != cell.top) {
+ RegionI _r(middle);
+ _r.scale((double)(cell.right-cell.left) / middle_w, (double)(cell.bottom-cell.top) / middle_h);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // right
+
+ if (right_bm) {
+ cell.left = r.right - right_w;
+ cell.top = r.top + top_h;
+ cell.right = r.right;
+ cell.bottom = r.bottom - bottomright_h;
+
+ if (canvas) right_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn && cell.bottom != cell.top) {
+ RegionI _r(right);
+ _r.scale(1, (double)(cell.bottom-cell.top) / right_h);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // bottomleft
+
+ if (bottomleft_bm) {
+ cell.left = r.left;
+ cell.top = r.bottom - bottomleft_h;
+ cell.right = r.left + bottomleft_w;
+ cell.bottom = r.bottom;
+
+ if (canvas) bottomleft_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn) {
+ RegionI _r(bottomleft);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // bottom
+
+ if (bottom_bm) {
+ cell.left = r.left + bottomleft_w;
+ cell.top = r.bottom - bottom_h;
+ cell.right = r.right - bottomright_w;
+ cell.bottom = r.bottom;
+
+ if (canvas) bottom_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn && cell.right != cell.left) {
+ RegionI _r(bottom);
+ _r.scale((double)(cell.right-cell.left) / bottom_w, 1);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+
+ // bottomright
+
+ if (bottomright_bm) {
+ cell.left = r.right - bottomright_w;
+ cell.top = r.bottom - bottomright_h;
+ cell.right = r.right;
+ cell.bottom = r.bottom;
+
+ if (canvas) bottomright_bm->stretchToRectAlpha(canvas, &cell, paintingAlpha);
+ if (dorgn) {
+ RegionI _r(bottomright);
+ _r.offset(cell.left-r.left, cell.top-r.top);
+ reg.addRegion(&_r);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/xuigrid.h b/Src/Wasabi/api/skin/widgets/xuigrid.h
new file mode 100644
index 00000000..084c7d4c
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuigrid.h
@@ -0,0 +1,59 @@
+#ifndef __GRID_H
+#define __GRID_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <tataki/region/region.h>
+
+#define GRID_PARENT GuiObjectWnd
+
+// -----------------------------------------------------------------------
+class Grid : public GRID_PARENT {
+
+ public:
+
+ Grid();
+ virtual ~Grid();
+
+ virtual int onPaint(Canvas *c);
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setGridImage(const wchar_t *elementname, int what);
+ virtual void getGridRect(RECT *r) { getClientRect(r); }
+
+ virtual api_region *getRegion() { return &reg; }
+ virtual int onInit();
+ virtual int onResize();
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+ void doPaint(Canvas *canvas, int dorgn=0);
+
+ enum {
+ GRID_SETTOPLEFT= 0,
+ GRID_SETTOP,
+ GRID_SETTOPRIGHT,
+ GRID_SETLEFT,
+ GRID_SETMIDDLE,
+ GRID_SETRIGHT,
+ GRID_SETBOTTOMLEFT,
+ GRID_SETBOTTOM,
+ GRID_SETBOTTOMRIGHT,
+ };
+ static XMLParamPair params[];
+
+ int myxuihandle;
+
+ AutoSkinBitmap topleft, top, topright;
+ AutoSkinBitmap left, middle, right;
+ AutoSkinBitmap bottomleft, bottom, bottomright;
+ RegionI reg;
+};
+
+
+// -----------------------------------------------------------------------
+extern const wchar_t GridXuiObjectStr[];
+extern char GridXuiSvcName[];
+class GridXuiSvc : public XuiObjectSvc<Grid, GridXuiObjectStr, GridXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp b/Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp
new file mode 100644
index 00000000..c5c7e72b
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuigroupxfade.cpp
@@ -0,0 +1,120 @@
+#include <precomp.h>
+#include "xuigroupxfade.h"
+
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(GroupXFade_Svc);
+DECLARE_SERVICE(XuiObjectCreator<GroupXFadeXuiSvc>);
+END_SERVICES(GroupXFade_Svc, _GroupXFade_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_GroupXFadeXuiSvc; }
+#else
+extern "C" { int __link_GroupXFadeXuiSvc; }
+#endif
+
+#endif
+
+
+
+XMLParamPair GroupXFade::params[] = {
+ {GROUPXFADE_SETGROUP, L"GROUP"},
+ {GROUPXFADE_SETGROUP, L"GROUPID"},
+ {GROUPXFADE_SETSPEED, L"SPEED"},
+ };
+GroupXFade::GroupXFade() {
+ child[0] = child[1] = NULL;
+ curchild = 0;
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+ speed = 0.25;
+}
+
+void GroupXFade::CreateXMLParameters(int master_handle)
+{
+ //GROUPXFADE_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+
+}
+
+GroupXFade::~GroupXFade() {
+ if (child[0]) {
+ ifc_window *w = child[0]->guiobject_getRootWnd();
+ if (w) WASABI_API_SKIN->group_destroy(w);
+ }
+ if (child[1]) {
+ ifc_window *w = child[1]->guiobject_getRootWnd();
+ if (w) WASABI_API_SKIN->group_destroy(w);
+ }
+}
+
+int GroupXFade::onInit() {
+ GROUPXFADE_PARENT::onInit();
+ return 1;
+}
+
+int GroupXFade::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return GROUPXFADE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch(xmlattributeid) {
+ case GROUPXFADE_SETGROUP:
+ setNewGroup(value);
+ return 1;
+ case GROUPXFADE_SETSPEED:
+ speed = WTOF(value);
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int GroupXFade::onResize() {
+ GROUPXFADE_PARENT::onResize();
+ RECT r;
+ getClientRect(&r);
+ if (child[curchild])
+ child[curchild]->guiobject_getRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ int nextchild = curchild == 1 ? 0 : 1;
+ if (child[nextchild])
+ child[nextchild]->guiobject_getRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ return 1;
+}
+
+void GroupXFade::setNewGroup(const wchar_t *grp) {
+ if (child[curchild] && id[curchild].iscaseequal(grp)) return;
+ if (child[curchild]) {
+ child[curchild]->guiobject_setTargetA(0);
+ child[curchild]->guiobject_setTargetSpeed((float)speed);
+ child[curchild]->guiobject_gotoTarget();
+ }
+ int nextchild = curchild == 1 ? 0 : 1;
+ if (child[nextchild]) {
+ ifc_window *w = child[nextchild]->guiobject_getRootWnd();
+ WASABI_API_SKIN->group_destroy(w);
+ child[nextchild] = NULL;
+ }
+ if (grp && *grp) {
+ ifc_window *w = WASABI_API_SKIN->group_create(grp);
+ if (w) {
+ child[nextchild] = w->getGuiObject();
+ w->setParent(this);
+ w->setStartHidden(1);
+ RECT r;
+ getClientRect(&r);
+ w->setAlpha(0);
+ w->init(this);
+ w->setVisible(1);
+ w->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ child[nextchild]->guiobject_setTargetA(255);
+ child[nextchild]->guiobject_setTargetSpeed((float)speed);
+ child[nextchild]->guiobject_gotoTarget();
+ id[nextchild] = grp;
+ }
+ }
+ curchild = nextchild;
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuigroupxfade.h b/Src/Wasabi/api/skin/widgets/xuigroupxfade.h
new file mode 100644
index 00000000..50154ec5
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuigroupxfade.h
@@ -0,0 +1,40 @@
+#ifndef _XUIGROUPXFADE_H
+#define _XUIGROUPXFADE_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define GROUPXFADE_PARENT GuiObjectWnd
+class GroupXFade : public GROUPXFADE_PARENT {
+public:
+ static const wchar_t *xuiobject_getXmlTag() { return L"GroupXFade"; }
+ static const char *xuiobject_getServiceName() { return "GroupXFade XuiObject"; }
+ GroupXFade();
+ virtual ~GroupXFade();
+
+ virtual int onInit();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+ virtual int onResize();
+
+ enum {
+ GROUPXFADE_SETGROUP,
+ GROUPXFADE_SETSPEED,
+ };
+
+ void setNewGroup(const wchar_t *grp);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ int myxuihandle;
+ GuiObject *child[2];
+ StringW id[2];
+ int curchild;
+ double speed;
+
+ static XMLParamPair params[];
+};
+
+
+class GroupXFadeXuiSvc : public XuiObjectSvc2<GroupXFade> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuihideobject.cpp b/Src/Wasabi/api/skin/widgets/xuihideobject.cpp
new file mode 100644
index 00000000..76ff6b6d
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuihideobject.cpp
@@ -0,0 +1,50 @@
+#include <precomp.h>
+#include "xuihideobject.h"
+// -----------------------------------------------------------------------
+const wchar_t HideObjectXuiObjectStr[] = L"HideObject"; // This is the xml tag
+char HideObjectXuiSvcName[] = "HideObject xui object";
+
+XMLParamPair HideObject::params[] = {
+ { HIDEOBJECT_HIDE, L"HIDE"},
+};
+// -----------------------------------------------------------------------
+HideObject::HideObject() : HIDEOBJECT_PARENT()
+{
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+void HideObject::CreateXMLParameters(int master_handle)
+{
+ //HIDEOBJECT_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+
+// -----------------------------------------------------------------------
+int HideObject::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return HIDEOBJECT_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case HIDEOBJECT_HIDE:
+ actuator_setTarget(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void HideObject::actuator_onPerform(GuiObject *target) { // guaranteed non NULL
+ ifc_window *w = target->guiobject_getRootWnd();
+ if (w != NULL) {
+ w->setVisible(0);
+ }
+}
+
+
diff --git a/Src/Wasabi/api/skin/widgets/xuihideobject.h b/Src/Wasabi/api/skin/widgets/xuihideobject.h
new file mode 100644
index 00000000..b58a04da
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuihideobject.h
@@ -0,0 +1,40 @@
+#ifndef __HIDEOBJECT_H
+#define __HIDEOBJECT_H
+
+#include <api/skin/objectactuator.h>
+
+#define HIDEOBJECT_PARENT ObjectActuator
+
+extern const wchar_t HideObjectXuiObjectStr[];
+extern char HideObjectXuiSvcName[];
+// -----------------------------------------------------------------------
+// Your wnd object class
+class HideObject: public HIDEOBJECT_PARENT {
+
+ public:
+
+ HideObject();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void actuator_onPerform(GuiObject *target);
+ virtual const wchar_t *getActuatorTag() { return HideObjectXuiObjectStr; } // for error msgs purposes
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ int myxuihandle;
+
+ enum {
+ HIDEOBJECT_HIDE= 0,
+ };
+ static XMLParamPair params[];
+
+};
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+class HideObjectXuiSvc : public XuiObjectSvc<HideObject, HideObjectXuiObjectStr, HideObjectXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp b/Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp
new file mode 100644
index 00000000..04a13e90
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuihistoryedit.cpp
@@ -0,0 +1,7 @@
+#include <precomp.h>
+#include "xuihistoryedit.h"
+
+// -----------------------------------------------------------------------
+const wchar_t HistoryEditXuiObjectStr[] = L"Wasabi:HistoryEditBox";
+char HistoryEditXuiSvcName[] = "Wasabi:HistoryEditBox xui object";
+
diff --git a/Src/Wasabi/api/skin/widgets/xuihistoryedit.h b/Src/Wasabi/api/skin/widgets/xuihistoryedit.h
new file mode 100644
index 00000000..be15d407
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuihistoryedit.h
@@ -0,0 +1,10 @@
+#ifndef __XUIHISTORYEDITBOX_H
+#define __XUIHISTORYEDITBOX_H
+
+#include <api/skin/widgets/historyeditbox.h>
+
+extern const wchar_t HistoryEditXuiObjectStr[];
+extern char HistoryEditXuiSvcName[];
+class HistoryEditXuiSvc : public XuiObjectSvc<HistoryEditBox, HistoryEditXuiObjectStr, HistoryEditXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuilist.cpp b/Src/Wasabi/api/skin/widgets/xuilist.cpp
new file mode 100644
index 00000000..c8233409
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuilist.cpp
@@ -0,0 +1,1734 @@
+#include <precomp.h>
+#include "xuilist.h"
+
+#include <api/service/svc_enum.h>
+#include <bfc/parse/paramparser.h>
+#include <api/script/scriptguid.h>
+#include <api/skin/feeds/TextFeedEnum.h>
+
+// The temporary memory buffer to hold our string returns.
+StringW GuiListScriptController::staticStr;
+
+
+// -----------------------------------------------------------------------
+const wchar_t ScriptListXuiObjectStr[] = L"List"; // This is the xml tag
+char ScriptListXuiSvcName[] = "List xui object";
+
+
+XMLParamPair ScriptList::params[] = {
+ {SCRIPTLIST_SETITEMS, L"ITEMS"},
+ {SCRIPTLIST_SETMULTISELECT, L"MULTISELECT"},
+ {SCRIPTLIST_SETAUTODESELECT, L"AUTODESELECT"},
+ {SCRIPTLIST_SELECT, L"SELECT"},
+ {SCRIPTLIST_FEED, L"FEED"},
+ {SCRIPTLIST_HOVERSELECT, L"HOVERSELECT"},
+ {SCRIPTLIST_SORT, L"SORT"},
+ {SCRIPTLIST_SELECTONUPDOWN, L"SELECTONUPDOWN"},
+ {SCRIPTLIST_NUMCOLUMNS, L"NUMCOLUMNS"},
+ {SCRIPTLIST_COLUMNWIDTHS, L"COLUMNWIDTHS"},
+ {SCRIPTLIST_COLUMNLABELS, L"COLUMNLABELS"},
+ };
+// -----------------------------------------------------------------------
+ScriptList::ScriptList()
+{
+ getScriptObject()->vcpu_setInterface(guilistGuid, (void *)static_cast<ScriptList *>(this));
+ getScriptObject()->vcpu_setClassName(L"GuiList"); // this is the script class name
+ getScriptObject()->vcpu_setController(guiListController);
+
+
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+ setPreventMultipleSelection(1);
+ setVirtual(0);
+ feed = NULL;
+ multiselect = 0;
+ xmlnumcolumns = -1;
+ last_numcolumns = 0x80000000; // go ahead and try and be equal to that.
+ getGuiObject()->guiobject_getScriptObject()->vcpu_setInterface(listGuid, (void *)this);
+}
+
+void ScriptList::CreateXMLParameters(int master_handle)
+{
+ SCRIPTLIST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ScriptList::~ScriptList()
+{
+ closeFeed();
+}
+
+// -----------------------------------------------------------------------
+int ScriptList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return SCRIPTLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case SCRIPTLIST_SETITEMS:
+ items = value;
+ fillFromParams();
+#ifdef WASABI_COMPILE_CONFIG
+ if (getGuiObject()->guiobject_hasCfgAttrib())
+ selectFromConfig();
+#endif
+ break;
+ case SCRIPTLIST_SETMULTISELECT:
+ multiselect = WTOI(value);
+ break;
+ case SCRIPTLIST_SETAUTODESELECT:
+ setWantAutoDeselect(WTOI(value));
+ break;
+ case SCRIPTLIST_SELECT:
+ {
+ int i = selectEntry(value);
+ if (i != -1)
+ ensureItemVisible(i);
+ else
+ selectFirstEntry();
+ break;
+ }
+ case SCRIPTLIST_FEED:
+ {
+ closeFeed();
+ openFeed(value);
+ break;
+ }
+ case SCRIPTLIST_HOVERSELECT:
+ {
+ setHoverSelect(WTOI(value));
+ break;
+ }
+ case SCRIPTLIST_SORT:
+ {
+ setAutoSort(WTOB(value));
+ break;
+ }
+ case SCRIPTLIST_SELECTONUPDOWN:
+ {
+ setSelectOnUpDown(WTOI(value));
+ break;
+ }
+ case SCRIPTLIST_NUMCOLUMNS:
+ {
+ xmlnumcolumns = WTOI(value);
+ setNumColumns();
+ break;
+ }
+ case SCRIPTLIST_COLUMNWIDTHS:
+ {
+ columnwidths = value;
+ setColumnWidths();
+ break;
+ }
+ case SCRIPTLIST_COLUMNLABELS:
+ {
+ columnlabels = value;
+ setColumnLabels();
+ break;
+ }
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int ScriptList::onInit()
+{
+ SCRIPTLIST_PARENT::onInit();
+
+ last_numcolumns = 0x80000000;
+ setNumColumns(); // Sets widths and labels if necessary
+
+ setPreventMultipleSelection(!multiselect);
+
+ // fillFromParams(); // done by setNumColumns();
+ return 1;
+}
+
+/*
+ Moved to script-oriented section
+// -----------------------------------------------------------------------
+void ScriptList::onDoubleClick(int itemnum) {
+#ifdef WASABI_COMPILE_CONFIG
+ saveToConfig();
+#endif
+}
+*/
+
+/*
+ Moved to script-oriented section
+// -----------------------------------------------------------------------
+void ScriptList::onItemSelection(int itemnum, int selected) {
+ SCRIPTLIST_PARENT::onItemSelection(itemnum, selected);
+#ifdef WASABI_COMPILE_CONFIG
+ saveToConfig();
+#endif
+}
+*/
+
+
+// -----------------------------------------------------------------------
+int ScriptList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ SCRIPTLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ if (!_wcsicmp(action, L"select_all"))
+ {
+ selectAll(0);
+#ifdef WASABI_COMPILE_CONFIG
+ saveToConfig();
+#endif
+
+ }
+ if (!_wcsicmp(action, L"deselect_all"))
+ {
+ deselectAll(0);
+#ifdef WASABI_COMPILE_CONFIG
+ saveToConfig();
+#endif
+
+ }
+ if (!_wcsicmp(action, L"get_selection"))
+ {
+ if (source != NULL)
+ {
+ StringW res(L"");
+ for (int i = 0;i < getNumItems();i++)
+ {
+ if (getItemSelected(i))
+ {
+ if (!res.isempty()) res += L";";
+ res += getSubitemText(i, 0);
+ }
+ }
+ sendAction(source, L"set_selection", res);
+ }
+ }
+ return 1;
+}
+
+void ScriptList::onSetVisible(int i)
+{
+ SCRIPTLIST_PARENT::onSetVisible(i);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+// -----------------------------------------------------------------------
+int ScriptList::onReloadConfig()
+{
+ SCRIPTLIST_PARENT::onReloadConfig();
+ selectFromConfig();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::saveToConfig()
+{
+ StringW res(L"");
+ for (int i = 0;i < getNumItems();i++)
+ {
+ if (getItemSelected(i))
+ {
+ if (!res.isempty()) res += L";";
+ res += getSubitemText(i, 0);
+ }
+ }
+ getGuiObject()->guiobject_setCfgString(res);
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::selectFromConfig()
+{
+ deselectAll(0);
+ const wchar_t *p = getGuiObject()->guiobject_getCfgString();
+ if (p != NULL)
+ {
+ ParamParser pp(p);
+ for (int i = 0;i < pp.getNumItems();i++)
+ selectEntry(pp.enumItem(i), 0);
+ }
+}
+#endif
+
+// -----------------------------------------------------------------------
+int ScriptList::selectEntry(const wchar_t *e, int cb)
+{
+ for (int i = 0;i < getNumItems();i++)
+ {
+ const wchar_t *si = getSubitemText(i, 0);
+ if (WCSCASEEQLSAFE(si, e))
+ {
+ setSelected(i, 1, cb);
+ return i;
+ }
+ }
+ return -1;
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::fillFromParams()
+{
+ deleteAllItems();
+ if (!items.isempty())
+ {
+ ParamParser pp(items);
+ if (xmlnumcolumns == -1)
+ {
+ // OLD WAY
+ for (int i = 0;i < pp.getNumItems();i++)
+ addItem(pp.enumItem(i), (LPARAM)NULL);
+ }
+ else
+ {
+ // NEW WAY
+ int i, n = pp.getNumItems();
+ for (i = 0; i < n; i++)
+ {
+ StringW row = pp.enumItem(i);
+ ParamParser rp(row, L",");
+ addItem(rp.enumItem(0), (LPARAM)NULL);
+ int j, m = rp.getNumItems();
+ for (j = 1; j < m; j++)
+ {
+ setSubItem(i, j, rp.enumItem(j));
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::selectEntries(const wchar_t *entries, int cb)
+{
+ ParamParser pp(entries);
+ for (int i = 0;i < pp.getNumItems();i++)
+ selectEntry(pp.enumItem(i), cb);
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::setColumnWidths()
+{
+ // don't bother if there's no value.
+ if (columnwidths.len())
+ {
+ ParamParser pp(columnwidths);
+ int i, n = MIN(pp.getNumItems(), getNumColumns()); // whichever is less.
+ for (i = 0; i < n; i++)
+ {
+ ListColumn *column = getColumn(i);
+ if (column)
+ {
+ column->setWidth(WTOI(pp.enumItem(i)));
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::setColumnLabels()
+{
+ // don't bother if there's no value.
+ if (columnlabels.len())
+ {
+ ParamParser pp(columnlabels);
+ int i, n = MIN(pp.getNumItems(), getNumColumns()); // whichever is less.
+ for (i = 0; i < n; i++)
+ {
+ ListColumn *column = getColumn(i);
+ if (column)
+ {
+ column->setLabel(pp.enumItem(i));
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::setNumColumns()
+{
+ if (last_numcolumns == xmlnumcolumns) return ;
+
+ if (xmlnumcolumns == -1)
+ {
+ // the old way.
+ insertColumn(new ListColumn(L"", TRUE));
+ }
+ else
+ {
+ // delete all columns.
+ int i, n = getNumColumns();
+ for (i = 0; i < n; i++)
+ {
+ this->delColumnByPos(0);
+ }
+ // create new ones.
+ ParamParser cw(columnwidths);
+ int nw = cw.getNumItems();
+ ParamParser cl(columnlabels);
+ int nl = cl.getNumItems();
+ for (i = 0; i < xmlnumcolumns; i++)
+ {
+ const wchar_t *collabel = L"";
+ int colwidth = -1; // magic value for "be dynamic"
+ if (i < nl)
+ {
+ collabel = cl.enumItem(i);
+ }
+ if (i < nw)
+ {
+ colwidth = WTOI(cw.enumItem(i));
+ }
+ ListColumn *pCol = new ListColumn(collabel, (colwidth < 0));
+ if (colwidth >= 0)
+ {
+ pCol->setWidth(colwidth);
+ }
+ insertColumn(pCol);
+ }
+ fillFromParams();
+ }
+
+ last_numcolumns = xmlnumcolumns;
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::openFeed(const wchar_t *feedid)
+{
+ if (!_wcsicmp(feedid, last_feed)) return ;
+ feed = TextFeedEnum(feedid).getFirst();
+ if (feed != NULL)
+ {
+ viewer_addViewItem(feed->getDependencyPtr());
+ }
+ last_feed = feedid;
+}
+
+// -----------------------------------------------------------------------
+void ScriptList::closeFeed()
+{
+ if (feed)
+ {
+ viewer_delViewItem(feed->getDependencyPtr());
+ SvcEnum::release(feed);
+ }
+ feed = NULL;
+ last_feed = L"";
+}
+
+// -----------------------------------------------------------------------
+int ScriptList::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (feed && feed->getDependencyPtr() == item)
+ {
+ if (event == svc_textFeed::Event_TEXTCHANGE)
+ {
+ setXuiParam(myxuihandle, SCRIPTLIST_SETITEMS, L"items", (const wchar_t *)ptr);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+// -----------------------------------------------------------------------
+// Callback methods that send hooks into the Script system
+void ScriptList::onSelectAll()
+{
+ SCRIPTLIST_PARENT::onSelectAll();
+ GuiListScriptController::guilist_onSelectAll(SCRIPT_CALL, getScriptObject());
+}
+
+void ScriptList::onDelete()
+{
+ SCRIPTLIST_PARENT::onDelete();
+ GuiListScriptController::guilist_onDelete(SCRIPT_CALL, getScriptObject());
+}
+
+void ScriptList::onDoubleClick(int itemnum)
+{
+ SCRIPTLIST_PARENT::onDoubleClick(itemnum);
+ GuiListScriptController::guilist_onDoubleClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum));
+#ifdef WASABI_COMPILE_CONFIG
+ saveToConfig();
+#endif
+}
+
+void ScriptList::onLeftClick(int itemnum)
+{
+ SCRIPTLIST_PARENT::onLeftClick(itemnum);
+ GuiListScriptController::guilist_onLeftClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum));
+}
+
+int ScriptList::onIconLeftClick(int itemnum, int x , int y)
+{
+ SCRIPTLIST_PARENT::onIconLeftClick(itemnum, x, y);
+ scriptVar v = GuiListScriptController::guilist_onIconLeftClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y));
+ if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING))
+ {
+ return GET_SCRIPT_INT(v);
+ }
+ return 0;
+}
+
+void ScriptList::onSecondLeftClick(int itemnum)
+{
+ SCRIPTLIST_PARENT::onSecondLeftClick(itemnum);
+ GuiListScriptController::guilist_onSecondLeftClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum));
+}
+
+int ScriptList::onRightClick(int itemnum)
+{
+ SCRIPTLIST_PARENT::onRightClick(itemnum);
+ scriptVar v = GuiListScriptController::guilist_onRightClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum));
+ if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING))
+ {
+ return GET_SCRIPT_BOOLEAN(v);
+ }
+ return 0;
+}
+
+int ScriptList::onColumnDblClick(int col, int x, int y)
+{
+ SCRIPTLIST_PARENT::onColumnDblClick(col, x, y);
+ scriptVar v = GuiListScriptController::guilist_onColumnDblClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(col), MAKE_SCRIPT_INT(y), MAKE_SCRIPT_INT(x));
+ if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING))
+ {
+ return GET_SCRIPT_BOOLEAN(v);
+ }
+ return 0;
+}
+
+int ScriptList::onColumnLabelClick(int col, int x, int y)
+{
+ SCRIPTLIST_PARENT::onColumnLabelClick(col, x, y);
+ scriptVar v = GuiListScriptController::guilist_onColumnLabelClick(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(col), MAKE_SCRIPT_INT(y), MAKE_SCRIPT_INT(x));
+ if ((v.type != SCRIPT_VOID) && (v.type != SCRIPT_OBJECT) && (v.type != SCRIPT_STRING))
+ {
+ return GET_SCRIPT_BOOLEAN(v);
+ }
+ return 1; // don't ask me, that's what ListWnd does.
+}
+
+void ScriptList::onItemSelection(int itemnum, int selected)
+{
+ SCRIPTLIST_PARENT::onItemSelection(itemnum, selected);
+ GuiListScriptController::guilist_onItemSelection(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(itemnum), MAKE_SCRIPT_INT(selected));
+#ifdef WASABI_COMPILE_CONFIG
+ saveToConfig();
+#endif
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+GuiListScriptController _guiListController;
+GuiListScriptController *guiListController = &_guiListController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GuiListScriptController::exportedFunction[] = {
+ {L"getNumItems", 0, (void*)GuiListScriptController::guilist_getNumItems },
+ {L"getWantAutoDeselect", 0, (void*)guilist_getWantAutoDeselect },
+ {L"setWantAutoDeselect", 1, (void*)guilist_setWantAutoDeselect },
+ {L"onSetVisible", 1, (void*)guilist_onSetVisible },
+ {L"setAutoSort", 1, (void*)guilist_setAutoSort },
+ {L"next", 0, (void*)guilist_next },
+ {L"selectCurrent", 0, (void*)guilist_selectCurrent },
+ {L"selectFirstEntry", 0, (void*)guilist_selectFirstEntry },
+ {L"previous", 0, (void*)guilist_previous },
+ {L"pagedown", 0, (void*)guilist_pagedown },
+ {L"pageup", 0, (void*)guilist_pageup },
+ {L"home", 0, (void*)guilist_home },
+ {L"end", 0, (void*)guilist_end },
+ {L"reset", 0, (void*)guilist_reset },
+ {L"addColumn", 3, (void*)guilist_addColumn },
+ {L"getNumColumns", 0, (void*)guilist_getNumColumns },
+ {L"getColumnWidth", 1, (void*)guilist_getColumnWidth },
+ {L"setColumnWidth", 2, (void*)guilist_setColumnWidth },
+ {L"getColumnLabel", 1, (void*)guilist_getColumnLabel },
+ {L"setColumnLabel", 2, (void*)guilist_setColumnLabel },
+ {L"getColumnNumeric", 1, (void*)guilist_getColumnNumeric },
+ {L"setColumnDynamic", 2, (void*)guilist_setColumnDynamic },
+ {L"isColumnDynamic", 1, (void*)guilist_isColumnDynamic },
+ {L"setMinimumSize", 1, (void*)guilist_setMinimumSize },
+ {L"addItem", 1, (void*)guilist_addItem },
+ {L"insertItem", 2, (void*)guilist_insertItem },
+ {L"getLastAddedItemPos", 0, (void*)guilist_getLastAddedItemPos },
+ {L"setSubItem", 3, (void*)guilist_setSubItem },
+ {L"deleteAllItems", 0, (void*)guilist_deleteAllItems },
+ {L"deleteByPos", 1, (void*)guilist_deleteByPos },
+ {L"getItemLabel", 2, (void*)guilist_getItemLabel },
+ {L"setItemLabel", 2, (void*)guilist_setItemLabel },
+
+ {L"setItemIcon", 2, (void*)guilist_setItemIcon },
+ {L"getItemIcon", 1, (void*)guilist_getItemIcon },
+ {L"setShowIcons", 1, (void*)guilist_setShowIcons },
+ {L"getShowIcons", 0, (void*)guilist_getShowIcons },
+ {L"setIconWidth", 1, (void*)guilist_setIconWidth },
+ {L"getIconWidth", 0, (void*)guilist_getIconWidth },
+ {L"setIconHeight", 1, (void*)guilist_setIconHeight },
+ {L"getIconHeight", 0, (void*)guilist_getIconHeight },
+ {L"onIconLeftclick", 3, (void*)guilist_onIconLeftClick },
+
+ {L"getItemSelected", 1, (void*)guilist_getItemSelected },
+ {L"isItemFocused", 1, (void*)guilist_isItemFocused },
+ {L"getItemFocused", 0, (void*)guilist_getItemFocused },
+ {L"setItemFocused", 1, (void*)guilist_setItemFocused },
+ {L"ensureItemVisible", 1, (void*)guilist_ensureItemVisible },
+ {L"invalidateColumns", 0, (void*)guilist_invalidateColumns },
+ {L"scrollAbsolute", 1, (void*)guilist_scrollAbsolute },
+ {L"scrollRelative", 1, (void*)guilist_scrollRelative },
+ {L"scrollLeft", 1, (void*)guilist_scrollLeft },
+ {L"scrollRight", 1, (void*)guilist_scrollRight },
+ {L"scrollUp", 1, (void*)guilist_scrollUp },
+ {L"scrollDown", 1, (void*)guilist_scrollDown },
+ {L"getSubitemText", 2, (void*)guilist_getSubitemText },
+ {L"getFirstItemSelected", 0, (void*)guilist_getFirstItemSelected },
+ {L"getNextItemSelected", 1, (void*)guilist_getNextItemSelected },
+ {L"selectAll", 0, (void*)guilist_selectAll },
+ {L"deselectAll", 0, (void*)guilist_deselectAll },
+ {L"invertSelection", 0, (void*)guilist_invertSelection },
+ {L"invalidateItem", 1, (void*)guilist_invalidateItem },
+ {L"getFirstItemVisible", 0, (void*)guilist_getFirstItemVisible },
+ {L"getLastItemVisible", 0, (void*)guilist_getLastItemVisible },
+ {L"setFontSize", 1, (void*)guilist_setFontSize },
+ {L"getFontSize", 0, (void*)guilist_getFontSize },
+ {L"jumpToNext", 1, (void*)guilist_jumpToNext },
+ {L"scrollToItem", 1, (void*)guilist_scrollToItem },
+ {L"resort", 0, (void*)guilist_resort },
+ {L"getSortDirection", 0, (void*)guilist_getSortDirection },
+ {L"getSortColumn", 0, (void*)guilist_getSortColumn },
+ {L"setSortColumn", 1, (void*)guilist_setSortColumn },
+ {L"setSortDirection", 1, (void*)guilist_setSortDirection },
+ {L"getItemCount", 0, (void*)guilist_getItemCount },
+ {L"setSelectionStart", 1, (void*)guilist_setSelectionStart },
+ {L"setSelectionEnd", 1, (void*)guilist_setSelectionEnd },
+ {L"setSelected", 2, (void*)guilist_setSelected },
+ {L"toggleSelection", 2, (void*)guilist_toggleSelection },
+ {L"getHeaderHeight", 0, (void*)guilist_getHeaderHeight },
+ {L"getPreventMultipleSelection", 0, (void*)guilist_getPreventMultipleSelection },
+ {L"setPreventMultipleSelection", 1, (void*)guilist_setPreventMultipleSelection },
+ {L"moveItem", 2, (void*)guilist_moveItem },
+ {L"onSelectAll", 0, (void*)guilist_onSelectAll },
+ {L"onDelete", 0, (void*)guilist_onDelete },
+ {L"onDoubleClick", 1, (void*)guilist_onDoubleClick },
+ {L"onLeftClick", 1, (void*)guilist_onLeftClick },
+ {L"onSecondLeftClick", 1, (void*)guilist_onSecondLeftClick },
+ {L"onRightClick", 1, (void*)guilist_onRightClick },
+ {L"onColumnDblClick", 3, (void*)guilist_onColumnDblClick },
+ {L"onColumnLabelClick", 3, (void*)guilist_onColumnLabelClick },
+ {L"onItemSelection", 2, (void*)guilist_onItemSelection },
+ };
+
+ScriptObject *GuiListScriptController::instantiate()
+{
+ ScriptList *sp = new ScriptList;
+ ASSERT(sp != NULL);
+ return sp->getScriptObject();
+}
+
+void GuiListScriptController::destroy(ScriptObject *o)
+{
+ ScriptList *sp = static_cast<ScriptList *>(o->vcpu_getInterface(guilistGuid));
+ ASSERT(sp != NULL);
+ delete sp;
+}
+
+void *GuiListScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for guilists yet
+}
+
+void GuiListScriptController::deencapsulate(void *o)
+{}
+
+int GuiListScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GuiListScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int a = 0;
+ if (sp) a = sp->getNumItems();
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int a = 0;
+ if (sp)
+ {
+ sp->wantAutoDeselect();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar want)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _want = GET_SCRIPT_INT(want);
+ sp->setWantAutoDeselect(_want);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onSetVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar show)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _show = GET_SCRIPT_INT(show);
+ sp->onSetVisible(_show);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setAutoSort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dosort)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _dosort = GET_SCRIPT_INT(dosort);
+ sp->setAutoSort(!!_dosort);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_next(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->next();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_selectCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->selectCurrent();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_selectFirstEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->selectFirstEntry();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_previous(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->previous();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_pagedown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->pagedown();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_pageup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->pageup();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->home();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_end(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->end();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_reset(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->reset();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_addColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar name, /*int*/ scriptVar width, /*int*/ scriptVar numeric)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ StringW _name = GET_SCRIPT_STRING(name);
+ int _width = GET_SCRIPT_INT(width);
+ int _numeric = GET_SCRIPT_INT(numeric);
+ retval = sp->addColumn(_name, _width, _numeric);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getNumColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getNumColumns();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ retval = sp->getColumnWidth(_column);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar newwidth)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ int _newwidth = GET_SCRIPT_INT(newwidth);
+ ListColumn *c = sp->getColumn(_column);
+ if (c)
+ {
+ c->setWidth(_newwidth);
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*String*/ scriptVar GuiListScriptController::guilist_getColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ const wchar_t * retval = L"";
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ ListColumn *c = sp->getColumn(_column);
+ if (c)
+ {
+ retval = c->getLabel();
+ }
+ }
+
+ return MAKE_SCRIPT_STRING(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*String*/ scriptVar newlabel)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ StringW _newlabel = GET_SCRIPT_STRING(newlabel);
+ ListColumn *c = sp->getColumn(_column);
+ if (c)
+ {
+ c->setLabel(_newlabel);
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getColumnNumeric(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ ListColumn *c = sp->getColumn(_column);
+ if (c)
+ {
+ retval = c->getNumeric();
+ }
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar isdynamic)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ int _isdynamic = GET_SCRIPT_INT(isdynamic);
+ ListColumn *c = sp->getColumn(_column);
+ if (c)
+ {
+ c->setDynamic(_isdynamic);
+ }
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_isColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _column = GET_SCRIPT_INT(column);
+ ListColumn *c = sp->getColumn(_column);
+ if (c)
+ {
+ retval = c->isDynamic();
+ }
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setMinimumSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _size = GET_SCRIPT_INT(size);
+ sp->setMinimumSize(_size);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ StringW _label = GET_SCRIPT_STRING(label);
+ retval = sp->addItem(_label, 0);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_insertItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar label)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ StringW _label = GET_SCRIPT_STRING(label);
+ retval = sp->insertItem(_pos, _label, 0);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getLastAddedItemPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getLastAddedItemPos();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setSubItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos, /*String*/ scriptVar txt)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ int _subpos = GET_SCRIPT_INT(subpos);
+ StringW _txt = GET_SCRIPT_STRING(txt);
+ sp->setSubItem(_pos, _subpos, _txt);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->deleteAllItems();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_deleteByPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ retval = sp->deleteByPos(_pos);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*String*/ scriptVar GuiListScriptController::guilist_getItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ wchar_t retval[255] = { 0 };
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ int _subpos = GET_SCRIPT_INT(subpos);
+ sp->getItemLabel(_pos, _subpos, retval, 254);
+ retval[254]=0;
+ }
+ staticStr = retval;
+ return MAKE_SCRIPT_STRING(staticStr);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar text)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ StringW _text = GET_SCRIPT_STRING(text);
+ sp->setItemLabel(_pos, _text);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar bitmapId)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ StringW _bitmapId = GET_SCRIPT_STRING(bitmapId);
+ sp->setItemIcon(_pos, _bitmapId);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*string*/ scriptVar GuiListScriptController::guilist_getItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ SkinBitmap * bmp = sp->getItemIcon(_pos);
+ staticStr = bmp->getBitmapName();
+ }
+ return MAKE_SCRIPT_STRING(staticStr);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar onoff)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _onoff = GET_SCRIPT_INT(onoff);
+ sp->setShowIcons(_onoff);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getShowIcons();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _val = GET_SCRIPT_INT(val);
+ sp->setIconWidth(_val);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getIconWidth();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _val = GET_SCRIPT_INT(val);
+ sp->setIconHeight(_val);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getIconHeight();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ retval = sp->getItemSelected(_pos);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_isItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ retval = sp->getItemFocused(_pos);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getItemFocused();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ sp->setItemFocused(_pos);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ sp->ensureItemVisible(_pos);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_invalidateColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->invalidateColumns();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_scrollAbsolute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _x = GET_SCRIPT_INT(x);
+ retval = sp->scrollAbsolute(_x);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_scrollRelative(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _x = GET_SCRIPT_INT(x);
+ retval = sp->scrollRelative(_x);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_scrollLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ //int _lines = GET_SCRIPT_INT(lines);
+ sp->scrollLeft();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_scrollRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ //int _lines = GET_SCRIPT_INT(lines);
+ sp->scrollRight();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_scrollUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ //int _lines = GET_SCRIPT_INT(lines);
+ sp->scrollUp();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_scrollDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ //int _lines = GET_SCRIPT_INT(lines);
+ sp->scrollDown();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*String*/ scriptVar GuiListScriptController::guilist_getSubitemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ const wchar_t *retval = 0;
+
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ int _subpos = GET_SCRIPT_INT(subpos);
+ retval = sp->getSubitemText(_pos, _subpos);
+ }
+ return MAKE_SCRIPT_STRING(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getFirstItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getFirstItemSelected();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getNextItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lastpos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _lastpos = GET_SCRIPT_INT(lastpos);
+ retval = sp->getNextItemSelected(_lastpos);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->selectAll();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_deselectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->deselectAll();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_invertSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->invertSelection();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_invalidateItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ retval = sp->invalidateItem(_pos);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getFirstItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getFirstItemVisible();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getLastItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getLastItemVisible();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _size = GET_SCRIPT_INT(size);
+ retval = sp->setFontSize(_size);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getFontSize();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*char*/ scriptVar c)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ char _c = GET_SCRIPT_INT(c);
+ sp->jumpToNext(_c);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_scrollToItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ sp->scrollToItem(_pos);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_resort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ sp->resort();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getSortDirection();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getSortColumn();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _col = GET_SCRIPT_INT(col);
+ sp->setSortColumn(_col);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dir)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _dir = GET_SCRIPT_INT(dir);
+ sp->setSortDirection(_dir);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getItemCount(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getItemCount();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setSelectionStart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ sp->setSelectionStart(_pos);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setSelectionEnd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ sp->setSelectionEnd(_pos);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_setSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar selected)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ int _selected = GET_SCRIPT_INT(selected);
+ sp->setSelected(_pos, _selected);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_toggleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar setfocus)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _pos = GET_SCRIPT_INT(pos);
+ int _setfocus = GET_SCRIPT_INT(setfocus);
+ sp->toggleSelection(_pos, _setfocus);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getHeaderHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getHeaderHeight();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_getPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ retval = sp->getPreventMultipleSelection();
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_setPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ int retval = 0;
+ if (sp)
+ {
+ int _val = GET_SCRIPT_INT(val);
+ retval = sp->setPreventMultipleSelection(_val);
+ }
+ return MAKE_SCRIPT_INT(retval);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_moveItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar from, /*int*/ scriptVar to)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptList *sp = static_cast<ScriptList*>(o->vcpu_getInterface(guilistGuid));
+ if (sp)
+ {
+ int _from = GET_SCRIPT_INT(from);
+ int _to = GET_SCRIPT_INT(to);
+ sp->moveItem(_from, _to);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onSelectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiListController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onDelete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiListController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiListController, itemnum);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, itemnum);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiListController, itemnum);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, itemnum);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onIconLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum, /*int*/ scriptVar x, /*int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS3(o, guiListController, itemnum, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, itemnum, x, y);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onSecondLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiListController, itemnum);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, itemnum);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiListController, itemnum);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, itemnum);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_onColumnDblClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS3(o, guiListController, col, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, col, x, y);
+}
+
+/*int*/ scriptVar GuiListScriptController::guilist_onColumnLabelClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS3(o, guiListController, col, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, col, x, y);
+}
+
+/*void*/ scriptVar GuiListScriptController::guilist_onItemSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum, /*int*/ scriptVar selected)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiListController, itemnum, selected);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, itemnum, selected);
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuilist.h b/Src/Wasabi/api/skin/widgets/xuilist.h
new file mode 100644
index 00000000..ecc5c4a9
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuilist.h
@@ -0,0 +1,221 @@
+#ifndef __XUILIST_H
+#define __XUILIST_H
+
+#include <api/wnd/wndclass/listwnd.h>
+#include <api/script/objcontroller.h>
+#include <bfc/depend.h>
+
+class svc_textFeed;
+
+#define SCRIPTLIST_PARENT ListWnd
+
+// -----------------------------------------------------------------------
+class ScriptList : public SCRIPTLIST_PARENT, public DependentViewerI {
+ public:
+ ScriptList();
+ virtual ~ScriptList();
+
+ virtual int onInit();
+
+ //virtual void onDoubleClick(int itemnum); // moved to the script-handling callback.
+ //void onItemSelection(int itemnum, int selected);
+
+ int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+#ifdef WASABI_COMPILE_CONFIG
+ int onReloadConfig();
+#endif
+
+ virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual void onSetVisible(int i);
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ // Callback methods that send hooks into the Script system
+ virtual void onSelectAll();
+ virtual void onDelete();
+ virtual void onDoubleClick(int itemnum);
+ virtual void onLeftClick(int itemnum);
+ virtual void onSecondLeftClick(int itemnum);
+ virtual int onRightClick(int itemnum);
+ virtual int onColumnDblClick(int col, int x, int y);
+ virtual int onColumnLabelClick(int col, int x, int y);
+ virtual void onItemSelection(int itemnum, int selected);
+ virtual int onIconLeftClick(int itemnum, int x, int y);
+
+
+
+ enum {
+ SCRIPTLIST_SETITEMS = 0,
+ SCRIPTLIST_SETMULTISELECT,
+ SCRIPTLIST_SETAUTODESELECT,
+ SCRIPTLIST_SELECT,
+ SCRIPTLIST_FEED,
+ SCRIPTLIST_HOVERSELECT,
+ SCRIPTLIST_SORT,
+ SCRIPTLIST_SELECTONUPDOWN,
+ SCRIPTLIST_NUMCOLUMNS,
+ SCRIPTLIST_COLUMNWIDTHS,
+ SCRIPTLIST_COLUMNLABELS,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+ static XMLParamPair params[];
+#ifdef WASABI_COMPILE_CONFIG
+ void saveToConfig();
+ void selectFromConfig();
+#endif
+ void fillFromParams();
+ int selectEntry(const wchar_t *e, int cb=1);
+ void selectEntries(const wchar_t *multientry, int cb=1);
+ void setNumColumns();
+ void setColumnWidths();
+ void setColumnLabels();
+
+ void openFeed(const wchar_t *feedid);
+ void closeFeed();
+
+ //virtual int getColumnsHeight() { return 0; }
+ virtual int wantHScroll() { return 0; }
+
+ StringW items;
+ StringW columnwidths;
+ StringW columnlabels;
+ int xmlnumcolumns;
+ int last_numcolumns;
+ int multiselect;
+ int myxuihandle;
+ int autosave;
+#ifdef WASABI_COMPILE_CONFIG
+ int config_reentry;
+#endif
+
+ svc_textFeed *feed;
+ StringW last_feed;
+};
+
+// -----------------------------------------------------------------------------------------------------
+class GuiListScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"GuiList"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return guilistGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar guilist_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setWantAutoDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar want);
+ static /*void*/ scriptVar guilist_onSetVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar show);
+ static /*void*/ scriptVar guilist_setAutoSort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dosort);
+ static /*void*/ scriptVar guilist_next(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_selectCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_selectFirstEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_previous(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_pagedown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_pageup(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_home(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_end(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_reset(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_addColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar name, /*int*/ scriptVar width, /*int*/ scriptVar numeric);
+ static /*int*/ scriptVar guilist_getNumColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column);
+ static /*void*/ scriptVar guilist_setColumnWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar newwidth);
+ static /*String*/ scriptVar guilist_getColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column);
+ static /*void*/ scriptVar guilist_setColumnLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*String*/ scriptVar newlabel);
+ static /*int*/ scriptVar guilist_getColumnNumeric(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column);
+ static /*void*/ scriptVar guilist_setColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column, /*int*/ scriptVar isdynamic);
+ static /*int*/ scriptVar guilist_isColumnDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar column);
+ static /*void*/ scriptVar guilist_setMinimumSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size);
+ static /*int*/ scriptVar guilist_addItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label);
+ static /*int*/ scriptVar guilist_insertItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar label);
+ static /*int*/ scriptVar guilist_getLastAddedItemPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setSubItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos, /*String*/ scriptVar txt);
+ static /*void*/ scriptVar guilist_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_deleteByPos(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*String*/ scriptVar guilist_getItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos);
+ static /*void*/ scriptVar guilist_setItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar text);
+
+ static /*void*/ scriptVar guilist_setItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*String*/ scriptVar bitmapId);
+ static /*string*/ scriptVar guilist_getItemIcon(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*void*/ scriptVar guilist_setShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar onoff);
+ static /*int*/ scriptVar guilist_getShowIcons(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setIconWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static /*int*/ scriptVar guilist_getIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setIconHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val);
+ static /*int*/ scriptVar guilist_onIconLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar pos, scriptVar x, scriptVar y);
+
+ static /*int*/ scriptVar guilist_getItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*int*/ scriptVar guilist_isItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*int*/ scriptVar guilist_getItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setItemFocused(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*void*/ scriptVar guilist_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*void*/ scriptVar guilist_invalidateColumns(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_scrollAbsolute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x);
+ static /*int*/ scriptVar guilist_scrollRelative(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar x);
+ static /*void*/ scriptVar guilist_scrollLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines);
+ static /*void*/ scriptVar guilist_scrollRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines);
+ static /*void*/ scriptVar guilist_scrollUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines);
+ static /*void*/ scriptVar guilist_scrollDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lines);
+ static /*String*/ scriptVar guilist_getSubitemText(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar subpos);
+ static /*int*/ scriptVar guilist_getFirstItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getNextItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar lastpos);
+ static /*int*/ scriptVar guilist_selectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_deselectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_invertSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_invalidateItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*int*/ scriptVar guilist_getFirstItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getLastItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar size);
+ static /*int*/ scriptVar guilist_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*char*/ scriptVar c);
+ static /*void*/ scriptVar guilist_scrollToItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*void*/ scriptVar guilist_resort(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setSortColumn(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col);
+ static /*void*/ scriptVar guilist_setSortDirection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar dir);
+ static /*int*/ scriptVar guilist_getItemCount(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_setSelectionStart(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*void*/ scriptVar guilist_setSelectionEnd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos);
+ static /*void*/ scriptVar guilist_setSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar selected);
+ static /*void*/ scriptVar guilist_toggleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar pos, /*int*/ scriptVar setfocus);
+ static /*int*/ scriptVar guilist_getHeaderHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_getPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar guilist_setPreventMultipleSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar val);
+ static /*void*/ scriptVar guilist_moveItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar from, /*int*/ scriptVar to);
+
+ static /*void*/ scriptVar guilist_onSelectAll(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_onDelete(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar guilist_onDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum);
+ static /*void*/ scriptVar guilist_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum);
+ static /*void*/ scriptVar guilist_onSecondLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum);
+ static /*int*/ scriptVar guilist_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum);
+ static /*int*/ scriptVar guilist_onColumnDblClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y);
+ static /*int*/ scriptVar guilist_onColumnLabelClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar col, /*int*/ scriptVar x, /*int*/ scriptVar y);
+ static /*void*/ scriptVar guilist_onItemSelection(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar itemnum, /*int*/ scriptVar selected);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+
+ static StringW staticStr;
+};
+
+extern GuiListScriptController *guiListController;
+
+
+// -----------------------------------------------------------------------
+extern const wchar_t ScriptListXuiObjectStr[];
+extern char ScriptListXuiSvcName[];
+class ScriptListXuiSvc : public XuiObjectSvc<ScriptList, ScriptListXuiObjectStr, ScriptListXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuimenu.cpp b/Src/Wasabi/api/skin/widgets/xuimenu.cpp
new file mode 100644
index 00000000..7113b8fb
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuimenu.cpp
@@ -0,0 +1,384 @@
+#include <precomp.h>
+#include "xuimenu.h"
+#include <api/service/svcs/svc_action.h>
+
+#define MENU_TIMER_CHECK 0x100
+#define DC_MENU_CHAIN 0x101
+#define DC_MENU_REENABLE 0x102
+#define DC_MENU_INIT 0x103
+#define DC_MENU_NEXT 0x104
+#define DC_MENU_PREV 0x105
+#define DC_MENU_OPENACTION 0x106
+#define MENU_TIMER_POPKBDLOCK 0x107
+#define MENU_TIMER_DELAY 5
+extern HINSTANCE hInstance;
+const wchar_t MenuXuiObjectStr[] = L"Menu"; // This is the xml tag
+char MenuXuiSvcName[] = "Menu xui object";
+
+static XuiMenu *xuimenu_hookingMenu = NULL;
+static HHOOK hhook=NULL;
+static HHOOK hhook_menuselect=NULL;
+static int hookusercount = 0;
+
+XMLParamPair XuiMenu::params[] = {
+ {MENU_DOWNID, L"DOWN"},
+ {MENU_HOVERID, L"HOVER"},
+ {MENU_MENU, L"MENU"},
+ {MENU_MENUGROUP, L"MENUGROUP"},
+ {MENU_NEXT, L"NEXT"},
+ {MENU_NORMALID, L"NORMAL"},
+ {MENU_PREV, L"PREV"},
+ };
+
+XuiMenu::XuiMenu() {
+ timerset = 0;
+ disablespawn = 0;
+ nextinchain = NULL;
+ normal = NULL;
+ down = NULL;
+ isspawned = 0;
+ inarea = 0;
+ kbdhook = 0;
+ kbdlocktimer = 0;
+ submenu_isselected = 0;
+ submenu_selectedbymouse = 0;
+ submenu_selected = NULL;
+ first_hmenu = NULL;
+ cur_hmenu = NULL;
+ getScriptObject()->vcpu_setInterface(xuiMenuGuid, (void *)static_cast<XuiMenu *>(this));
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+ hover = NULL;
+ orig_x = orig_y = 0;
+ menu_parent = NULL;
+}
+
+void XuiMenu::CreateXMLParameters(int master_handle)
+{
+ //XUIMENU_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+XuiMenu::~XuiMenu() {
+ if (timerset) killTimer(MENU_TIMER_CHECK);
+ if (kbdlocktimer) { killTimer(MENU_TIMER_POPKBDLOCK); WASABI_API_WND->popKeyboardLock(); } // do not set kbdlocktimer to 0, or stopKbdHook will start a timer
+ stopKbdHook();
+}
+
+int XuiMenu::onInit() {
+ XUIMENU_PARENT::onInit();
+ postDeferredCallback(DC_MENU_INIT);
+ return 1;
+}
+
+int XuiMenu::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) {
+ if (xuihandle == _xuihandle) {
+ switch (xmlattrid) {
+ case MENU_MENUGROUP: setMenuGroup(value); return 1;
+ case MENU_MENU: setMenu(value); return 1;
+ case MENU_NORMALID: setNormalId(value); return 1;
+ case MENU_DOWNID: setDownId(value); return 1;
+ case MENU_HOVERID: setHoverId(value); return 1;
+ case MENU_NEXT: next = value; return 1;
+ case MENU_PREV: prev = value; return 1;
+ }
+ }
+ return XUIMENU_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value);
+}
+
+void XuiMenu::setMenu(const wchar_t *m)
+{
+ menuid = m;
+ return;
+}
+
+void XuiMenu::setMenuGroup(const wchar_t *mg) {
+ menugroup = mg;
+ return;
+}
+
+void XuiMenu::setNormalId(const wchar_t *id) {
+ normalid = id;
+ updateObjects();
+}
+
+void XuiMenu::setDownId(const wchar_t *id) {
+ downid = id;
+ updateObjects();
+}
+
+void XuiMenu::setHoverId(const wchar_t *id) {
+ hoverid = id;
+ updateObjects();
+}
+
+int XuiMenu::onLeftButtonDown(int x, int y) {
+ XUIMENU_PARENT::onLeftButtonDown(x, y);
+ if (!disablespawn)
+ spawnMenu();
+ return 1;
+}
+
+void XuiMenu::timerCallback(int c) {
+ if (c == MENU_TIMER_CHECK) {
+ timerCheck();
+ } else if (c == MENU_TIMER_POPKBDLOCK) {
+ kbdlocktimer = 0;
+ killTimer(MENU_TIMER_POPKBDLOCK);
+ WASABI_API_WND->popKeyboardLock();
+ }
+ else XUIMENU_PARENT::timerCallback(c);
+}
+
+void XuiMenu::timerCheck() {
+ POINT pt;
+ Wasabi::Std::getMousePos((long*)&pt.x, (long*)&pt.y);
+ if (pt.x == orig_x && pt.y == orig_y) return;
+ nextinchain = NULL;
+ ifc_window *w = WASABI_API_WND->rootWndFromPoint(&pt);
+ if (w != NULL) {
+ XuiMenu *x = static_cast<XuiMenu *>(w->getInterface(xuiMenuGuid));
+ switchToMenu(x);
+ }
+}
+
+void XuiMenu::switchToMenu(XuiMenu *x) {
+ if (x != NULL && x != this && x != nextinchain)
+ {
+ if (WCSCASEEQLSAFE(x->getMenuGroup(), getMenuGroup()))
+ {
+ killTimer(MENU_TIMER_CHECK);
+ timerset = 0;
+ nextinchain = x;
+ stopKbdHook();
+ cancelMenu();
+ }
+ }
+}
+
+void XuiMenu::spawnMenu(int monitor) {
+
+ Wasabi::Std::getMousePos(&orig_x, &orig_y);
+
+ isspawned = 1;
+ onOpenMenu();
+
+ if (monitor) { setTimer(MENU_TIMER_CHECK, MENU_TIMER_DELAY); timerset = 1; startKbdHook(); }
+
+ StringW actionstr = StringPrintfW(L"MENU:%s", menuid);
+
+ svc_action *act = ActionEnum(actionstr).getNext();
+ if (act) {
+ RECT r;
+ getClientRect(&r);
+ clientToScreen(&r);
+ act->onAction(actionstr, NULL, r.left, r.bottom, NULL, 0, this);
+ SvcEnum::release(act);
+ }
+
+ if (monitor) {
+ if (timerset) { killTimer(MENU_TIMER_CHECK); timerset = 0; }
+ stopKbdHook();
+ }
+ disablespawn = 1;
+ if (nextinchain) {
+ postDeferredCallback(DC_MENU_CHAIN);
+ }
+ postDeferredCallback(DC_MENU_REENABLE);
+
+ isspawned = 0;
+ onCloseMenu();
+}
+
+int XuiMenu::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == DC_MENU_CHAIN) {
+ XuiMenu *x = nextinchain;
+ nextinchain = NULL;
+ x->spawnMenu();
+ } else if (p1 == DC_MENU_REENABLE) {
+ disablespawn = 0;
+ } else if (p1 == DC_MENU_INIT) {
+ updateObjects();
+ } else if (p1 == DC_MENU_NEXT) {
+ _nextMenu();
+ } else if (p1 == DC_MENU_PREV) {
+ _previousMenu();
+ } else if (p1 == DC_MENU_OPENACTION) {
+ spawnMenu();
+ WASABI_API_WND->kbdReset();
+ } else return XUIMENU_PARENT::onDeferredCallback(p1, p2);
+ return 1;
+}
+
+void XuiMenu::cancelMenu() {
+ #ifdef WIN32
+
+ PostMessage(gethWnd(), WM_LBUTTONDOWN, 0, 0xdeadc0de);
+ PostMessage(gethWnd(), WM_LBUTTONUP, 0, 0xdeadc0de);
+
+ #else
+
+ #error port me! you should close that menu which is in its own message pump now (oh and btw, you don't know shit about the menu itself because it's spawned by an action). have fun!
+
+ #endif
+}
+
+void XuiMenu::onOpenMenu() {
+ updateObjects();
+ script_onOpenMenu();
+}
+
+void XuiMenu::onCloseMenu() {
+ updateObjects();
+ WASABI_API_WND->kbdReset();
+ script_onCloseMenu();
+}
+
+void XuiMenu::updateObjects()
+{
+ normal = findObject(normalid);
+ down = findObject(downid);
+ hover = findObject(hoverid);
+ if (normal) normal->guiobject_getRootWnd()->setVisible(!isspawned);
+ if (down) down->guiobject_getRootWnd()->setVisible(isspawned);
+ if (hover) hover->guiobject_getRootWnd()->setVisible(!isspawned && inarea);
+}
+
+void XuiMenu::onEnterArea() {
+ XUIMENU_PARENT::onEnterArea();
+ inarea = 1;
+ updateObjects();
+}
+
+void XuiMenu::onLeaveArea() {
+ XUIMENU_PARENT::onLeaveArea();
+ inarea = 0;
+ updateObjects();
+}
+
+int XuiMenu::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ if (!_wcsicmp(action, L"open")) { openAction(); }
+ //else if (STRCASEEQL(action, "preopen")) { inarea = 1; updateObjects(); startKbdHook(); }
+ else if (!_wcsicmp(action, L"close")) cancelMenu();
+ else return XUIMENU_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ return 1;
+}
+
+LRESULT CALLBACK xuimenu_KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
+ if (code >= 0 && xuimenu_hookingMenu != NULL) {
+ if (code != HC_NOREMOVE && !(lParam & (1 << 31))) {
+ switch (wParam) {
+ case VK_LEFT: xuimenu_hookingMenu->onTrappedLeft(); break;
+ case VK_RIGHT: xuimenu_hookingMenu->onTrappedRight(); break;
+ //case VK_ESCAPE: DebugString("Escape trapped!\n"); break;
+ }
+ }
+ }
+ if (hhook) return CallNextHookEx(hhook, code, wParam, lParam);
+ return 1;
+}
+
+LRESULT CALLBACK xuimenu_msgProc(int code, WPARAM wParam, LPARAM lParam) {
+ if (code >= 0 && xuimenu_hookingMenu != NULL) {
+ MSG *msg = (MSG *)lParam;
+ if (msg->message == WM_MENUSELECT) {
+ xuimenu_hookingMenu->onMenuSelect(msg->hwnd, (HMENU)msg->lParam, LOWORD(msg->wParam), HIWORD(msg->wParam));
+ }
+ }
+ if (hhook_menuselect) return CallNextHookEx(hhook_menuselect, code, wParam, lParam);
+ return 1;
+}
+
+void XuiMenu::startKbdHook() {
+ if (kbdhook) return;
+ if (kbdlocktimer) { killTimer(MENU_TIMER_POPKBDLOCK); kbdlocktimer = 0; }
+ else WASABI_API_WND->pushKeyboardLock();
+ xuimenu_hookingMenu = this;
+ if (hhook == NULL) {
+ hhook = SetWindowsHookEx(WH_KEYBOARD, xuimenu_KeyboardProc, 0, GetCurrentThreadId());
+ hhook_menuselect = SetWindowsHookEx(WH_MSGFILTER, xuimenu_msgProc, 0, GetCurrentThreadId());
+ hookusercount = 1;
+ } else hookusercount++;
+ kbdhook = 1;
+}
+
+void XuiMenu::stopKbdHook() {
+ if (!kbdhook) return;
+ if (nextinchain) {
+ if (!kbdlocktimer) {
+ kbdlocktimer = 1;
+ setTimer(MENU_TIMER_POPKBDLOCK, 500);
+ }
+ } else WASABI_API_WND->popKeyboardLock();
+ if (xuimenu_hookingMenu == this) xuimenu_hookingMenu = NULL;
+ first_hmenu = NULL;
+ submenu_isselected = 0;
+ submenu_selectedbymouse = 0;
+ submenu_selected = NULL;
+ cur_hmenu = NULL;
+ menu_parent = NULL;
+ if (--hookusercount == 0) {
+ UnhookWindowsHookEx(hhook_menuselect);
+ UnhookWindowsHookEx(hhook);
+ hhook = NULL;
+ hhook_menuselect = NULL;
+ }
+ kbdhook = 0;
+}
+
+void XuiMenu::onMenuSelect(HWND hwnd, HMENU menu, int item, int flags) {
+ if (first_hmenu == NULL) first_hmenu = menu;
+ cur_hmenu = menu;
+ menu_parent = hwnd;
+
+// DebugString("Menu Item Selected! HMENU = %X, item = %d, flags = %d, submenu = %X\n", menu, item, flags, flags & MF_POPUP);
+
+ if (flags & MF_POPUP) { submenu_isselected = 1; submenu_selected = GetSubMenu(menu, item); submenu_selectedbymouse = flags & MF_MOUSESELECT; }
+ else { submenu_isselected = 0; submenu_selected = NULL; submenu_selectedbymouse = 0; }
+}
+
+void XuiMenu::onTrappedLeft() {
+ if (cur_hmenu == first_hmenu)
+ xuimenu_hookingMenu->previousMenu();
+}
+
+void XuiMenu::onTrappedRight() {
+ if (!submenu_isselected)
+ nextMenu();
+ else if (submenu_selectedbymouse)
+ PostMessage(menu_parent, WM_KEYDOWN, VK_DOWN, 0);
+}
+
+
+void XuiMenu::openAction() {
+ postDeferredCallback(DC_MENU_OPENACTION);
+}
+
+void XuiMenu::previousMenu() {
+ postDeferredCallback(DC_MENU_PREV);
+}
+
+void XuiMenu::nextMenu() {
+ postDeferredCallback(DC_MENU_NEXT);
+}
+
+void XuiMenu::_nextMenu() {
+ GuiObject *o = findObject(next);
+ if (o) {
+ XuiMenu *menu = static_cast<XuiMenu*>(o->guiobject_getScriptObject()->vcpu_getInterface(xuiMenuGuid));
+ if (menu) switchToMenu(menu);
+ }
+}
+
+void XuiMenu::_previousMenu() {
+ GuiObject *o = findObject(prev);
+ if (o) {
+ XuiMenu *menu = static_cast<XuiMenu*>(o->guiobject_getScriptObject()->vcpu_getInterface(xuiMenuGuid));
+ if (menu) switchToMenu(menu);
+ }
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuimenu.h b/Src/Wasabi/api/skin/widgets/xuimenu.h
new file mode 100644
index 00000000..2629f980
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuimenu.h
@@ -0,0 +1,110 @@
+#ifndef _XUIMENU_H
+#define _XUIMENU_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+/*<?<autoheader/>*/
+#include "xuimenuso.h"
+/*?>*/
+
+#define XUIMENU_PARENT XuiMenuScriptObject
+
+// {A0211C57-DCED-45ae-AEA6-56014B5898E8}
+static const GUID xuiMenuGuid =
+{ 0xa0211c57, 0xdced, 0x45ae, { 0xae, 0xa6, 0x56, 0x1, 0x4b, 0x58, 0x98, 0xe8 } };
+
+/*<?<classdecl name="XuiMenu" factory="ScriptObject" />*/
+class XuiMenu : public XuiMenuScriptObject
+{
+/*?>*/
+ public:
+ friend LRESULT CALLBACK xuimenu_KeyboardProc(int code, WPARAM wParam, LPARAM lParam);
+ friend LRESULT CALLBACK xuimenu_msgProc(int code, WPARAM wParam, LPARAM lParam);
+
+ XuiMenu();
+ virtual ~XuiMenu();
+
+ virtual int onInit();
+ virtual int onLeftButtonDown(int x, int y);
+ int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value);
+ virtual void timerCallback(int c);
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ SCRIPT void setMenuGroup(const wchar_t *mg);
+ SCRIPT const wchar_t *getMenuGroup() { return menugroup; }
+
+ SCRIPT void setMenu(const wchar_t *m);
+ SCRIPT const wchar_t *getMenu() { return menuid; }
+
+ SCRIPT void spawnMenu(int monitor = 1);
+ SCRIPT void cancelMenu();
+
+ SCRIPT void setNormalId(const wchar_t *id);
+ SCRIPT void setDownId(const wchar_t *id);
+ SCRIPT void setHoverId(const wchar_t *id);
+
+ SCRIPT EVENT virtual void onOpenMenu();
+ SCRIPT EVENT virtual void onCloseMenu();
+
+ virtual void onEnterArea();
+ virtual void onLeaveArea();
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ SCRIPT void nextMenu();
+ SCRIPT void previousMenu();
+
+ enum {
+ MENU_MENU = 0,
+ MENU_MENUGROUP,
+ MENU_NORMALID,
+ MENU_DOWNID,
+ MENU_HOVERID,
+ MENU_NEXT,
+ MENU_PREV,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+ static XMLParamPair params[];
+ void onMenuSelect(HWND hwnd, HMENU menu, int menuitem, int flags);
+ void startKbdHook();
+ void stopKbdHook();
+ void updateObjects();
+ void timerCheck();
+ void switchToMenu(XuiMenu *menu);
+ void _nextMenu();
+ void _previousMenu();
+ void openAction();
+ void onTrappedLeft();
+ void onTrappedRight();
+ StringW menugroup;
+ StringW menuid;
+ int xuihandle;
+ XuiMenu *nextinchain;
+ int timerset;
+ int disablespawn;
+ GuiObject *normal;
+ GuiObject *down;
+ GuiObject *hover;
+ StringW next, prev;
+ int isspawned;
+ StringW normalid, downid, hoverid;
+ int inarea;
+ int kbdhook;
+ int orig_x, orig_y;
+ int kbdlocktimer;
+ int submenu_isselected;
+ int submenu_selectedbymouse;
+ HMENU submenu_selected;
+ HWND menu_parent;
+ HMENU first_hmenu;
+ HMENU cur_hmenu;
+};
+
+// -----------------------------------------------------------------------
+extern const wchar_t MenuXuiObjectStr[];
+extern char MenuXuiSvcName[];
+class MenuXuiSvc : public XuiObjectSvc<XuiMenu, MenuXuiObjectStr, MenuXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuimenuso.cpp b/Src/Wasabi/api/skin/widgets/xuimenuso.cpp
new file mode 100644
index 00000000..8c48f210
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuimenuso.cpp
@@ -0,0 +1,271 @@
+// ----------------------------------------------------------------------------
+// Generated by ScriptObjectFactory [Sun Dec 14 07:21:52 2003]
+//
+// File : xuimenuso.cpp
+// Class : XuiMenuScriptObject
+// class layer : Automatic Object Scripting
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "xuimenuso.h"
+#include "xuimenu.h"
+
+// ScriptController Instance
+static XuiMenuScriptController _xuiMenuScriptController;XuiMenuScriptController *xuiMenuScriptController = &_xuiMenuScriptController;
+
+// Function Descriptor Table
+function_descriptor_struct XuiMenuScriptController::exportedFunctions[] = {
+ {L"setMenuGroup", 1, script_setMenuGroup },
+ {L"getMenuGroup", 0, script_getMenuGroup },
+ {L"setMenu", 1, script_setMenu },
+ {L"getMenu", 0, script_getMenu },
+ {L"spawnMenu", 1, script_spawnMenu },
+ {L"cancelMenu", 0, script_cancelMenu },
+ {L"setNormalId", 1, script_setNormalId },
+ {L"setDownId", 1, script_setDownId },
+ {L"setHoverId", 1, script_setHoverId },
+ {L"onOpenMenu", 0, script_onOpenMenu },
+ {L"onCloseMenu", 0, script_onCloseMenu },
+ {L"nextMenu", 0, script_nextMenu },
+ {L"previousMenu", 0, script_previousMenu },
+};
+
+// Script Object Methods
+XuiMenuScriptObject::XuiMenuScriptObject() {
+ if (!getScriptObject()) return;
+ xuiMenuScriptObject_init();
+}
+
+XuiMenuScriptObject::~XuiMenuScriptObject() {
+}
+
+void XuiMenuScriptObject::xuiMenuScriptObject_init() {
+ // Assign the script interface to this instance.
+ getScriptObject()->vcpu_setInterface(XuiMenuScriptGuid, (void *)static_cast<XuiMenu*>(this));
+ // Assign the class name to this instance.
+ getScriptObject()->vcpu_setClassName(L"Menu");
+ // Assign the controller instance to this script object instance.
+ getScriptObject()->vcpu_setController(xuiMenuScriptController);
+}
+
+// Script Object Methods
+
+void XuiMenuScriptObject::script_onOpenMenu() {
+ XuiMenuScriptController::script_onOpenMenu(SCRIPT_CALL, getScriptObject());
+}
+
+void XuiMenuScriptObject::script_onCloseMenu() {
+ XuiMenuScriptController::script_onCloseMenu(SCRIPT_CALL, getScriptObject());
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_setMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ mg) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->setMenuGroup(GET_SCRIPT_STRING(mg));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*const char **/ XuiMenuScriptController::script_getMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+
+ if (_pObj)
+ return MAKE_SCRIPT_STRING(_pObj->getMenuGroup());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_setMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ m) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->setMenu(GET_SCRIPT_STRING(m));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*const char **/ XuiMenuScriptController::script_getMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+
+ if (_pObj)
+ return MAKE_SCRIPT_STRING(_pObj->getMenu());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_spawnMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*int */ monitor) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->spawnMenu(GET_SCRIPT_INT(monitor));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_cancelMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->cancelMenu();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_setNormalId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ id) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj)
+ {
+ // Then properly call the hosted object;
+ _pObj->setNormalId(GET_SCRIPT_STRING(id));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_setDownId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ id) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->setDownId(GET_SCRIPT_STRING(id));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_setHoverId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar /*const char **/ id) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->setHoverId(GET_SCRIPT_STRING(id));
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_onOpenMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block
+ SCRIPT_FUNCTION_INIT;
+ // Honnor C++ hooks
+ PROCESS_HOOKS0(_pSO, xuiMenuScriptController);
+ // If there are no script hooks to execute, we abort here.
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ // Otherwise we execute the script methods by calling this.
+ SCRIPT_EXEC_EVENT0(_pSO);
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_onCloseMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block
+ SCRIPT_FUNCTION_INIT;
+ // Honnor C++ hooks
+ PROCESS_HOOKS0(_pSO, xuiMenuScriptController);
+ // If there are no script hooks to execute, we abort here.
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ // Otherwise we execute the script methods by calling this.
+ SCRIPT_EXEC_EVENT0(_pSO);
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_nextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->nextMenu();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar /*void */ XuiMenuScriptController::script_previousMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO) {
+ // Begin all script methods with the init block.
+ SCRIPT_FUNCTION_INIT;
+ // Find the proper pointer for the "this" object, _pSO.
+ XuiMenu*_pObj = static_cast<XuiMenu*>(_pSO->vcpu_getInterface(XuiMenuScriptGuid));
+ if (_pObj) {
+ // Then properly call the hosted object;
+ _pObj->previousMenu();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+// Script Controller
+
+// This method returns the human readable name of the class in script files.
+const wchar_t *XuiMenuScriptController::getClassName() {
+ return L"Menu";
+}
+
+// This method returns the human readable name of the parent of this class.
+const wchar_t *XuiMenuScriptController::getAncestorClassName() {
+ return XUIMENU_SCRIPTPARENTCLASS;
+}
+
+// This method returns the controller object for the parent class.
+ScriptObjectController *XuiMenuScriptController::getAncestorController() {
+ return WASABI_API_MAKI->maki_getController(guiObjectGuid);
+}
+
+// This method returns the number of methods this class publishes.
+int XuiMenuScriptController::getNumFunctions() {
+ return sizeof(exportedFunctions) / sizeof(function_descriptor_struct);
+}
+
+// This method returns the block of published function descriptors.
+const function_descriptor_struct *XuiMenuScriptController::getExportedFunctions() {
+ return exportedFunctions;
+}
+
+// This method returns the GUID assigned to this script class.
+GUID XuiMenuScriptController::getClassGuid() {
+ return XuiMenuScriptGuid;
+}
+
+// This method creates and returns a new script class instance.
+ScriptObject *XuiMenuScriptController::instantiate() {
+ XuiMenu*_pObj = new XuiMenu();
+ ASSERT(_pObj != NULL);
+ return _pObj->XuiMenuScriptObject::getScriptObject();
+}
+
+// This method deletes a given script class instance.
+void XuiMenuScriptController::destroy(ScriptObject *o) {
+ XuiMenu*_pObj = static_cast<XuiMenu*>(o->vcpu_getInterface(XuiMenuScriptGuid));
+ ASSERT(_pObj != NULL);
+ delete _pObj;
+}
+
+// This method returns an encapsulated interface for the given instance.
+void *XuiMenuScriptController::encapsulate(ScriptObject *o) {
+ // No automatic encapsulation
+ return NULL;
+}
+
+// This method frees a previously encapsulated interface.
+void XuiMenuScriptController::deencapsulate(void *o) {
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuimenuso.h b/Src/Wasabi/api/skin/widgets/xuimenuso.h
new file mode 100644
index 00000000..3c09555e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuimenuso.h
@@ -0,0 +1,76 @@
+// ----------------------------------------------------------------------------
+// Generated by ScriptObjectFactory [Sun Dec 14 07:21:52 2003]
+//
+// File : xuimenuso.h
+// Class : XuiMenuScriptObject
+// class layer : Automatic Object Scripting
+// ----------------------------------------------------------------------------
+
+#ifndef __XUIMENUSCRIPTOBJECT_H
+#define __XUIMENUSCRIPTOBJECT_H
+
+class XuiMenu;
+
+#include <api/script/objects/rootobj.h>
+#include <api/script/objcontroller.h>
+
+#define XUIMENU_SCRIPTPARENT GuiObjectWnd
+#define XUIMENU_SCRIPTPARENTCLASS L"GuiObject"
+
+// ----------------------------------------------------------------------------
+// {73C00594-961F-401B-9B1B-672427AC4165}
+static const GUID XuiMenuScriptGuid =
+{ 0x73c00594, 0x961f, 0x401b, { 0x9b, 0x1b, 0x67, 0x24, 0x27, 0xac, 65, 101 } };
+// -----------------------------------------------------------------------------
+
+class XuiMenuScriptObject : public XUIMENU_SCRIPTPARENT {
+protected:
+ XuiMenuScriptObject();
+ virtual ~XuiMenuScriptObject();
+
+public:
+ void xuiMenuScriptObject_init();
+
+public:
+ virtual void script_onOpenMenu();
+ virtual void script_onCloseMenu();
+private:
+};
+
+// -----------------------------------------------------------------------------
+class XuiMenuScriptController : public ScriptObjectControllerI {
+public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+public:
+ static scriptVar script_setMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar mg);
+ static scriptVar script_getMenuGroup(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_setMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar m);
+ static scriptVar script_getMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_spawnMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar monitor);
+ static scriptVar script_cancelMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_setNormalId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar id);
+ static scriptVar script_setDownId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar id);
+ static scriptVar script_setHoverId(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO, scriptVar id);
+ static scriptVar script_onOpenMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_onCloseMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_nextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+ static scriptVar script_previousMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *_pSO);
+
+private:static function_descriptor_struct exportedFunctions[];
+};
+
+extern XuiMenuScriptController *xuiMenuScriptController;
+// ----------------------------------------------------------------------------
+
+#endif // __XUIMENUSCRIPTOBJECT_H
diff --git a/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp
new file mode 100644
index 00000000..90ac1aaa
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.cpp
@@ -0,0 +1,57 @@
+#include <precomp.h>
+
+#include "xuiobjdirwnd.h"
+
+const wchar_t ScriptObjDirWndXuiObjectStr[] = L"ObjDirView"; // This is the xml tag
+char ScriptObjDirWndXuiSvcName[] = "ObjDirView xui object";
+
+XMLParamPair ScriptObjDirWnd::params[] = {
+ {DEFAULTDISPLAY, L"DEFAULTDISPLAY"},
+ {SCRIPTOBJDIRWND_DIR, L"DIR"},
+ {DISPLAYTARGET, L"DISPLAYTARGET"},
+ {FORCEVIRTUAL, L"FORCEVIRTUAL"},
+ {SCRIPTOBJDIRWND_ACTION_TARGET, L"TARGET"},
+ };
+
+ScriptObjDirWnd::ScriptObjDirWnd()
+{
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+void ScriptObjDirWnd::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTOBJDIRWND_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ScriptObjDirWnd::~ScriptObjDirWnd() { }
+
+int ScriptObjDirWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return SCRIPTOBJDIRWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+ switch (xmlattributeid) {
+ case SCRIPTOBJDIRWND_DIR:
+ setTargetDirName(value);
+ break;
+ case SCRIPTOBJDIRWND_ACTION_TARGET:
+ setActionTarget(value);
+ break;
+ case DISPLAYTARGET:
+ setDisplayTarget(value);
+ break;
+ case DEFAULTDISPLAY:
+ setDefaultDisplay(value);
+ break;
+ case FORCEVIRTUAL:
+ setVirtual(WTOI(value));
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h
new file mode 100644
index 00000000..f28c0b9a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiobjdirwnd.h
@@ -0,0 +1,32 @@
+#ifndef _XUIOBJDIRWND_H
+#define _XUIOBJDIRWND_H
+
+#include <api/skin/widgets/objdirwnd.h>
+
+#define SCRIPTOBJDIRWND_PARENT ObjDirWnd
+class ScriptObjDirWnd : public SCRIPTOBJDIRWND_PARENT {
+public:
+ ScriptObjDirWnd();
+ virtual ~ScriptObjDirWnd();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+
+enum {
+ SCRIPTOBJDIRWND_DIR=10,
+ SCRIPTOBJDIRWND_ACTION_TARGET=20,
+ DISPLAYTARGET,
+ DEFAULTDISPLAY,
+ FORCEVIRTUAL,
+};
+static XMLParamPair params[];
+ int myxuihandle;
+};
+
+extern const wchar_t ScriptObjDirWndXuiObjectStr[];
+extern char ScriptObjDirWndXuiSvcName[];
+class ScriptObjDirWndXuiSvc : public XuiObjectSvc<ScriptObjDirWnd, ScriptObjDirWndXuiObjectStr, ScriptObjDirWndXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp b/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp
new file mode 100644
index 00000000..4835271f
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuioswndhost.cpp
@@ -0,0 +1,306 @@
+#include <precomp.h>
+#include "xuioswndhost.h"
+#include <api/wnd/notifmsg.h>
+#include <bfc/parse/paramparser.h>
+#include <tataki/region/region.h>
+#include <api/wndmgr/layout.h>
+// -----------------------------------------------------------------------
+const wchar_t OSWndHostXuiObjectStr[] = L"OSWndHost"; // This is the xml tag
+char OSWndHostXuiSvcName[] = "OSWndHost xui object";
+
+XMLParamPair XuiOSWndHost::params[] = {
+ {XUIOSWNDHOST_SETHWND, L"HWND"},
+ {XUIOSWNDHOST_SETOFFSETS, L"OFFSETS"},
+ };
+// -----------------------------------------------------------------------
+XuiOSWndHost::XuiOSWndHost() {
+ hosted=false;
+ setStartHidden(1);
+ setVisible(0);
+ visible_start_state=1;
+ setVirtual(0); // we are a real window, with an hwnd and shit
+ hasregionrect = 0;
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ ScriptObject *o = getGuiObject()->guiobject_getScriptObject();
+ o->vcpu_setInterface(osWndHostGuid, static_cast<OSWndHost *>(this));
+}
+
+void XuiOSWndHost::CreateXMLParameters(int master_handle)
+{
+ //XUIOSWNDHOST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+XuiOSWndHost::~XuiOSWndHost() {
+}
+
+void XuiOSWndHost::onSetVisible(int show)
+{
+ visible_start_state = show;
+ XUIOSWNDHOST_PARENT::onSetVisible(show);
+}
+
+// -----------------------------------------------------------------------
+int XuiOSWndHost::onPaint(Canvas *c) {
+ XUIOSWNDHOST_PARENT::onPaint(c);
+ RECT r;
+ getClientRect(&r);
+ c->fillRect(&r, 0);
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int XuiOSWndHost::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return XUIOSWNDHOST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case XUIOSWNDHOST_SETHWND: {
+#ifdef _WIN64
+ HWND wnd = (HWND)_wtoi64(value);
+#else
+ HWND wnd = (HWND)WTOI(value);
+#endif
+ if (IsWindow(wnd))
+ oswndhost_host(wnd);
+ break;
+ }
+ case XUIOSWNDHOST_SETOFFSETS: {
+ ParamParser pp(value, L",");
+ RECT r={0,0,0,0};
+ if (pp.getNumItems() > 0)
+ r.left = WTOI(pp.enumItem(0));
+ if (pp.getNumItems() > 1)
+ r.top = WTOI(pp.enumItem(1));
+ if (pp.getNumItems() > 2)
+ r.right = WTOI(pp.enumItem(2));
+ if (pp.getNumItems() > 3)
+ r.bottom = WTOI(pp.enumItem(3));
+ oswndhost_setRegionOffsets(&r);
+ break;
+ }
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void XuiOSWndHost::oswndhost_setRegionOffsets(RECT *r) {
+ if (r == NULL) {
+ hasregionrect = 0;
+ if (wnd != NULL && isPostOnInit()) {
+ SetWindowRgn(wnd, NULL, 0);
+ onResize();
+ }
+ return;
+ }
+ regionrect = *r;
+ hasregionrect = 1;
+ //if (isPostOnInit())
+ //onResize();
+}
+
+void XuiOSWndHost::doOnResize()
+{
+ if (wnd != NULL)
+ {
+ RECT r;
+ getClientRect(&r);
+ if (renderRatioActive())
+ {
+ //CUT: double ra = getRenderRatio();
+ multRatio(&r);
+ }
+
+ if (hasregionrect) {
+ r.left -= regionrect.left;
+ r.top -= regionrect.top;
+ r.right += regionrect.right;
+ r.bottom += regionrect.bottom;
+ }
+ SetWindowPos(wnd, NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE/*|SWP_NOCOPYBITS|SWP_NOREDRAW*/);
+
+ if (hasregionrect) {
+ RECT cr={0,0,r.right-r.left,r.bottom-r.top};
+ RECT wndr={cr.left+regionrect.left, cr.top+regionrect.top, cr.right-regionrect.right, cr.bottom-regionrect.bottom};
+
+ RegionI reg(&wndr);
+ SetWindowRgn(wnd, reg.makeWindowRegion(), TRUE);
+ //InvalidateRgn(wnd, reg.getOSHandle(), FALSE);
+ }
+ //else
+ //InvalidateRect(wnd, NULL, TRUE);
+
+ //UpdateWindow(wnd);
+ //repaint();
+ }
+}
+int XuiOSWndHost::onAfterResize()
+{
+ if (!XUIOSWNDHOST_PARENT::onAfterResize()) return 0;
+ doHost();
+ doOnResize();
+
+
+ return 1;
+}
+// -----------------------------------------------------------------------
+
+#define STYLE_FILTER (WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW | WS_DLGFRAME | WS_CHILD)
+#define EXSTYLE_FILTER (WS_EX_OVERLAPPEDWINDOW | WS_EX_PALETTEWINDOW | WS_EX_CONTROLPARENT)
+
+void XuiOSWndHost::doHost()
+{
+ if (wnd && !hosted)
+ {
+ onBeforeReparent(1);
+ oldparent = GetAncestor(wnd, GA_PARENT);
+ /*
+ bool blah=false;
+ RECT r;
+ if (IsWindowVisible(wnd))
+ {
+
+ GetWindowRect(wnd, &r);
+ MapWindowPoints(HWND_DESKTOP, oldparent, (LPPOINT)&r, 2);
+ blah=true;
+ }
+*/
+ // remember if WS_POPUP or WS_CHILD was set so we can reset it when we unhost
+
+ DWORD style;
+ style = GetWindowLongPtrW(wnd, GWL_STYLE);
+ savedStyle = (style & STYLE_FILTER);
+ SetWindowLongPtrW(wnd, GWL_STYLE, (style & ~(STYLE_FILTER)) | WS_CHILD);
+ style = GetWindowLongPtrW(wnd, GWL_EXSTYLE);
+ savedExStyle = (style & EXSTYLE_FILTER);
+ SetWindowLongPtrW(wnd, GWL_EXSTYLE, (style & ~(EXSTYLE_FILTER)) | WS_EX_CONTROLPARENT);
+
+ GetWindowRect(wnd, &oldrect);
+
+ SetParent(wnd, gethWnd());
+ //if (blah)
+ //InvalidateRect(oldparent, &r, FALSE);
+ //UpdateWindow(oldparent);
+ SendMessageW(gethWnd(), 0x0127, MAKEWPARAM(3/*UIS_INITIALIZE*/, 3/*UISF_HIDEACCEL | UISF_HIDEFOCUS*/), 0L);
+ onAfterReparent(1);
+ dropVirtualCanvas(); // we don't need a canvas anymore, save the memory!
+ hosted=true;
+ doOnResize();
+ setVisible(visible_start_state);
+ }
+}
+
+// -----------------------------------------------------------------------
+void XuiOSWndHost::oswndhost_host(HWND oswnd)
+{
+ ASSERT(IsWindow(oswnd));
+ wnd = oswnd;
+ if (isPostOnInit())
+ doHost();
+}
+
+// -----------------------------------------------------------------------
+void XuiOSWndHost::oswndhost_unhost() {
+ if (wnd == NULL) return;
+ onBeforeReparent(0);
+
+ if (IsWindow(wnd)) {
+ // set back the old flags
+
+ DWORD style;
+ style = GetWindowLongPtrW(wnd, GWL_STYLE);
+ SetWindowLongPtrW(wnd, GWL_STYLE, ((style & ~STYLE_FILTER) | savedStyle));
+ style = GetWindowLongPtrW(wnd, GWL_EXSTYLE);
+ SetWindowLongPtrW(wnd, GWL_EXSTYLE, ((style & ~EXSTYLE_FILTER) | savedExStyle));
+
+ int config_aot = ((GetWindowLong(WASABI_API_WND->main_getRootWnd()->gethWnd(), GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
+
+ SetWindowPos(wnd, config_aot ? HWND_TOPMOST : HWND_NOTOPMOST,
+ oldrect.left, oldrect.top, oldrect.right-oldrect.left, oldrect.bottom-oldrect.top,
+ SWP_NOZORDER | (( 0 == config_aot) ? SWP_NOACTIVATE : 0));
+
+ SetParent(wnd, oldparent);
+
+ if (hasregionrect) SetWindowRgn(wnd, NULL, 0);
+// InvalidateRect(wnd, NULL, TRUE);
+ hosted=false;
+
+ }
+
+ onAfterReparent(0);
+
+ hasregionrect = 0;
+ wnd = NULL;
+}
+
+int XuiOSWndHost::onUserMessage(int msg, int w, int l, int *r) {
+ switch (msg) {
+ case OSWNDHOST_REQUEST_IDEAL_SIZE:
+ onDeferredCallback/*postDeferredCallback*/(DCB_OSWNDHOST_REQUEST_IDEAL_SIZE, (intptr_t)(new DCBIdealSize(w, l)));
+ *r = 1;
+ return 1;
+ }
+ return XUIOSWNDHOST_PARENT::onUserMessage(msg, w, l, r); // do default handling
+}
+
+int XuiOSWndHost::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ switch (p1) {
+ case DCB_OSWNDHOST_REQUEST_IDEAL_SIZE:
+ {
+ DCBIdealSize *ideal = (DCBIdealSize *)p2;
+ if (ideal == NULL) break;
+
+ ifc_window *p=getDesktopParent(); // Gets the group/layout at the base of the wnd tree, the desktop hwnd
+ if (p == NULL) {
+ delete ideal;
+ break;
+ }
+ Layout *l = static_cast<Layout *>(p->getInterface(layoutGuid));
+ if (l)
+ l->beginResize();
+ RECT r,r2;
+ getClientRect(&r); // the size of this wnd
+ if (renderRatioActive()) multRatio(&r);
+
+ p->getWindowRect(&r2); // the size of the desktop parent
+
+ // take borders into account
+ int neww = ideal->m_idealwidth+((r2.right-r2.left)-(r.right-r.left));
+ int newh = ideal->m_idealheight+((r2.bottom-r2.top)-(r.bottom-r.top));
+
+ // take layout min/max values into account
+ int min_w = p->getPreferences(MINIMUM_W);
+ int min_h = p->getPreferences(MINIMUM_H);
+ int max_w = p->getPreferences(MAXIMUM_W);
+ int max_h = p->getPreferences(MAXIMUM_H);
+ if (min_w != AUTOWH) neww = MAX(min_w, neww);
+ if (min_h != AUTOWH) newh = MAX(min_h, newh);
+ if (max_w != AUTOWH) neww = MIN(max_w, neww);
+ if (max_h != AUTOWH) newh = MIN(max_h, newh);
+
+ //CUT: RECT res={r2.left,r2.top,neww,newh};
+ p->resize(r2.left, r2.top, neww, newh);
+ if (l)
+ l->endResize();
+ delete ideal;
+ return 1;
+ }
+
+ }
+ return XUIOSWNDHOST_PARENT::onDeferredCallback(p1, p2);
+}
+
+void XuiOSWndHost::onBeforeReparent(int i) {
+}
+
+void XuiOSWndHost::onAfterReparent(int i) {
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuioswndhost.h b/Src/Wasabi/api/skin/widgets/xuioswndhost.h
new file mode 100644
index 00000000..05359563
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuioswndhost.h
@@ -0,0 +1,78 @@
+#ifndef __OSWndHost_H
+#define __OSWndHost_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/wnd/wndclass/oswndhost.h>
+
+#define XUIOSWNDHOST_PARENT GuiObjectWnd
+
+#define DCB_OSWNDHOST_REQUEST_IDEAL_SIZE 2048
+
+#define OSWNDHOST_REQUEST_IDEAL_SIZE WM_USER + DCB_OSWNDHOST_REQUEST_IDEAL_SIZE
+
+class DCBIdealSize {
+ public:
+ DCBIdealSize(int idealwidth, int idealheight) : m_idealwidth(idealwidth), m_idealheight(idealheight) {}
+ int m_idealwidth;
+ int m_idealheight;
+};
+
+// -----------------------------------------------------------------------
+class XuiOSWndHost : public XUIOSWNDHOST_PARENT, public OSWndHostI
+{
+
+ public:
+
+ XuiOSWndHost();
+ virtual ~XuiOSWndHost();
+ virtual int onPaint(Canvas *c);
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+ virtual int wantRedrawOnResize() { return 0; }
+ virtual int onAfterResize();
+ void setHWND(const char *hwnd);
+ HWND getHWND() { return wnd; }
+ void setHWND(HWND hwnd) { wnd = hwnd; }
+ virtual void oswndhost_host(HWND oswnd);
+ virtual void oswndhost_unhost();
+ virtual void oswndhost_setRegionOffsets(RECT *r);
+
+ virtual int onUserMessage(int msg, int w, int l, int *r);
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ virtual void onBeforeReparent(int host);
+ virtual void onAfterReparent(int host);
+ virtual int handleRatio() { return 0; }
+ virtual int handleDesktopAlpha() { return 0; }
+ void onSetVisible(int show);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+ void doOnResize();
+ void doHost();
+
+ enum {
+ XUIOSWNDHOST_SETHWND = 0,
+ XUIOSWNDHOST_SETOFFSETS = 1,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+ RECT regionrect;
+ int hasregionrect;
+ HWND wnd;
+ HWND oldparent;
+ DWORD savedStyle;
+ DWORD savedExStyle;
+
+ RECT oldrect;
+ bool hosted;
+ int visible_start_state;
+};
+
+
+// -----------------------------------------------------------------------
+
+extern const wchar_t OSWndHostXuiObjectStr[];
+extern char OSWndHostXuiSvcName[];
+class OSWndHostXuiSvc : public XuiObjectSvc<XuiOSWndHost, OSWndHostXuiObjectStr, OSWndHostXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuipathpicker.cpp b/Src/Wasabi/api/skin/widgets/xuipathpicker.cpp
new file mode 100644
index 00000000..45c2d27e
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuipathpicker.cpp
@@ -0,0 +1,73 @@
+#include <precomp.h>
+#include "xuipathpicker.h"
+
+// -----------------------------------------------------------------------
+const wchar_t PathPickerXuiObjectStr[] = L"Wasabi:PathPicker";
+char PathPickerXuiSvcName[] = "Wasabi:PathPicker xui object";
+
+// -----------------------------------------------------------------------
+ScriptPathPicker::ScriptPathPicker() {
+ getScriptObject()->vcpu_setInterface(pathPickerGuid, (void *)static_cast<PathPicker *>(this));
+ getScriptObject()->vcpu_setClassName(L"PathPicker"); // this is the script class name
+ getScriptObject()->vcpu_setController(pathPickerController);
+}
+
+// -----------------------------------------------------------------------
+ScriptPathPicker::~ScriptPathPicker() {
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+PathPickerScriptController _pathPickerController;
+PathPickerScriptController *pathPickerController = &_pathPickerController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct PathPickerScriptController::exportedFunction[] = {
+ {L"getPath", 0, (void*)PathPickerScriptController::PathPicker_getPath},
+ {L"onPathChanged", 1, (void*)PathPickerScriptController::PathPicker_onPathChanged},
+};
+
+ScriptObject *PathPickerScriptController::instantiate() {
+ ScriptPathPicker *sddl = new ScriptPathPicker;
+ ASSERT(sddl != NULL);
+ return sddl->getScriptObject();
+}
+
+void PathPickerScriptController::destroy(ScriptObject *o) {
+ ScriptPathPicker *sddl= static_cast<ScriptPathPicker *>(o->vcpu_getInterface(pathPickerGuid));
+ ASSERT(sddl != NULL);
+ delete sddl;
+}
+
+void *PathPickerScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation
+}
+
+void PathPickerScriptController::deencapsulate(void *o) {
+}
+
+int PathPickerScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *PathPickerScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar PathPickerScriptController::PathPicker_getPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptPathPicker *sddl = static_cast<ScriptPathPicker*>(o->vcpu_getInterface(pathPickerGuid));
+ const wchar_t *p=L"";
+ if (sddl) p = sddl->getPath();
+ return MAKE_SCRIPT_STRING(p);
+}
+
+// PathPickerScriptController::PathPicker_onNewPath(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_STRING(newpath));
+scriptVar PathPickerScriptController::PathPicker_onPathChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newpath) {
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, pathPickerController, newpath);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, newpath);
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuipathpicker.h b/Src/Wasabi/api/skin/widgets/xuipathpicker.h
new file mode 100644
index 00000000..05ca69b0
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuipathpicker.h
@@ -0,0 +1,53 @@
+#ifndef __XUIPATHPICKER_H
+#define __XUIPATHPICKER_H
+
+#include <api/skin/widgets/pathpicker.h>
+#include <api/script/objcontroller.h>
+
+#define SCRIPTPATHPICKER_PARENT PathPicker
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+
+class ScriptPathPicker: public SCRIPTPATHPICKER_PARENT {
+
+ public:
+
+ ScriptPathPicker();
+ virtual ~ScriptPathPicker();
+
+ private:
+};
+
+// -----------------------------------------------------------------------
+class PathPickerScriptController: public ScriptObjectControllerI {
+public:
+ virtual const wchar_t *getClassName() { return L"PathPicker"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return pathPickerGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+private:
+
+ static function_descriptor_struct exportedFunction[];
+ static scriptVar PathPicker_getPath(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar PathPicker_onPathChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newpath);
+};
+
+extern PathPickerScriptController *pathPickerController;
+
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+extern const wchar_t PathPickerXuiObjectStr[];
+extern char PathPickerXuiSvcName[];
+class PathPickerXuiSvc : public XuiObjectSvc<ScriptPathPicker, PathPickerXuiObjectStr, PathPickerXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp
new file mode 100644
index 00000000..edb9e918
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.cpp
@@ -0,0 +1,162 @@
+#include <precomp.h>
+#include "xuiprogressgrid.h"
+#include <tataki/canvas/ifc_canvas.h>
+#include <bfc/string/stringdict.h>
+#include <api/core/api_core.h>
+
+#define ProgressGrid_TIMER_POS 1
+#define PROGRESSGRID_INTERVAL 500
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(ProgressGrid_Svc);
+DECLARE_SERVICE(XuiObjectCreator<ProgressGridXuiSvc>);
+END_SERVICES(ProgressGrid_Svc, _ProgressGrid_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_ProgressGridXuiSvc; }
+#else
+extern "C" { int __link_ProgressGridXuiSvc; }
+#endif
+
+#endif
+
+BEGIN_STRINGDICTIONARY(_pgorientationvalues)
+SDI(L"top", PROGRESSGRID_TOP);
+SDI(L"left", PROGRESSGRID_LEFT);
+SDI(L"right", PROGRESSGRID_RIGHT);
+SDI(L"bottom", PROGRESSGRID_BOTTOM);
+END_STRINGDICTIONARY(_pgorientationvalues, pgorientationvalues)
+
+// -----------------------------------------------------------------------
+
+const wchar_t ProgressGridXuiObjectStr[] = L"ProgressGrid"; // xml tag
+char ProgressGridXuiSvcName[] = "ProgressGrid xui object";
+XMLParamPair ProgressGrid::params[] = {
+ { PROGRESSGRID_SETORIENTATION, L"ORIENTATION"},
+ { PROGRESSGRID_SETINTERVAL, L"INTERVAL"},
+};
+
+// -----------------------------------------------------------------------
+ProgressGrid::ProgressGrid() {
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ orientation = PROGRESSGRID_RIGHT;
+ progress = 0;
+ started = 0;
+ update_interval = PROGRESSGRID_INTERVAL;
+}
+
+void ProgressGrid::CreateXMLParameters(int master_handle)
+{
+ //PROGRESSGRID_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ProgressGrid::~ProgressGrid() {
+ killTimer(ProgressGrid_TIMER_POS);
+ WASABI_API_MEDIACORE->core_delCallback(0, this);
+}
+
+// -----------------------------------------------------------------------
+int ProgressGrid::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return PROGRESSGRID_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid) {
+ case PROGRESSGRID_SETORIENTATION:
+ setOrientation(value);
+ break;
+
+ case PROGRESSGRID_SETINTERVAL:
+ if ((update_interval = WTOI(value)) <= 20)
+ update_interval = PROGRESSGRID_INTERVAL;
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ProgressGrid::setOrientation(const wchar_t *or) {
+ int a = pgorientationvalues.getId(or);
+ if (orientation == a) return;
+ orientation = a;
+ invalidate();
+}
+
+// -----------------------------------------------------------------------
+void ProgressGrid::getGridRect(RECT *r) {
+ RECT cr;
+ getClientRect(&cr);
+ float p = started ? progress : 0.0f;
+ int height = (int)((float)(cr.bottom - cr.top) * p);
+ int width = (int)((float)(cr.right - cr.left) * p);
+
+ switch (orientation) {
+ case PROGRESSGRID_LEFT: cr.left = cr.right - width; break;
+ case PROGRESSGRID_TOP: cr.top = cr.bottom - height; break;
+ case PROGRESSGRID_RIGHT: cr.right = cr.left + width; break;
+ case PROGRESSGRID_BOTTOM: cr.bottom = cr.top + height; break;
+ }
+ *r = cr;
+}
+
+// -----------------------------------------------------------------------
+int ProgressGrid::onInit() {
+ PROGRESSGRID_PARENT::onInit();
+ timerCallback(ProgressGrid_TIMER_POS);
+ setTimer(ProgressGrid_TIMER_POS, update_interval);
+ WASABI_API_MEDIACORE->core_addCallback(0, this);
+ if (WASABI_API_MEDIACORE->core_getStatus(0) != 0) started = 1; else started = 0;
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int ProgressGrid::corecb_onSeeked(int newpos) {
+ if(!started) corecb_onStarted();
+ int len = WASABI_API_MEDIACORE->core_getLength(0);
+ if (newpos == -1 || len <= 0) setProgress(0);
+ else setProgress(((float)newpos/(float)len));
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+int ProgressGrid::corecb_onStarted() {
+ started = 1;
+ invalidate();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+int ProgressGrid::corecb_onStopped() {
+ started = 0;
+ progress = 0.0f;
+ invalidate();
+ return 0;
+}
+
+void ProgressGrid::setProgress(float p) {
+ if (progress == p) return;
+ progress = p;
+ invalidate();
+}
+
+void ProgressGrid::timerCallback(int id) {
+ switch (id) {
+ case ProgressGrid_TIMER_POS: {
+ int playpos = WASABI_API_MEDIACORE->core_getPosition(0);
+ corecb_onSeeked(playpos);
+ }
+ break;
+ default:
+ PROGRESSGRID_PARENT::timerCallback(id);
+ }
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/xuiprogressgrid.h b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.h
new file mode 100644
index 00000000..ba215bfa
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiprogressgrid.h
@@ -0,0 +1,59 @@
+#ifndef __PROGRESSGRID_H
+#define __PROGRESSGRID_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include "xuigrid.h"
+#include <api/syscb/callbacks/corecbi.h>
+
+#define PROGRESSGRID_PARENT Grid
+
+enum {
+ PROGRESSGRID_TOP = 0,
+ PROGRESSGRID_LEFT = 1,
+ PROGRESSGRID_RIGHT = 2,
+ PROGRESSGRID_BOTTOM = 3,
+};
+
+// -----------------------------------------------------------------------
+class ProgressGrid : public PROGRESSGRID_PARENT, public CoreCallbackI {
+
+ public:
+
+ ProgressGrid();
+ virtual ~ProgressGrid();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void setOrientation(const wchar_t *or);
+ virtual void getGridRect(RECT *r);
+
+ virtual void setProgress(float p); // 0..1
+
+ virtual int onInit();
+ virtual int corecb_onSeeked(int newpos);
+ virtual int corecb_onStarted();
+ virtual int corecb_onStopped();
+ virtual void timerCallback(int id);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ enum {
+ PROGRESSGRID_SETORIENTATION = 0,
+ PROGRESSGRID_SETINTERVAL = 1,
+ };
+ static XMLParamPair params[];
+ int orientation;
+ int myxuihandle;
+ float progress;
+ int started;
+ int update_interval;
+};
+
+
+// -----------------------------------------------------------------------
+extern const wchar_t ProgressGridXuiObjectStr[];
+extern char ProgressGridXuiSvcName[];
+class ProgressGridXuiSvc : public XuiObjectSvc<ProgressGrid, ProgressGridXuiObjectStr, ProgressGridXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp b/Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp
new file mode 100644
index 00000000..c25ee183
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiradiogroup.cpp
@@ -0,0 +1,17 @@
+#include <precomp.h>
+#include "xuiradiogroup.h"
+#include <bfc/parse/paramparser.h>
+#include <api/script/objects/c_script/c_text.h>
+
+// -----------------------------------------------------------------------
+const wchar_t ScriptRadioGroupXuiObjectStr[] = L"Wasabi:RadioGroup"; // This is the xml tag
+char ScriptRadioGroupXuiSvcName[] = "Wasabi:RadioGroup xui object";
+
+// -----------------------------------------------------------------------
+ScriptRadioGroup::ScriptRadioGroup() : SCRIPTRADIOGROUP_PARENT(), myxuihandle(0) {
+}
+
+// -----------------------------------------------------------------------
+ScriptRadioGroup::~ScriptRadioGroup() {
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuiradiogroup.h b/Src/Wasabi/api/skin/widgets/xuiradiogroup.h
new file mode 100644
index 00000000..7ac7e636
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiradiogroup.h
@@ -0,0 +1,30 @@
+#ifndef __SCRIPTRADIOGROUP_H
+#define __SCRIPTRADIOGROUP_H
+
+#include <api/skin/widgets/guiradiogroup.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+
+#define SCRIPTRADIOGROUP_PARENT GuiRadioGroup
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+class ScriptRadioGroup : public SCRIPTRADIOGROUP_PARENT {
+
+ public:
+
+ ScriptRadioGroup();
+ virtual ~ScriptRadioGroup();
+
+ private:
+
+ int myxuihandle;
+};
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+extern const wchar_t ScriptRadioGroupXuiObjectStr[];
+extern char ScriptRadioGroupXuiSvcName[];
+class ScriptRadioGroupXuiSvc : public XuiObjectSvc<ScriptRadioGroup, ScriptRadioGroupXuiObjectStr, ScriptRadioGroupXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuirect.cpp b/Src/Wasabi/api/skin/widgets/xuirect.cpp
new file mode 100644
index 00000000..dd692893
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuirect.cpp
@@ -0,0 +1,186 @@
+#include <precomp.h>
+#include "xuirect.h"
+
+#include <tataki/canvas/ifc_canvas.h>
+#include <bfc/parse/paramparser.h>
+#include <api/skin/skinfilter.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define BLTSIZE 1
+
+
+namespace RectEdges
+{
+enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
+};
+using namespace RectEdges;
+
+XMLParamPair ScriptRect::params[] = {
+ {SCRIPTRECT_SETCOLOR, L"COLOR"},
+ {SCRIPTRECT_EDGES, L"EDGES"},
+ {SCRIPTRECT_SETFILLED, L"FILLED"},
+ {SCRIPTRECT_GAMMAGROUP, L"GAMMAGROUP"},
+ {SCRIPTRECT_THICKNESS, L"THICKNESS"},
+ };
+
+ScriptRect::ScriptRect()
+ : pixel(BLTSIZE, BLTSIZE, NULL)
+{
+ filled = 0;
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+ color.setColorGroup(L"");
+
+ resetPixel();
+ edges = LEFT | RIGHT | TOP | BOTTOM;
+ thickness = 1;
+}
+
+void ScriptRect::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTRECT_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ if (params[i].id == SCRIPTRECT_SETCOLOR)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_REQUIRED);
+ else
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ScriptRect::~ScriptRect()
+{}
+
+int ScriptRect::onInit()
+{
+ SCRIPTRECT_PARENT::onInit();
+ return 1;
+}
+
+int ScriptRect::onPaint(Canvas *c)
+{
+ if (c == NULL)
+ {
+ PaintCanvas pc;
+ if (!pc.beginPaint(this)) return 0;
+ return ScriptRect::onPaint(&pc);
+ }
+
+ // check for colors changing on us
+ if (!color.iteratorValid()) resetPixel();
+
+ //RECT src = {0, 0, BLTSIZE, BLTSIZE};
+ if (filled)
+ {
+ RECT dst;
+ getClientRect(&dst);
+ c->fillRectAlpha(&dst, color.v(), getPaintingAlpha());
+// pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha());
+ }
+ else
+ {
+ RECT dst, odst;
+ getClientRect(&odst);
+ if (edges & TOP)
+ {
+ dst = odst;
+ dst.bottom = dst.top + thickness;
+ c->fillRectAlpha(&dst, color.v(), getPaintingAlpha());
+ //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha());
+ }
+ if (edges & BOTTOM)
+ {
+ dst = odst;
+ dst.top = dst.bottom - thickness;
+ c->fillRectAlpha(&dst, color.v(), getPaintingAlpha());
+ //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha());
+ }
+ if (edges & RIGHT)
+ {
+ dst = odst;
+ dst.top++; dst.bottom--;
+ dst.left = dst.right - thickness;
+ c->fillRectAlpha(&dst, color.v(), getPaintingAlpha());
+ //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha());
+ }
+ if (edges & LEFT)
+ {
+ dst = odst;
+ dst.right = dst.left + thickness;
+ c->fillRectAlpha(&dst, color.v(), getPaintingAlpha());
+ //pixel./*getSkinBitmap()->*/stretchToRectAlpha(c, &src, &dst, getPaintingAlpha());
+
+ }
+ }
+
+ return 1;
+}
+
+int ScriptRect::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return SCRIPTRECT_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case SCRIPTRECT_SETCOLOR:
+ {
+ ARGB32 prev_color = color;
+ color.setElementName(value);
+ //CUT color = WASABI_API_SKIN->skin_getColorElement((char*)value);
+ if (color.v() != prev_color)
+ {
+ //CUT? ApplySkinFilters::apply(NULL, getXmlParamByName("gammagroup"), &color, BLTSIZE, BLTSIZE);
+ resetPixel();
+ invalidate();
+ }
+ }
+ break;
+ case SCRIPTRECT_GAMMAGROUP:
+ {
+ ARGB32 prev_color = color;
+ color.setColorGroup(value);
+ if (color.v() != prev_color)
+ {
+ resetPixel();
+ invalidate();
+ }
+ }
+ break;
+ case SCRIPTRECT_SETFILLED:
+ {
+ int was_filled = filled;
+ filled = WTOI(value);
+ if (was_filled != filled) invalidate();
+ }
+ break;
+ case SCRIPTRECT_EDGES:
+ {
+ int prev_edges = edges;
+ ParamParser pp((const wchar_t *)value);
+ edges = 0;
+ edges |= !!pp.hasString(L"left") * LEFT;
+ edges |= !!pp.hasString(L"right") * RIGHT;
+ edges |= !!pp.hasString(L"top") * TOP;
+ edges |= !!pp.hasString(L"bottom") * BOTTOM;
+ if (edges != prev_edges) invalidate();
+ }
+ break;
+ case SCRIPTRECT_THICKNESS:
+ {
+ int prev_thickness = thickness;
+ thickness = WTOI(value);
+ if (thickness < 1) thickness = 1;
+ if (thickness != prev_thickness) invalidate();
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void ScriptRect::resetPixel()
+{
+ pixel.fillBits(0xFF000000 | RGBTOBGR(color.v()));
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuirect.h b/Src/Wasabi/api/skin/widgets/xuirect.h
new file mode 100644
index 00000000..e986d6d1
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuirect.h
@@ -0,0 +1,43 @@
+#ifndef _XUIRECT_H
+#define _XUIRECT_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <tataki/color/skinclr.h>
+#include <tataki/canvas/bltcanvas.h>
+#define SCRIPTRECT_PARENT GuiObjectWnd
+class ScriptRect : public SCRIPTRECT_PARENT {
+public:
+ static const wchar_t *xuiobject_getXmlTag() { return L"Rect"; }
+ static const char *xuiobject_getServiceName() { return "Rect XuiObject"; }
+
+ ScriptRect();
+ virtual ~ScriptRect();
+
+ virtual int onInit();
+
+ virtual int onPaint(Canvas *c);
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ enum {
+ SCRIPTRECT_SETCOLOR = 0,
+ SCRIPTRECT_SETFILLED,
+ SCRIPTRECT_EDGES,
+ SCRIPTRECT_THICKNESS,
+ SCRIPTRECT_GAMMAGROUP,
+};
+ static XMLParamPair params[];
+ void resetPixel();
+
+ int myxuihandle;
+ SkinColor color;
+ int filled, edges, thickness;
+ BltCanvas pixel;
+};
+
+class ScriptRectXuiSvc : public XuiObjectSvc2<ScriptRect> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuisendparams.cpp b/Src/Wasabi/api/skin/widgets/xuisendparams.cpp
new file mode 100644
index 00000000..64a03633
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuisendparams.cpp
@@ -0,0 +1,37 @@
+#include <precomp.h>
+#include "xuisendparams.h"
+#include <api/script/scriptguid.h>
+
+// -----------------------------------------------------------------------
+const wchar_t SendParamsXuiObjectStr[] = L"SendParams"; // This is the xml tag
+char SendParamsXuiSvcName[] = "SendParams xui object";
+
+// -----------------------------------------------------------------------
+SendParams::SendParams():myxuihandle(0) {
+}
+
+// -----------------------------------------------------------------------
+SendParams::~SendParams() {
+ pastlist.deleteAll();
+}
+
+// -----------------------------------------------------------------------
+int SendParams::setXmlParam(const wchar_t *param, const wchar_t *value)
+{
+ int r = SENDPARAMS_PARENT::setXmlParam(param, value);
+ if (!WCSCASEEQLSAFE(param, L"group") && !WCSCASEEQLSAFE(param, L"target")) {
+ Pair<StringW, StringW> *pair = new Pair<StringW, StringW>(param, value);
+ pastlist.addItem(pair);
+ }
+ return r;
+}
+
+// -----------------------------------------------------------------------
+void SendParams::actuator_onPerform(GuiObject *target) { // guaranteed non NULL
+ SENDPARAMS_PARENT::actuator_onPerform(target);
+ XmlObject *xtarget = static_cast<XmlObject *>(target->guiobject_getScriptObject()->vcpu_getInterface(xmlObjectGuid));
+ foreach(pastlist)
+ xtarget->setXmlParam(pastlist.getfor()->a, pastlist.getfor()->b);
+ endfor;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuisendparams.h b/Src/Wasabi/api/skin/widgets/xuisendparams.h
new file mode 100644
index 00000000..0096ed89
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuisendparams.h
@@ -0,0 +1,36 @@
+#ifndef __SENDPARAMS_H
+#define __SENDPARAMS_H
+
+#include <api/skin/objectactuator.h>
+#include <bfc/pair.h>
+
+#define SENDPARAMS_PARENT ObjectActuator
+
+extern const wchar_t SendParamsXuiObjectStr[];
+extern char SendParamsXuiSvcName[];
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+class SendParams: public SENDPARAMS_PARENT {
+
+ public:
+
+ SendParams();
+ virtual ~SendParams();
+
+ virtual int setXmlParam(const wchar_t *param, const wchar_t *value);
+ virtual void actuator_onPerform(GuiObject *target);
+ virtual const wchar_t *getActuatorTag() { return SendParamsXuiObjectStr; } // for error msgs purposes
+
+ private:
+
+ int myxuihandle;
+ PtrList< Pair<StringW, StringW> > pastlist;
+};
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+class SendParamsXuiSvc : public XuiObjectSvc<SendParams, SendParamsXuiObjectStr, SendParamsXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuistatus.cpp b/Src/Wasabi/api/skin/widgets/xuistatus.cpp
new file mode 100644
index 00000000..efc10ddd
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuistatus.cpp
@@ -0,0 +1,98 @@
+#include <precomp.h>
+#include "xuistatus.h"
+
+const wchar_t StatusXuiObjectStr[] = L"LayoutStatus"; // This is the xml tag
+char StatusXuiSvcName[] = "Status xui object";
+
+LayoutStatusController _layoutStatusController;
+LayoutStatusController *layoutStatusController = &_layoutStatusController;
+
+
+XMLParamPair XuiStatus::params[] = {
+ {EXCLUDE, L"EXCLUDE"},
+ {INCLUDE, L"INCLUDEONLY"},
+ };
+
+XuiStatus::XuiStatus() {
+ getScriptObject()->vcpu_setInterface(layoutStatusGuid, (void *)static_cast<XuiStatus *>(this));
+ getScriptObject()->vcpu_setClassName(L"LayoutStatus"); // this is the script class name
+ getScriptObject()->vcpu_setController(layoutStatusController);
+
+ myxuihandle = newXuiHandle();
+CreateXMLParameters(myxuihandle);
+}
+
+void XuiStatus::CreateXMLParameters(int master_handle)
+{
+ //XUISTATUS_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+int XuiStatus::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return XUISTATUS_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+ switch (xmlattributeid) {
+ case EXCLUDE:
+ setExclude(value);
+ break;
+ case INCLUDE:
+ setIncludeOnly(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void XuiStatus::callme(const wchar_t *str)
+{
+ fakeButtonPush(str);
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+// -- Functions table -------------------------------------
+function_descriptor_struct LayoutStatusController::exportedFunction[] = {
+ {L"callme", 1, (void*)LayoutStatusController::layoutstatus_callme },
+};
+
+ScriptObject *LayoutStatusController::instantiate() {
+ XuiStatus *xs = new XuiStatus;
+ ASSERT(xs != NULL);
+ return xs->getScriptObject();
+}
+
+void LayoutStatusController::destroy(ScriptObject *o) {
+ XuiStatus *xs = static_cast<XuiStatus *>(o->vcpu_getInterface(layoutStatusGuid));
+ ASSERT(xs!= NULL);
+ delete xs;
+}
+
+void *LayoutStatusController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for layoutstatus yet
+}
+
+void LayoutStatusController::deencapsulate(void *o) {
+}
+
+int LayoutStatusController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *LayoutStatusController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar LayoutStatusController::layoutstatus_callme(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str) {
+ SCRIPT_FUNCTION_INIT
+ XuiStatus *xs = static_cast<XuiStatus *>(o->vcpu_getInterface(layoutStatusGuid));
+ if (xs) xs->callme(GET_SCRIPT_STRING(str));
+ RETURN_SCRIPT_VOID;
+}
+
diff --git a/Src/Wasabi/api/skin/widgets/xuistatus.h b/Src/Wasabi/api/skin/widgets/xuistatus.h
new file mode 100644
index 00000000..972190e3
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuistatus.h
@@ -0,0 +1,54 @@
+#ifndef __XUISTATUS_H
+#define __XUISTATUS_H
+
+#include <api/wnd/wndclass/status.h>
+#include <api/script/objcontroller.h>
+
+#define XUISTATUS_PARENT StatusBar
+class XuiStatus : public XUISTATUS_PARENT {
+public:
+ XuiStatus();
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ virtual void callme(const wchar_t *txt);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+
+enum {
+ EXCLUDE, INCLUDE
+};
+ static XMLParamPair params[];
+ int myxuihandle;
+};
+
+extern const wchar_t StatusXuiObjectStr[];
+extern char StatusXuiSvcName[];
+class LayoutStatusXuiSvc : public XuiObjectSvc<XuiStatus, StatusXuiObjectStr, StatusXuiSvcName> {};
+
+// -----------------------------------------------------------------------------------------------------
+class LayoutStatusController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"LayoutStatus"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return layoutStatusGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar layoutstatus_callme(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar str);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern LayoutStatusController *layoutStatusController;
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuitabsheet.cpp b/Src/Wasabi/api/skin/widgets/xuitabsheet.cpp
new file mode 100644
index 00000000..4b777e64
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuitabsheet.cpp
@@ -0,0 +1,217 @@
+#include <precomp.h>
+#include "xuitabsheet.h"
+#include <bfc/parse/paramparser.h>
+static ScriptTabSheetController TabsheetController;
+ScriptTabSheetController *tabsheetController=&TabsheetController;
+
+// -----------------------------------------------------------------------
+const wchar_t ScriptTabSheetXuiObjectStr[] = L"Wasabi:TabSheet"; // This is the xml tag
+char ScriptTabSheetXuiSvcName[] = "Wasabi:TabSheet xui object";
+
+XMLParamPair ScriptTabSheet::params[] = {
+
+ {SCRIPTTABSHEET_SETCHILDREN, L"CHILDREN"},
+ {SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM, L"CONTENT_MARGIN_BOTTOM"},
+ {SCRIPTTABSHEET_SETCONTENTMARGINLEFT, L"CONTENT_MARGIN_LEFT"},
+ {SCRIPTTABSHEET_SETCONTENTMARGINRIGHT, L"CONTENT_MARGIN_RIGHT"},
+ {SCRIPTTABSHEET_SETCONTENTMARGINTOP, L"CONTENT_MARGIN_TOP"},
+ {SCRIPTTABSHEET_SETTYPE, L"TYPE"},
+ {SCRIPTTABSHEET_SETWINDOWTYPE, L"WINDOWTYPE"},
+ };
+// -----------------------------------------------------------------------
+ScriptTabSheet::ScriptTabSheet() : TypeSheet(0) {
+ getScriptObject()->vcpu_setInterface(tabsheetGuid, (void *)static_cast<ScriptTabSheet*>(this));
+ getScriptObject()->vcpu_setClassName(L"TabSheet"); // this is the script class name
+ getScriptObject()->vcpu_setController(tabsheetController);
+
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ wndtype = 0;
+ type = TABSHEET_GROUPS;
+ left_margin = right_margin = bottom_margin = top_margin = 0;
+}
+
+void ScriptTabSheet::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTTABSHEET_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ScriptTabSheet::~ScriptTabSheet() {
+ children_id.deleteAll();
+}
+
+// -----------------------------------------------------------------------
+int ScriptTabSheet::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return SCRIPTTABSHEET_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case SCRIPTTABSHEET_SETWINDOWTYPE:
+ setWindowType(value);
+ break;
+ case SCRIPTTABSHEET_SETCHILDREN:
+ setChildrenIds(value);
+ break;
+ case SCRIPTTABSHEET_SETTYPE:
+ setType(value);
+ break;
+ case SCRIPTTABSHEET_SETCONTENTMARGINLEFT:
+ case SCRIPTTABSHEET_SETCONTENTMARGINTOP:
+ case SCRIPTTABSHEET_SETCONTENTMARGINRIGHT:
+ case SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM:
+ setContentMarginX(value, xmlattributeid);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ScriptTabSheet::setWindowType(const wchar_t *paramvalue) {
+ if (WCSEQLSAFE(wndtype, paramvalue)) return;
+ wndtype = paramvalue;
+ reloadChildren();
+}
+
+// -----------------------------------------------------------------------
+void ScriptTabSheet::setChildrenIds(const wchar_t *paramvalue) {
+ if (WCSEQLSAFE(paramvalue, L"")) {
+ children_id.removeAll();
+ }
+ ParamParser pp(paramvalue);
+ for (int i=0;i<pp.getNumItems();i++)
+ children_id.addItem(new StringW(pp.enumItem(i)));
+ reloadChildren();
+}
+
+// -----------------------------------------------------------------------
+void ScriptTabSheet::setType(const wchar_t *paramvalue) {
+ int ttype = WTOI(paramvalue);
+ if (type == ttype) return;
+ type = ttype;
+ setButtonType(type);
+}
+
+// -----------------------------------------------------------------------
+void ScriptTabSheet::reloadChildren() {
+ if (!isInited()) return;
+ killChildren();
+ for (int i=0;i<children_id.getNumItems();i++) {
+ GuiObjectWnd *w = new GuiObjectWnd;
+ //w->abstract_setAllowDeferredContent(1);
+ w->setContent(children_id.enumItem(i)->getValue());
+ addChild(w);
+ }
+ TypeSheet::setWindowType(wndtype);
+ if (!wndtype.isempty())
+ TypeSheet::load();
+}
+
+// -----------------------------------------------------------------------
+int ScriptTabSheet::onInit() {
+ int r = SCRIPTTABSHEET_PARENT::onInit();
+ setButtonType(type);
+ reloadChildren();
+ return r;
+}
+
+void ScriptTabSheet::setContentMarginX(const wchar_t *value, int what) {
+ switch (what) {
+ case SCRIPTTABSHEET_SETCONTENTMARGINLEFT:
+ setContentMarginLeft(WTOI(value));
+ break;
+ case SCRIPTTABSHEET_SETCONTENTMARGINTOP:
+ setContentMarginTop(WTOI(value));
+ break;
+ case SCRIPTTABSHEET_SETCONTENTMARGINRIGHT:
+ setContentMarginRight(WTOI(value));
+ break;
+ case SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM:
+ setContentMarginBottom(WTOI(value));
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ScriptTabSheetController::exportedFunction[] = {
+ {L"getCurPage", 0, (void*)ScriptTabSheetController::tabsheet_getCurPage },
+ {L"setCurPage", 1, (void*)ScriptTabSheetController::tabsheet_setCurPage },
+};
+
+ScriptObject *ScriptTabSheetController::instantiate() {
+ ScriptTabSheet *sts = new ScriptTabSheet;
+ ASSERT(sts != NULL);
+ return sts->getScriptObject();
+}
+
+void ScriptTabSheetController::destroy(ScriptObject *o) {
+ ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid));
+ ASSERT(sts != NULL);
+ delete sts;
+}
+
+void *ScriptTabSheetController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for tabsheet yet
+}
+
+void ScriptTabSheetController::deencapsulate(void *o) {
+}
+
+int ScriptTabSheetController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ScriptTabSheetController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar ScriptTabSheetController::tabsheet_getCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid));
+ int a = 0;
+ if (sts) a = sts->getCurPage();
+ return MAKE_SCRIPT_INT(a);
+}
+
+scriptVar ScriptTabSheetController::tabsheet_getNumPages(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid));
+ int a = 0;
+ if (sts) a = sts->getNumPages();
+ return MAKE_SCRIPT_INT(a);
+}
+
+scriptVar ScriptTabSheetController::tabsheet_setCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a) {
+ SCRIPT_FUNCTION_INIT
+ ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid));
+ int _a = GET_SCRIPT_INT(a);
+ if (sts) sts->setCurPage(_a);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptTabSheetController::tabsheet_nextPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid));
+ if (sts) sts->nextPage();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar ScriptTabSheetController::tabsheet_previousPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ ScriptTabSheet *sts = static_cast<ScriptTabSheet *>(o->vcpu_getInterface(tabsheetGuid));
+ if (sts) sts->previousPage();
+ RETURN_SCRIPT_VOID;
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuitabsheet.h b/Src/Wasabi/api/skin/widgets/xuitabsheet.h
new file mode 100644
index 00000000..efb17222
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuitabsheet.h
@@ -0,0 +1,91 @@
+#ifndef __SCRIPTTABSHEET_H
+#define __SCRIPTTABSHEET_H
+
+#include <api/wnd/wndclass/typesheet.h>
+#include <api/script/objcontroller.h>
+
+#define SCRIPTTABSHEET_PARENT TypeSheet
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+
+class ScriptTabSheet : public SCRIPTTABSHEET_PARENT {
+
+ public:
+
+ ScriptTabSheet();
+ virtual ~ScriptTabSheet();
+
+ // XuiObject automatically calls this back for all parameters registered using addParam
+ // encountered in the xml source
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setWindowType(const wchar_t *elementname);
+ void setChildrenIds(const wchar_t *paramvalue);
+ void setType(const wchar_t *element);
+ virtual int onInit();
+
+ void setContentMarginX(const wchar_t *value, int what);
+protected:
+ void CreateXMLParameters(int master_handle);
+ private:
+
+ // a list of IDs for our xml attributes, we use them in addParam() in the constructor
+ enum {
+ SCRIPTTABSHEET_SETWINDOWTYPE = 0,
+ SCRIPTTABSHEET_SETCHILDREN,
+ SCRIPTTABSHEET_SETTYPE,
+ SCRIPTTABSHEET_SETCONTENTMARGINLEFT,
+ SCRIPTTABSHEET_SETCONTENTMARGINTOP,
+ SCRIPTTABSHEET_SETCONTENTMARGINRIGHT,
+ SCRIPTTABSHEET_SETCONTENTMARGINBOTTOM,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+ PtrList<StringW> children_id;
+ void reloadChildren();
+ int type;
+ StringW wndtype;
+
+ int left_margin, right_margin, top_margin, bottom_margin;
+};
+
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+extern const wchar_t ScriptTabSheetXuiObjectStr[];
+extern char ScriptTabSheetXuiSvcName[];
+class ScriptTabSheetXuiSvc : public XuiObjectSvc<ScriptTabSheet, ScriptTabSheetXuiObjectStr, ScriptTabSheetXuiSvcName> {};
+
+// -----------------------------------------------------------------------------------------------------
+class ScriptTabSheetController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"TabSheet"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return tabsheetGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar tabsheet_getCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar tabsheet_setCurPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar a);
+ static scriptVar tabsheet_getNumPages(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar tabsheet_nextPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar tabsheet_previousPage(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern ScriptTabSheetController *tabsheetController;
+
+#endif
+
diff --git a/Src/Wasabi/api/skin/widgets/xuithemeslist.cpp b/Src/Wasabi/api/skin/widgets/xuithemeslist.cpp
new file mode 100644
index 00000000..c86c8142
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuithemeslist.cpp
@@ -0,0 +1,365 @@
+#include <precomp.h>
+#include "xuithemeslist.h"
+#include <api/wnd/popup.h>
+#include "../Agave/Language/api_language.h"
+#include "resource.h"
+
+#ifndef _WASABIRUNTIME
+
+BEGIN_SERVICES(ColorThemesList_Svc);
+DECLARE_SERVICE(XuiObjectCreator<ColorThemesListXuiSvc>);
+DECLARE_SERVICE(XuiObjectCreator<NakedColorThemesListXuiSvc>);
+DECLARE_SERVICE(ActionCreator<ThemesSlotActionSvc>);
+END_SERVICES(ColorThemesList_Svc, _ColorThemesList_Svc);
+
+#ifdef _X86_
+extern "C" { int _link_ColorThemesListXuiSvc; }
+#else
+extern "C" { int __link_ColorThemesListXuiSvc; }
+#endif
+
+#endif
+
+int ThemesSlotActionSvc::onActionId(int pvtid, const wchar_t *action, const wchar_t *param, int p1, int p2, void *data, int datalen, ifc_window *source) {
+ PopupMenu p_load;
+ for (int i=0;i<10;i++)
+ {
+ StringW s = ColorThemesList::getSlot(i), no_set = WASABI_API_LNGSTRINGW(IDS_NO_SET);
+ p_load.addCommand(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SLOT_X_X), i+1, s.isempty() ? no_set/*L"no set"*/ : s), 200+i, 0, s.isempty());
+ }
+ int r = p_load.popAtMouse();
+ if (r >= 200 && r < 210)
+ {
+ StringW set = ColorThemesList::getSlot(r-200);
+ if (!set.isempty())
+ WASABI_API_SKIN->colortheme_setColorSet(set);
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+const wchar_t ColorThemesListXuiObjectStr[] = L"ColorThemes:List"; // This is the xml tag
+char ColorThemesListXuiSvcName[] = "ColorThemes:List xui object";
+const wchar_t NakedColorThemesListXuiObjectStr[] = L"ColorThemes:Mgr"; // This is the xml tag
+char NakedColorThemesListXuiSvcName[] = "ColorThemes:Mgr xui object";
+
+XMLParamPair ColorThemesList::params[] = {
+ {CTLIST_NOHSCROLL, L"NOHSCROLL"},
+};
+
+// -----------------------------------------------------------------------
+ColorThemesList::ColorThemesList() {
+ setPreventMultipleSelection(1);
+ ensure_on_paint = -1;
+ setAutoSort(1);
+ nohscroll = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+}
+
+void ColorThemesList::CreateXMLParameters(int master_handle)
+{
+ //THEMESLIST_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ColorThemesList::~ColorThemesList() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+}
+
+// -----------------------------------------------------------------------
+NakedColorThemesList::NakedColorThemesList() {
+ xuihandle = newXuiHandle();
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+}
+
+// -----------------------------------------------------------------------
+NakedColorThemesList::~NakedColorThemesList() {
+ items.deleteAll();
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+}
+
+// -----------------------------------------------------------------------
+int ColorThemesList::onInit() {
+ THEMESLIST_PARENT::onInit();
+ addColumn(L"Theme",250);
+ //loadThemes();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int ColorThemesList::onResize() {
+ THEMESLIST_PARENT::onResize();
+ if (nohscroll) {
+ RECT r;
+ getClientRect(&r);
+ ListColumn *col = getColumn(0);
+ col->setWidth(r.right-r.left-4);
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::onDoubleClick(int itemnum) {
+ colorthemes_switch();
+}
+
+// -----------------------------------------------------------------------
+int ColorThemesList::onRightClick(int itemnum) {
+ THEMESLIST_PARENT::onRightClick(itemnum);
+ PopupMenu p_save;
+ PopupMenu p_load;
+ PopupMenu p;
+ StringW no_set = WASABI_API_LNGSTRINGW(IDS_NO_SET);
+
+ for (int i=0;i<10;i++)
+ {
+ StringW s = getSlot(i);
+ p_save.addCommand(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SLOT_X_X), i+1, s.isempty() ? no_set : s), 100+i);
+ }
+ for (int i=0;i<10;i++) {
+ StringW s = getSlot(i);
+ p_load.addCommand(StringPrintfW(WASABI_API_LNGSTRINGW(IDS_SLOT_X_X), i+1, s.isempty() ? no_set : s), 200+i, 0, s.isempty());
+ }
+
+ p.addSubMenu(&p_load, WASABI_API_LNGSTRINGW(IDS_XUITHEME_LOAD));
+ p.addSubMenu(&p_save, WASABI_API_LNGSTRINGW(IDS_XUITHEME_SAVE));
+
+ int r = p.popAtMouse();
+ if (r >= 100 && r < 110) {
+ int sel = getFirstItemSelected();
+ if (sel >= 0) {
+ wchar_t set[256+11]=L"";
+ getItemLabel(sel, 0, set, 255); set[255] = 0;
+ int p = (getItemData(sel) & 0xFFFF0000) >> 16;
+ if (p)
+ WCSCPYN(set, StringPrintfW(L"{coloredit}%s", set), 255+11);
+ setSlot(r-100, set);
+ }
+ }
+ else if (r >= 200 && r < 210) {
+ StringW set = getSlot(r-200);
+ if (!set.isempty())
+ WASABI_API_SKIN->colortheme_setColorSet(set);
+ }
+ return 1;
+}
+
+void ColorThemesList::setSlot(int i, const wchar_t *set) {
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"%s/slot%d", WASABI_API_SKIN->getSkinName(), i+1), set);
+}
+
+const wchar_t *ColorThemesList::getSlot(int i) {
+ static wchar_t set[256]=L"";
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"%s/slot%d", WASABI_API_SKIN->getSkinName(), i+1), set, 256, L"");
+ return set;
+}
+
+// -----------------------------------------------------------------------
+int ColorThemesList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (!_wcsicmp(action, L"colorthemes_switch")) { colorthemes_switch(); return 1; }
+ if (!_wcsicmp(action, L"colorthemes_next")) { colorthemes_next(); return 1; }
+ if (!_wcsicmp(action, L"colorthemes_previous")) { colorthemes_previous(); return 1; }
+ return THEMESLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
+// -----------------------------------------------------------------------
+int NakedColorThemesList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (!_wcsicmp(action, L"colorthemes_next")) { colorthemes_next(); return 1; }
+ if (!_wcsicmp(action, L"colorthemes_previous")) { colorthemes_previous(); return 1; }
+ return THEMESLIST2_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::colorthemes_switch() {
+ int sel = getFirstItemSelected();
+ if (sel >= 0) {
+ wchar_t set[256+11]=L"";
+ getItemLabel(sel, 0, set, 255); set[255] = 0;
+ int p = (getItemData(sel) & 0xFFFF0000) >> 16;
+ if (p)
+ WCSCPYN(set, StringPrintfW(L"{coloredit}%s", set), 255+11);
+ WASABI_API_SKIN->colortheme_setColorSet(set);
+ }
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::colorthemes_advance(int n)
+{
+ StringW curs = WASABI_API_SKIN->colortheme_getColorSet();
+ curs.trunc(255);
+ wchar_t txt[256+11] = {0};
+ int i;
+ for (i=0;i<getNumItems();i++)
+ {
+ getItemLabel(i, 0, txt, 255);
+ int p = (getItemData(i) & 0xFFFF0000) >> 16;
+ txt[256] = 0;
+ if (p)
+ WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11);
+ if (!_wcsicmp(txt, curs))
+ break;
+ }
+ if (i >= WASABI_API_SKIN->colortheme_getNumColorSets()) return;
+ i += n;
+ if (i < 0) i = WASABI_API_SKIN->colortheme_getNumColorSets()-1;
+ i %= WASABI_API_SKIN->colortheme_getNumColorSets();
+ getItemLabel(i, 0, txt, 255); txt[255] = 0;
+ int p = (getItemData(i) & 0xFFFF0000) >> 16;
+ if (p)
+ WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11);
+ ensure_on_paint = i;
+ WASABI_API_SKIN->colortheme_setColorSet(txt);
+ invalidate();
+}
+
+// -----------------------------------------------------------------------
+int ColorThemesList::getTextBold(LPARAM lParam) {
+ if (WCSCASEEQLSAFE(WASABI_API_SKIN->colortheme_enumColorSet(lParam & 0xFFFF), WASABI_API_SKIN->colortheme_getColorSet())) return 1;
+ return THEMESLIST_PARENT::getTextBold(lParam);
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::colorthemes_next() {
+ colorthemes_advance(1);
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::colorthemes_previous() {
+ colorthemes_advance(-1);
+}
+
+// -----------------------------------------------------------------------
+void NakedColorThemesList::colorthemes_advance(int n) {
+ StringW curs = WASABI_API_SKIN->colortheme_getColorSet();
+ curs.trunc(255);
+ wchar_t txt[256+11] = {0};
+ int i;
+ for (i=0;i<items.getNumItems();i++)
+ {
+ WCSCPYN(txt, items.enumItem(i)->getName(), 256);
+ int p = (items.enumItem(i)->getData() & 0xFFFF0000) >> 16;
+ txt[256] = 0;
+ if (p)
+ {
+ WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11);
+ }
+ if (!_wcsicmp(txt, curs))
+ break;
+ }
+ if (i >= WASABI_API_SKIN->colortheme_getNumColorSets()) return;
+ i += n;
+ if (i < 0) i = WASABI_API_SKIN->colortheme_getNumColorSets()-1;
+ i %= WASABI_API_SKIN->colortheme_getNumColorSets();
+ WCSCPYN(txt, items.enumItem(i)->getName(), 256);
+ int p = (items.enumItem(i)->getData() & 0xFFFF0000) >> 16;
+ if (p)
+ {
+ WCSCPYN(txt, StringPrintfW(L"{coloredit}%s", txt), 255+11);
+ }
+ WASABI_API_SKIN->colortheme_setColorSet(txt);
+}
+
+// -----------------------------------------------------------------------
+void NakedColorThemesList::colorthemes_next() {
+ colorthemes_advance(1);
+}
+
+// -----------------------------------------------------------------------
+void NakedColorThemesList::colorthemes_previous() {
+ colorthemes_advance(-1);
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::onSetVisible(int show) {
+ THEMESLIST_PARENT::onSetVisible(show);
+ if (show) loadThemes();
+ else getDesktopParent()->setFocus();
+}
+
+// -----------------------------------------------------------------------
+void NakedColorThemesList::onSetVisible(int show) {
+ THEMESLIST2_PARENT::onSetVisible(show);
+ if (show) loadThemes();
+}
+
+// -----------------------------------------------------------------------
+void ColorThemesList::loadThemes()
+{
+ setAutoSort(0);
+ deleteAllItems();
+ const wchar_t *curset = WASABI_API_SKIN->colortheme_getColorSet();
+ for (int i=0;i<WASABI_API_SKIN->colortheme_getNumColorSets();i++) {
+ const wchar_t *set = WASABI_API_SKIN->colortheme_enumColorSet(i);
+ int p = 0;
+ if (!_wcsnicmp(set, L"{coloredit}", 11)) {
+ set += 11;
+ p = 1 << 16;
+ }
+ addItem(set, p | i);
+ }
+
+ setAutoSort(1);
+ resort();
+
+ if (curset != NULL) {
+ wchar_t set[256+11]=L"";
+ for (int i=0;i<WASABI_API_SKIN->colortheme_getNumColorSets();i++)
+ {
+ getItemLabel(i, 0, set, 255); set[255]=0;
+ int p = (getItemData(i) & 0xFFFF0000) >> 16;
+ if (p)
+ WCSCPYN(set, StringPrintfW(L"{coloredit}%s", set), 255+11);
+ if (set && !_wcsicmp(curset,set))
+ {
+ setSelected(i, 1);
+ ensureItemVisible(i);
+ return;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void NakedColorThemesList::loadThemes()
+{
+ items.setAutoSort(0);
+ items.deleteAll();
+ //CUT: const wchar_t *curset = WASABI_API_SKIN->colortheme_getColorSet();
+ for (int i=0;i<WASABI_API_SKIN->colortheme_getNumColorSets();i++)
+ {
+ const wchar_t *set = WASABI_API_SKIN->colortheme_enumColorSet(i);
+ int p = 0;
+ if (!_wcsnicmp(set, L"{coloredit}", 11))
+ {
+ set += 11;
+ p = 1 << 16;
+ }
+ NakedItem *n = new NakedItem(set, p|i);
+ items.addItem(n);
+ }
+ items.setAutoSort(1);
+ items.sort(TRUE);
+}
+
+// -----------------------------------------------------------------------
+int ColorThemesList::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) {
+ if (xuihandle == _xuihandle) {
+ switch (xmlattrid) {
+ case CTLIST_NOHSCROLL: nohscroll = WTOI(value); return 1;
+ }
+ }
+ return THEMESLIST_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value);
+}
+
+int ColorThemesList::onPaint(Canvas *canvas) {
+ if (ensure_on_paint > -1) ensureItemVisible(ensure_on_paint);
+ ensure_on_paint = -1;
+ THEMESLIST_PARENT::onPaint(canvas);
+ return 1;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/widgets/xuithemeslist.h b/Src/Wasabi/api/skin/widgets/xuithemeslist.h
new file mode 100644
index 00000000..8c4a3df9
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuithemeslist.h
@@ -0,0 +1,128 @@
+#ifndef __THEMESLIST_H
+#define __THEMESLIST_H
+
+#include <api/wnd/wndclass/listwnd.h>
+#include <api/skin/nakedobject.h>
+#include <api/service/svcs/svc_action.h>
+
+class ThemesSlotActionSvc : public svc_actionI {
+public:
+ ThemesSlotActionSvc() {
+ registerAction(L"ThemesSlotsMenu", 0);
+ }
+ virtual ~ThemesSlotActionSvc() {}
+ virtual int onActionId(int pvtid, const wchar_t *action, const wchar_t *param=NULL, int p1=0, int p2=0, void *data=NULL, int datalen=0, ifc_window *source=NULL);
+ static const char *getServiceName() { return "ThemesSlotMenu Service"; }
+};
+
+#define THEMESLIST_PARENT ListWnd
+#define THEMESLIST2_PARENT NakedObject
+
+// -----------------------------------------------------------------------
+class ColorThemesList : public THEMESLIST_PARENT, public SkinCallbackI
+{
+
+ public:
+
+ ColorThemesList();
+ virtual ~ColorThemesList();
+
+ virtual int onInit();
+ virtual void onDoubleClick(int itemnum);
+ virtual int onPaint(Canvas *canvas);
+ virtual int onRightClick(int itemnum);
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+ virtual int onResize();
+ virtual int wantResizeCols() { return 0; }
+ virtual int setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value);
+ virtual int wantHScroll() { return !nohscroll; }
+
+ virtual int getTextBold(LPARAM lParam);
+ virtual void onSetVisible(int show);
+
+ virtual int skincb_onColorThemesListChanged() { loadThemes(); return 1;}
+
+ enum {
+ CTLIST_NOHSCROLL = 0,
+ };
+
+ static void setSlot(int s, const wchar_t *set);
+ static const wchar_t *getSlot(int s);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+ static XMLParamPair params[];
+ void colorthemes_switch();
+ void colorthemes_next();
+ void colorthemes_previous();
+ void colorthemes_advance(int i);
+ void loadThemes();
+ int xuihandle;
+ int nohscroll;
+ int ensure_on_paint;
+};
+
+// -----------------------------------------------------------------------
+class NakedItem
+{
+ public:
+ NakedItem(const wchar_t *_name, int _p) : name(_name), data(_p) {}
+ virtual ~NakedItem() {}
+ const wchar_t *getName() { return name; }
+ int getData() { return data; }
+ private:
+ StringW name;
+ int data;
+};
+
+// -----------------------------------------------------------------------
+class NakedItemSort {
+public:
+ // comparator for sorting
+ static int compareItem(NakedItem *p1, NakedItem *p2) {
+ return _wcsicmp(p1->getName(), p2->getName());
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, NakedItem *item) {
+ return _wcsicmp(attrib, item->getName());
+ }
+};
+
+
+// -----------------------------------------------------------------------
+class NakedColorThemesList : public THEMESLIST2_PARENT, public SkinCallbackI
+{
+
+ public:
+
+ NakedColorThemesList();
+ virtual ~NakedColorThemesList();
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ virtual void onSetVisible(int show);
+
+ virtual int skincb_onColorThemesListChanged() { loadThemes(); return 1;}
+
+ private:
+
+ PtrListQuickSorted<NakedItem, NakedItemSort> items;
+ void colorthemes_switch();
+ void colorthemes_next();
+ void colorthemes_previous();
+ void colorthemes_advance(int i);
+ void loadThemes();
+ int xuihandle;
+};
+
+
+// -----------------------------------------------------------------------
+extern const wchar_t ColorThemesListXuiObjectStr[];
+extern char ColorThemesListXuiSvcName[];
+class ColorThemesListXuiSvc : public XuiObjectSvc<ColorThemesList, ColorThemesListXuiObjectStr, ColorThemesListXuiSvcName> {};
+extern const wchar_t NakedColorThemesListXuiObjectStr[];
+extern char NakedColorThemesListXuiSvcName[];
+class NakedColorThemesListXuiSvc : public XuiObjectSvc<NakedColorThemesList, NakedColorThemesListXuiObjectStr, NakedColorThemesListXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuititlebox.cpp b/Src/Wasabi/api/skin/widgets/xuititlebox.cpp
new file mode 100644
index 00000000..ba0d8e5a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuititlebox.cpp
@@ -0,0 +1,59 @@
+#include <precomp.h>
+#include "xuititlebox.h"
+
+// -----------------------------------------------------------------------
+const wchar_t ScriptTitleBoxXuiObjectStr[] = L"Wasabi:TitleBox"; // This is the xml tag
+char ScriptTitleBoxXuiSvcName[] = "Wasabi:TitleBox xui object";
+
+XMLParamPair ScriptTitleBox::params[] = {
+ {SCRIPTTITLEBOX_CENTERED, L"CENTERED"},
+ {SCRIPTTITLEBOX_CONTENT, L"CONTENT"},
+ {SCRIPTTITLEBOX_SUFFIX, L"SUFFIX"},
+ {SCRIPTTITLEBOX_TITLE, L"TITLE"},
+ };
+// -----------------------------------------------------------------------
+ScriptTitleBox::ScriptTitleBox() : SCRIPTTITLEBOX_PARENT()
+{
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+}
+
+void ScriptTitleBox::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTTITLEBOX_PARENT::CreateXMLParameters(master_handle);
+int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ScriptTitleBox::~ScriptTitleBox()
+{}
+
+// -----------------------------------------------------------------------
+int ScriptTitleBox::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return SCRIPTTITLEBOX_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ // Parcel the values out to the window object we multiply inherit from
+ switch (xmlattributeid)
+ {
+ case SCRIPTTITLEBOX_TITLE:
+ setTitle(value);
+ break;
+ case SCRIPTTITLEBOX_CONTENT:
+ setChildGroup(value);
+ break;
+ case SCRIPTTITLEBOX_CENTERED:
+ setCentered(WTOI(value));
+ break;
+ case SCRIPTTITLEBOX_SUFFIX:
+ setSuffix(value);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuititlebox.h b/Src/Wasabi/api/skin/widgets/xuititlebox.h
new file mode 100644
index 00000000..804e25ab
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuititlebox.h
@@ -0,0 +1,44 @@
+#ifndef __SCRIPTTITLEBOX_H
+#define __SCRIPTTITLEBOX_H
+
+#include <api/skin/widgets/titlebox.h>
+#include <api/script/objects/c_script/h_guiobject.h>
+#include <api/wnd/accessible.h>
+
+#define SCRIPTTITLEBOX_PARENT TitleBox
+
+// -----------------------------------------------------------------------
+// Your wnd object class
+class ScriptTitleBox : public SCRIPTTITLEBOX_PARENT {
+
+ public:
+
+ ScriptTitleBox();
+ virtual ~ScriptTitleBox();
+
+ // XuiObject automatically calls this back for all parameters registered using addParam
+ // encountered in the xml source
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ // a list of IDs for our xml attributes, we use them in addParam() in the constructor
+ enum {
+ SCRIPTTITLEBOX_TITLE= 0,
+ SCRIPTTITLEBOX_CONTENT,
+ SCRIPTTITLEBOX_CENTERED,
+ SCRIPTTITLEBOX_SUFFIX,
+ };
+ int myxuihandle;
+ static XMLParamPair params[];
+};
+
+// -----------------------------------------------------------------------
+// This defines the svc_xuiObject that exposes your wnd object
+
+extern const wchar_t ScriptTitleBoxXuiObjectStr[];
+extern char ScriptTitleBoxXuiSvcName[];
+class ScriptTitleBoxXuiSvc : public XuiObjectSvc<ScriptTitleBox, ScriptTitleBoxXuiObjectStr, ScriptTitleBoxXuiSvcName> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuitree.cpp b/Src/Wasabi/api/skin/widgets/xuitree.cpp
new file mode 100644
index 00000000..66483656
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuitree.cpp
@@ -0,0 +1,2644 @@
+#include <precomp.h>
+#include "xuitree.h"
+
+#include <api/service/svc_enum.h>
+#include <bfc/parse/hierarchyparser.h>
+#include <api/script/scriptguid.h>
+#include <api/skin/feeds/TextFeedEnum.h>
+
+// The temporary memory buffer to hold our string returns.
+StringW GuiTreeScriptController::staticStr;
+
+class ScriptTreeItem;
+
+// -----------------------------------------------------------------------
+// class TreeItemScript -- This is the tree item type inserted into
+// the tree if a script or XML piece is inserting items into the tree.
+class TreeItemScript : public TreeItem
+{
+public:
+ TreeItemScript(const wchar_t *label = NULL, ScriptTreeItem *_scriptitem = NULL) : scriptitem(_scriptitem), TreeItem(label)
+ {}
+ virtual ~TreeItemScript()
+ {}
+ virtual void onTreeAdd()
+ {
+ if (scriptitem) TreeItemScriptController::treeitem_onTreeAdd(SCRIPT_CALL, scriptitem->getScriptObject());
+ }
+ virtual void onTreeRemove()
+ {
+ if (scriptitem) TreeItemScriptController::treeitem_onTreeRemove(SCRIPT_CALL, scriptitem->getScriptObject());
+ }
+ virtual void onSelect()
+ {
+ if (scriptitem) TreeItemScriptController::treeitem_onSelect(SCRIPT_CALL, scriptitem->getScriptObject());
+ }
+ virtual void onDeselect()
+ {
+ if (scriptitem) TreeItemScriptController::treeitem_onDeselect(SCRIPT_CALL, scriptitem->getScriptObject());
+ }
+ virtual int onLeftDoubleClick()
+ {
+ scriptVar retval;
+ if (scriptitem)
+ retval = TreeItemScriptController::treeitem_onLeftDoubleClick(SCRIPT_CALL, scriptitem->getScriptObject());
+ if ((retval.type == SCRIPT_VOID)
+ || (retval.type == SCRIPT_OBJECT)
+ || (retval.type == SCRIPT_STRING))
+ return 0;
+ return GET_SCRIPT_INT(retval);
+ }
+ virtual int onRightDoubleClick()
+ {
+ scriptVar retval;
+ if (scriptitem) retval = TreeItemScriptController::treeitem_onRightDoubleClick(SCRIPT_CALL, scriptitem->getScriptObject());
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) return 0;
+ return GET_SCRIPT_INT(retval);
+ }
+ // return 1 if you eat the key
+ virtual int onChar(UINT key)
+ {
+ scriptVar retval;
+ if (scriptitem) retval = TreeItemScriptController::treeitem_onChar(SCRIPT_CALL, scriptitem->getScriptObject(), MAKE_SCRIPT_INT(key));
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING)) return 0;
+ return GET_SCRIPT_INT(retval);
+ }
+ // these are called after the expand/collapse happens
+ virtual void onExpand()
+ {
+ if (scriptitem) TreeItemScriptController::treeitem_onExpand(SCRIPT_CALL, scriptitem->getScriptObject());
+ }
+ virtual void onCollapse()
+ {
+ if (scriptitem) TreeItemScriptController::treeitem_onCollapse(SCRIPT_CALL, scriptitem->getScriptObject());
+ }
+ virtual int onBeginLabelEdit()
+ {
+ scriptVar retval;
+ if (scriptitem) retval = TreeItemScriptController::treeitem_onBeginLabelEdit(SCRIPT_CALL, scriptitem->getScriptObject());
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = TreeItem::onBeginLabelEdit();
+ }
+ return retv;
+ }
+ virtual int onEndLabelEdit(const wchar_t *newlabel)
+ {
+ scriptVar retval;
+ if (scriptitem)
+ retval = TreeItemScriptController::treeitem_onEndLabelEdit(SCRIPT_CALL, scriptitem->getScriptObject(), MAKE_SCRIPT_STRING(newlabel));
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = TreeItem::onEndLabelEdit(newlabel);
+ }
+ return retv;
+ }
+ virtual int onContextMenu(int x, int y)
+ {
+ scriptVar retval;
+ if (scriptitem) retval = TreeItemScriptController::treeitem_onContextMenu(SCRIPT_CALL, scriptitem->getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = TreeItem::onContextMenu(x, y);
+ }
+ return retv;
+ }
+protected:
+ ScriptTreeItem *scriptitem;
+};
+
+
+// -----------------------------------------------------------------------
+const wchar_t ScriptTreeXuiObjectStr[] = L"Tree"; // This is the xml tag
+char ScriptTreeXuiSvcName[] = "Tree xui object";
+
+
+XMLParamPair ScriptTree::params[] = {
+ {SCRIPTTREE_CHILDTABS, L"CHILDTABS"},
+ {SCRIPTTREE_EXPANDROOT, L"EXPANDROOT"},
+ {SCRIPTTREE_FEED, L"FEED"},
+ {SCRIPTTREE_SETITEMS, L"ITEMS"},
+ {SCRIPTTREE_SORTED, L"SORTED"},
+ };
+// -----------------------------------------------------------------------
+ScriptTree::ScriptTree()
+{
+ getScriptObject()->vcpu_setInterface(guitreeGuid, (void *)static_cast<ScriptTree *>(this));
+ getScriptObject()->vcpu_setClassName(L"GuiTree"); // this is the script class name
+ getScriptObject()->vcpu_setController(guiTreeController);
+
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ feed = NULL;
+ childtabs = 1;
+ expandroot = 1;
+}
+
+void ScriptTree::CreateXMLParameters(int master_handle)
+{
+ //SCRIPTTREE_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+// -----------------------------------------------------------------------
+ScriptTree::~ScriptTree()
+{
+ closeFeed();
+
+ // Clean up the ScriptTreeItems owned by this guy.
+ TreeItem *item = enumRootItem(0);
+ while (item != NULL)
+ {
+ // Delete this item.
+ ScriptTreeItem *dead = NULL;
+ //if (TISC::g_scriptitems.getItem(item, &dead) && (dead != NULL))
+ //{ // true if it found something.
+ // TISC::g_scriptitems.delItem(item);
+ // delete dead;
+ // // DebugString(" === deleting tree item (%08X, %08X, %08X)\n", item, dead, this);
+ // continue;
+ //}
+ auto it = TISC::g_scriptitems.find(item);
+ if (TISC::g_scriptitems.end() != it)
+ {
+ dead = it->second;
+ delete dead;
+ TISC::g_scriptitems.erase(it);
+ continue;
+ }
+ else
+ {
+ // DebugString(" !!! ORPHAN TREE ITEM (%08X, %08X, %08X)\n", item, 0, this);
+ }
+
+ // Figure out who the next item to process should be.
+
+ // 1) Children first.
+ TreeItem *child = item->getChild();
+ if (child != NULL)
+ {
+ item = child;
+ }
+ else
+ {
+ // 2) Siblings next.
+ TreeItem *sibling = item->getSibling();
+ if (sibling != NULL)
+ {
+ item = sibling;
+ }
+ else
+ {
+ // 3) Zip up parent chain last.
+ TreeItem *item_parent, *parent_sibling;
+ item_parent = item->getParent();
+ item = NULL; // at this point if we do not assign, we are NULL.
+ while (item_parent != NULL)
+ {
+ parent_sibling = item_parent->getSibling();
+ if (parent_sibling != NULL)
+ {
+ item = parent_sibling;
+ break;
+ }
+ item_parent = item_parent->getParent();
+ }
+ // 4) Uhhh.... you're null. All done. Go home.
+ }
+ }
+ }
+
+ /*
+
+ // delete all of our script items from g_scriptitems
+ int i = 0;
+ TreeItem *next = enumRootItem(0);
+ while (next) { // go through all of our items
+ ScriptTreeItem *dead = NULL;
+ if (TISC::g_scriptitems.getItem(next, &dead) && (dead != NULL)) { // true if it found something.
+ TISC::g_scriptitems.delItem(next);
+ delete dead;
+ // DebugString(" === deleting tree item (%08X, %08X)\n", next, dead);
+ } else {
+ // DebugString(" !!! ORPHAN TREE ITEM (%08X, %08X)\n", next, i);
+ }
+ TreeItem *next = enumAllItems(i++);
+ }
+
+ */
+ // some items will wind up leaked into g_scriptitems, most likely.
+}
+
+// -----------------------------------------------------------------------
+int ScriptTree::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (xuihandle != myxuihandle)
+ return SCRIPTTREE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case SCRIPTTREE_SETITEMS:
+ items = value;
+ fillFromParams();
+#ifdef WASABI_COMPILE_CONFIG
+ if (getGuiObject()->guiobject_hasCfgAttrib())
+ selectFromConfig();
+#endif
+ break;
+ case SCRIPTTREE_FEED:
+ {
+ closeFeed();
+ openFeed(value);
+ break;
+ }
+ case SCRIPTTREE_SORTED:
+ {
+ setSorted(WTOB(value));
+ break;
+ }
+ case SCRIPTTREE_CHILDTABS:
+ {
+ childtabs = WTOI(value);
+ break;
+ }
+ case SCRIPTTREE_EXPANDROOT:
+ {
+ expandRoot(WTOI(value));
+ break;
+ }
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int ScriptTree::onInit()
+{
+ SCRIPTTREE_PARENT::onInit();
+
+ fillFromParams();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int ScriptTree::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ SCRIPTTREE_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ if (!WCSICMP(action, L"get_selection"))
+ {
+ if (source != NULL)
+ {
+ StringW res(L"");
+
+ // Hmmmmm..... multiselection trees?
+
+ sendAction(source, L"set_selection", res);
+ }
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+ScriptTreeItem *ScriptTree::bindScriptTreeItem(TreeItem *item)
+{
+ ASSERT(item != NULL);
+ // find this tree item in our map of tree items.
+ ScriptTreeItem *si = NULL;
+ //TISC::g_scriptitems.getItem(item, &si);
+ auto it = TISC::g_scriptitems.find(item);
+ if (TISC::g_scriptitems.end() == it)
+ {
+ // if there was no scriptobject in our map already, make one
+ // for this tree item and place it in our map.
+ si = new ScriptTreeItem(item, this);
+ TISC::g_scriptitems.insert({ item, si });
+ }
+ else
+ {
+ si = it->second;
+ }
+ return si;
+}
+
+// -----------------------------------------------------------------------
+int ScriptTree::destroyScriptTreeItem(ScriptTreeItem *item)
+{
+ ASSERT(item != NULL);
+ // find this tree item in our map of tree items.
+ TreeItem *ti = item->getItem();
+ if (ti)
+ {
+ ScriptTreeItem *check = NULL;
+ //TISC::g_scriptitems.getItem(ti, &check); // this is a doublecheck on who owns who.
+ auto it = TISC::g_scriptitems.find(ti);
+
+ if (TISC::g_scriptitems.end() != it)
+ {
+ // remove the treeitem from the tree
+ this->removeTreeItem(ti); // (removes without deleting)
+ // remove the scripttreeitem from the map
+ TISC::g_scriptitems.erase(it);
+ // and delete.(phew! bomb disposal!)
+ delete ti;
+ delete item;
+ return 1; // yes, we deleted it.
+ }
+ }
+ return 0; // Not ours, don't wanna delete it. Someone else can Deal With It.
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::onSetVisible(int i)
+{
+ SCRIPTTREE_PARENT::onSetVisible(i);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+// -----------------------------------------------------------------------
+int ScriptTree::onReloadConfig()
+{
+ SCRIPTTREE_PARENT::onReloadConfig();
+ selectFromConfig();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::saveToConfig()
+{}
+
+// -----------------------------------------------------------------------
+void ScriptTree::selectFromConfig()
+{}
+#endif
+
+// -----------------------------------------------------------------------
+int ScriptTree::selectEntry(const wchar_t *e, int cb)
+{
+ return -1;
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::expandRoot(int val)
+{
+ if (val)
+ {
+ expandroot = 1;
+ int count;
+ TreeItem *rootitem;
+ for (count = 0, rootitem = enumRootItem(count); rootitem; rootitem = enumRootItem(++count))
+ {
+ rootitem->expand();
+ }
+ }
+ else
+ {
+ expandroot = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::fillFromHPNode(HPNode *node, TreeItem *parent)
+{
+ // Go through the given node's children and add items for them
+ // to the corresponding parent item.
+ int i, n = node->getNumChildren();
+ for (i = 0; i < n; i++)
+ {
+ // Here's a child node
+ HPNode *child_node = static_cast<HPNode *>(node->enumChild(i));
+ // Make a script-aware tree item and script item to correspond to it, labelled with the child_node's name
+ ScriptTreeItem *si = new ScriptTreeItem;
+ TreeItem *child_item = new TreeItemScript((*child_node)(), si);
+ si->setItem(child_item);
+ si->setScriptTree(this);
+ // Add the script and tree items to the scriptitems map
+ TISC::g_scriptitems.insert({ child_item, si });
+ // DebugString(StringPrintf(" === NEW NODE ITEM (%08X, %08X, %08X)\n", child_item, si, this);
+ // Add the child item to either ourselves or the given parent.
+ addTreeItem(child_item, parent, getSorted(), childtabs);
+ // And then continue to fill from that node.
+ fillFromHPNode(child_node, child_item);
+ }
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::fillFromParams()
+{
+ deleteAllItems();
+ if (!items.isempty())
+ {
+ HierarchyParser hierarchy(items);
+ fillFromHPNode(hierarchy.rootNode());
+ }
+ // If we want our roots opened, do so now.
+ expandRoot(expandroot);
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::selectEntries(const wchar_t *entries, int cb)
+{}
+
+// -----------------------------------------------------------------------
+void ScriptTree::openFeed(const wchar_t *feedid)
+{
+ if (!_wcsicmp(feedid, last_feed)) return ;
+ feed = TextFeedEnum(feedid).getFirst();
+ if (feed != NULL)
+ {
+ viewer_addViewItem(feed->getDependencyPtr());
+ setXuiParam(myxuihandle, SCRIPTTREE_SETITEMS, L"items", feed->getFeedText(feedid));
+ }
+ last_feed = feedid;
+}
+
+// -----------------------------------------------------------------------
+void ScriptTree::closeFeed()
+{
+ if (feed)
+ {
+ viewer_delViewItem(feed->getDependencyPtr());
+ SvcEnum::release(feed);
+ }
+ feed = NULL;
+ last_feed = L"";
+}
+
+// -----------------------------------------------------------------------
+int ScriptTree::viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (feed == dynamic_guid_cast<svc_textFeed>(item, classguid))
+ {
+ if (event == svc_textFeed::Event_TEXTCHANGE)
+ {
+ setXuiParam(myxuihandle, SCRIPTTREE_SETITEMS, L"items", (const wchar_t *)ptr);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+// Callback methods that send hooks into the Script system
+
+int ScriptTree::onLeftButtonDown(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onLeftButtonDown(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onLeftButtonDown(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::onLeftButtonUp(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onLeftButtonUp(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onLeftButtonUp(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::onRightButtonUp(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onRightButtonUp(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onRightButtonUp(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::onMouseMove(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onMouseMove(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onMouseMove(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::wantAutoContextMenu()
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_wantAutoContextMenu(SCRIPT_CALL, getScriptObject() );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::wantAutoContextMenu();
+ }
+ return retv;
+}
+
+int ScriptTree::onLeftButtonDblClk(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onLeftButtonDblClk(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onLeftButtonDblClk(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::onRightButtonDblClk(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onRightButtonDblClk(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onRightButtonDblClk(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::onMouseWheelUp(int clicked, int lines)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onMouseWheelUp(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(clicked), MAKE_SCRIPT_INT(lines) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onMouseWheelUp(clicked, lines);
+ }
+ return retv;
+}
+
+int ScriptTree::onMouseWheelDown(int clicked, int lines)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onMouseWheelDown(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(clicked), MAKE_SCRIPT_INT(lines) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onMouseWheelDown(clicked, lines);
+ }
+ return retv;
+}
+
+int ScriptTree::onContextMenu(int x, int y)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onContextMenu(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(x), MAKE_SCRIPT_INT(y) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onContextMenu(x, y);
+ }
+ return retv;
+}
+
+int ScriptTree::onChar(wchar_t c)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onChar(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(c));
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onChar(c);
+ }
+ return retv;
+}
+
+int ScriptTree::onKeyDown(int keycode)
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onKeyDown(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(keycode) );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onKeyDown(keycode);
+ }
+ return retv;
+}
+
+void ScriptTree::onItemRecvDrop(TreeItem *item)
+{
+ ScriptTreeItem *sti_item = bindScriptTreeItem(item);
+ GuiTreeScriptController::guitree_onItemRecvDrop(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) );
+}
+
+void ScriptTree::onLabelChange(TreeItem *item)
+{
+ ScriptTreeItem *sti_item = bindScriptTreeItem(item);
+ GuiTreeScriptController::guitree_onLabelChange(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) );
+}
+
+void ScriptTree::onItemSelected(TreeItem *item)
+{
+ ScriptTreeItem *sti_item = bindScriptTreeItem(item);
+ GuiTreeScriptController::guitree_onItemSelected(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) );
+}
+
+void ScriptTree::onItemDeselected(TreeItem *item)
+{
+ ScriptTreeItem *sti_item = bindScriptTreeItem(item);
+ GuiTreeScriptController::guitree_onItemDeselected(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(sti_item->getScriptObject()) );
+}
+
+int ScriptTree::onKillFocus()
+{
+ scriptVar retval;
+ retval = GuiTreeScriptController::guitree_onKillFocus(SCRIPT_CALL, getScriptObject() );
+ int retv = 0;
+ if ((retval.type == SCRIPT_VOID) || (retval.type == SCRIPT_OBJECT) || (retval.type == SCRIPT_STRING))
+ {
+ retv = -1;
+ }
+ if (!retv)
+ {
+ retv = GET_SCRIPT_INT(retval);
+ }
+ if (retv < 1)
+ {
+ retv = SCRIPTTREE_PARENT::onKillFocus();
+ }
+ return retv;
+}
+
+
+
+
+
+// -----------------------------------------------------------------------
+// Script Object
+
+GuiTreeScriptController _guiTreeController;
+GuiTreeScriptController *guiTreeController = &_guiTreeController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct GuiTreeScriptController::exportedFunction[] = {
+ {L"getNumRootItems", 0, (void*)GuiTreeScriptController::guitree_getNumRootItems },
+ {L"enumRootItem", 1, (void*)GuiTreeScriptController::guitree_enumRootItem },
+
+ {L"onLeftButtonDown", 2, (void*)GuiTreeScriptController::guitree_onLeftButtonDown }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onLeftButtonUp", 2, (void*)GuiTreeScriptController::guitree_onLeftButtonUp }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onRightButtonUp", 2, (void*)GuiTreeScriptController::guitree_onRightButtonUp }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onMouseMove", 2, (void*)GuiTreeScriptController::guitree_onMouseMove }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onWantAutoContextMenu", 0, (void*)GuiTreeScriptController::guitree_wantAutoContextMenu }, // );
+ {L"onLeftButtonDblClk", 2, (void*)GuiTreeScriptController::guitree_onLeftButtonDblClk }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onRightButtonDblClk", 2, (void*)GuiTreeScriptController::guitree_onRightButtonDblClk }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onMouseWheelUp", 2, (void*)GuiTreeScriptController::guitree_onMouseWheelUp }, // , /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines);
+ {L"onMouseWheelDown", 2, (void*)GuiTreeScriptController::guitree_onMouseWheelDown }, // , /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines);
+ {L"onContextMenu", 2, (void*)GuiTreeScriptController::guitree_onContextMenu }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"onChar", 1, (void*)GuiTreeScriptController::guitree_onChar }, // , /*Int*/ scriptVar c);
+ {L"onKeyDown", 1, (void*)GuiTreeScriptController::guitree_onKeyDown }, // , /*Int*/ scriptVar keycode);
+ {L"onItemRecvDrop", 1, (void*)GuiTreeScriptController::guitree_onItemRecvDrop }, // , /*TreeItem*/ scriptVar item);
+ {L"onLabelChange", 1, (void*)GuiTreeScriptController::guitree_onLabelChange }, // , /*TreeItem*/ scriptVar item);
+ {L"onItemSelected", 1, (void*)GuiTreeScriptController::guitree_onItemSelected }, // , /*TreeItem*/ scriptVar item);
+ {L"onItemDeselected", 1, (void*)GuiTreeScriptController::guitree_onItemDeselected }, // , /*TreeItem*/ scriptVar item);
+ {L"onKillFocus", 0, (void*)GuiTreeScriptController::guitree_onKillFocus }, // );
+ {L"jumpToNext", 1, (void*)GuiTreeScriptController::guitree_jumpToNext }, // , /*Int*/ scriptVar c);
+ {L"ensureItemVisible", 1, (void*)GuiTreeScriptController::guitree_ensureItemVisible }, // , /*TreeItem*/ scriptVar item);
+ {L"getContentsWidth", 0, (void*)GuiTreeScriptController::guitree_getContentsWidth }, // );
+ {L"getContentsHeight", 0, (void*)GuiTreeScriptController::guitree_getContentsHeight }, // );
+ {L"addTreeItem", 4, (void*)GuiTreeScriptController::guitree_addTreeItem }, // , /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar par, /*Int*/ scriptVar sorted, /*Int*/ scriptVar haschildtab);
+ {L"removeTreeItem", 1, (void*)GuiTreeScriptController::guitree_removeTreeItem }, // , /*TreeItem*/ scriptVar item);
+ {L"moveTreeItem", 2, (void*)GuiTreeScriptController::guitree_moveTreeItem }, // , /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar newparent);
+ {L"deleteAllItems", 0, (void*)GuiTreeScriptController::guitree_deleteAllItems }, // );
+ {L"expandItem", 1, (void*)GuiTreeScriptController::guitree_expandItem }, // , /*TreeItem*/ scriptVar item);
+ {L"expandItemDeferred", 1, (void*)GuiTreeScriptController::guitree_expandItemDeferred }, // , /*TreeItem*/ scriptVar item);
+ {L"collapseItem", 1, (void*)GuiTreeScriptController::guitree_collapseItem }, // , /*TreeItem*/ scriptVar item);
+ {L"collapseItemDeferred", 1, (void*)GuiTreeScriptController::guitree_collapseItemDeferred }, // , /*TreeItem*/ scriptVar item);
+ {L"selectItem", 1, (void*)GuiTreeScriptController::guitree_selectItem }, // , /*TreeItem*/ scriptVar item);
+ {L"selectItemDeferred", 1, (void*)GuiTreeScriptController::guitree_selectItemDeferred }, // , /*TreeItem*/ scriptVar item);
+ {L"delItemDeferred", 1, (void*)GuiTreeScriptController::guitree_delItemDeferred }, // , /*TreeItem*/ scriptVar item);
+ {L"hiliteItem", 1, (void*)GuiTreeScriptController::guitree_hiliteItem }, // , /*TreeItem*/ scriptVar item);
+ {L"unhiliteItem", 1, (void*)GuiTreeScriptController::guitree_unhiliteItem }, // , /*TreeItem*/ scriptVar item);
+ {L"getCurItem", 0, (void*)GuiTreeScriptController::guitree_getCurItem }, // );
+ {L"hitTest", 2, (void*)GuiTreeScriptController::guitree_hitTest }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ {L"editItemLabel", 1, (void*)GuiTreeScriptController::guitree_editItemLabel }, // , /*TreeItem*/ scriptVar item);
+ {L"cancelEditLabel", 1, (void*)GuiTreeScriptController::guitree_cancelEditLabel }, // , /*Int*/ scriptVar destroyit);
+ {L"setAutoEdit", 1, (void*)GuiTreeScriptController::guitree_setAutoEdit }, // , /*Int*/ scriptVar ae);
+ {L"getAutoEdit", 0, (void*)GuiTreeScriptController::guitree_getAutoEdit }, // );
+ {L"getByLabel", 2, (void*)GuiTreeScriptController::guitree_getByLabel }, // , /*TreeItem*/ scriptVar item, /*String*/ scriptVar name);
+ {L"setSorted", 1, (void*)GuiTreeScriptController::guitree_setSorted }, // , /*Int*/ scriptVar dosort);
+ {L"getSorted", 0, (void*)GuiTreeScriptController::guitree_getSorted }, // );
+ {L"sortTreeItems", 0, (void*)GuiTreeScriptController::guitree_sortTreeItems }, // );
+ {L"getSibling", 1, (void*)GuiTreeScriptController::guitree_getSibling }, // , /*TreeItem*/ scriptVar item);
+ {L"setAutoCollapse", 1, (void*)GuiTreeScriptController::guitree_setAutoCollapse }, // , /*Int*/ scriptVar doautocollapse);
+ {L"setFontSize", 1, (void*)GuiTreeScriptController::guitree_setFontSize }, // , /*Int*/ scriptVar newsize);
+ {L"getFontSize", 0, (void*)GuiTreeScriptController::guitree_getFontSize }, // );
+ {L"getNumVisibleChildItems", 1, (void*)GuiTreeScriptController::guitree_getNumVisibleChildItems }, // , /*TreeItem*/ scriptVar c);
+ {L"getNumVisibleItems", 0, (void*)GuiTreeScriptController::guitree_getNumVisibleItems }, // );
+ {L"enumVisibleItems", 1, (void*)GuiTreeScriptController::guitree_enumVisibleItems }, // , /*Int*/ scriptVar n);
+ {L"enumVisibleChildItems", 2, (void*)GuiTreeScriptController::guitree_enumVisibleChildItems }, // , /*TreeItem*/ scriptVar c, /*Int*/ scriptVar n);
+ {L"enumAllItems", 1, (void*)GuiTreeScriptController::guitree_enumAllItems }, // , /*Int*/ scriptVar n);
+ {L"getItemRectX", 1, (void*)GuiTreeScriptController::guitree_getItemRectX }, // , /*TreeItem*/ scriptVar item);
+ {L"getItemRectY", 1, (void*)GuiTreeScriptController::guitree_getItemRectY }, // , /*TreeItem*/ scriptVar item);
+ {L"getItemRectW", 1, (void*)GuiTreeScriptController::guitree_getItemRectW }, // , /*TreeItem*/ scriptVar item);
+ {L"getItemRectH", 1, (void*)GuiTreeScriptController::guitree_getItemRectH }, // , /*TreeItem*/ scriptVar item);
+ // {L"getItemFromPoint", 2, (void*)GuiTreeScriptController::guitree_getItemFromPoint }, // , /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+
+ };
+
+ScriptObject *GuiTreeScriptController::instantiate()
+{
+ ScriptTree *sp = new ScriptTree;
+ ASSERT(sp != NULL);
+ return sp->getScriptObject();
+}
+
+void GuiTreeScriptController::destroy(ScriptObject *o)
+{
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ ASSERT(sp != NULL);
+ delete sp;
+}
+
+void *GuiTreeScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for guitrees yet
+}
+
+void GuiTreeScriptController::deencapsulate(void *o)
+{}
+
+int GuiTreeScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *GuiTreeScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+/*int*/ scriptVar GuiTreeScriptController::guitree_getNumRootItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree*>(o->vcpu_getInterface(guitreeGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->getNumRootItems();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumRootItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar which)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree*>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ int _which = GET_SCRIPT_INT(which);
+ a = sp->enumRootItem(_which);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onLeftButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onLeftButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onRightButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onMouseMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_wantAutoContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onLeftButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onRightButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onMouseWheelUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, clicked, lines);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, clicked, lines);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onMouseWheelDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, clicked, lines);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, clicked, lines);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, x, y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, x, y);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar c)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, c);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, c);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onKeyDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar keycode)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, keycode);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, keycode);
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_onItemRecvDrop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, item);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, item);
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_onLabelChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, item);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, item);
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_onItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, item);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, item);
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_onItemDeselected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, item);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, item);
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_onKillFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+// -------------------------------------------------------------------------
+/*Void*/ scriptVar GuiTreeScriptController::guitree_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _c = GET_SCRIPT_INT(c);
+ if (sp != NULL)
+ {
+ sp->jumpToNext(_c);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->ensureItemVisible(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getContentsWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->getContentsWidth();
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getContentsHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->getContentsHeight();
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_addTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar par, scriptVar sorted, scriptVar haschildtab)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_par = NULL;
+ ScriptObject *so_par = GET_SCRIPT_OBJECT(par);
+ if (so_par)
+ {
+ ScriptTreeItem *sti_par = static_cast<ScriptTreeItem *>(so_par->vcpu_getInterface(treeitemGuid));
+ if (sti_par)
+ {
+ _par = sti_par->getItem();
+ }
+ }
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ int _haschildtab = GET_SCRIPT_INT(haschildtab);
+ int _sorted = GET_SCRIPT_INT(sorted);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->addTreeItem(_item, _par, _sorted, _haschildtab);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_removeTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->removeTreeItem(_item);
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_moveTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar newparent)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_newparent = NULL;
+ ScriptObject *so_newparent = GET_SCRIPT_OBJECT(newparent);
+ if (so_newparent)
+ {
+ ScriptTreeItem *sti_newparent = static_cast<ScriptTreeItem *>(so_newparent->vcpu_getInterface(treeitemGuid));
+ if (sti_newparent)
+ {
+ _newparent = sti_newparent->getItem();
+ }
+ }
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->moveTreeItem(_item, _newparent);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ if (sp != NULL)
+ {
+ sp->deleteAllItems();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_expandItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->expandItem(_item);
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_expandItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->expandItemDeferred(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_collapseItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->collapseItem(_item);
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_collapseItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->collapseItemDeferred(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->selectItem(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_selectItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->selectItemDeferred(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_delItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->delItemDeferred(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_hiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->hiliteItem(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_unhiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->unhiliteItem(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getCurItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->getCurItem();
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_hitTest(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _y = GET_SCRIPT_INT(y);
+ int _x = GET_SCRIPT_INT(x);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->hitTest(_x, _y);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_editItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ if (sp != NULL)
+ {
+ sp->editItemLabel(_item);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_cancelEditLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar destroyit)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _destroyit = GET_SCRIPT_INT(destroyit);
+ if (sp != NULL)
+ {
+ sp->cancelEditLabel(_destroyit);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_setAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar ae)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _ae = GET_SCRIPT_INT(ae);
+ if (sp != NULL)
+ {
+ sp->setAutoEdit(_ae);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->getAutoEdit();
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getByLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, /*String*/ scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ StringW _name = GET_SCRIPT_STRING(name);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->getByLabel(_item, _name);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar dosort)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _dosort = GET_SCRIPT_INT(dosort);
+ if (sp != NULL)
+ {
+ sp->setSorted(!!_dosort);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ int a = NULL;
+ a = sp->getSorted();
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_sortTreeItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ if (sp != NULL)
+ {
+ sp->sortTreeItems();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->getSibling(_item);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*Void*/ scriptVar GuiTreeScriptController::guitree_setAutoCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar doautocollapse)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _doautocollapse = GET_SCRIPT_INT(doautocollapse);
+ if (sp != NULL)
+ {
+ sp->setAutoCollapse(!!_doautocollapse);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar newsize)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _newsize = GET_SCRIPT_INT(newsize);
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->setFontSize(_newsize);
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->getFontSize();
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getNumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_c = NULL;
+ ScriptObject *so_c = GET_SCRIPT_OBJECT(c);
+ if (so_c)
+ {
+ ScriptTreeItem *sti_c = static_cast<ScriptTreeItem *>(so_c->vcpu_getInterface(treeitemGuid));
+ if (sti_c)
+ {
+ _c = sti_c->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->getNumVisibleChildItems(_c);
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getNumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ a = sp->getNumVisibleItems();
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _n = GET_SCRIPT_INT(n);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->enumVisibleItems(_n);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar c, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_c = NULL;
+ ScriptObject *so_c = GET_SCRIPT_OBJECT(c);
+ if (so_c)
+ {
+ ScriptTreeItem *sti_c = static_cast<ScriptTreeItem *>(so_c->vcpu_getInterface(treeitemGuid));
+ if (sti_c)
+ {
+ _c = sti_c->getItem();
+ }
+ }
+ int _n = GET_SCRIPT_INT(n);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->enumVisibleChildItems(_c, _n);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_enumAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _n = GET_SCRIPT_INT(n);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ a = sp->enumAllItems(_n);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ RECT r;
+ sp->getItemRect(_item, &r);
+ a = r.left;
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ RECT r;
+ sp->getItemRect(_item, &r);
+ a = r.top;
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ RECT r;
+ sp->getItemRect(_item, &r);
+ a = r.left - r.right;
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+/*Int*/ scriptVar GuiTreeScriptController::guitree_getItemRectH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ TreeItem *_item = NULL;
+ ScriptObject *so_item = GET_SCRIPT_OBJECT(item);
+ if (so_item)
+ {
+ ScriptTreeItem *sti_item = static_cast<ScriptTreeItem *>(so_item->vcpu_getInterface(treeitemGuid));
+ if (sti_item)
+ {
+ _item = sti_item->getItem();
+ }
+ }
+ scriptVar retval = MAKE_SCRIPT_INT(0);
+ if (sp != NULL)
+ {
+ int a = 0;
+ RECT r;
+ sp->getItemRect(_item, &r);
+ a = r.bottom - r.top;
+ retval = MAKE_SCRIPT_INT(a);
+ }
+ return retval;
+}
+
+#if 0 // Not implemented in TreeWnd, dammit.
+/*TreeItem*/ scriptVar GuiTreeScriptController::guitree_getItemFromPoint(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTree *sp = static_cast<ScriptTree *>(o->vcpu_getInterface(guitreeGuid));
+ int _y = GET_SCRIPT_INT(y);
+ int _x = GET_SCRIPT_INT(x);
+ scriptVar retval = MAKE_SCRIPT_OBJECT(NULL);
+ if (sp != NULL)
+ {
+ TreeItem *a = NULL;
+ POINT p = {_x, _y};
+ a = sp->getItemFromPoint(&p);
+ if (a != NULL)
+ {
+ ScriptTreeItem *item = sp->bindScriptTreeItem(a);
+ if (item != NULL)
+ {
+ retval = MAKE_SCRIPT_OBJECT(item->getScriptObject());
+ }
+ }
+ }
+ return retval;
+}
+#endif
+
+// -----------------------------------------------------------------------
+// Script Object For The Tree Item
+
+ScriptTreeItem::ScriptTreeItem(TreeItem *_item, ScriptTree *_tree) : item(_item), tree(_tree), SCRIPTTREEITEM_SCRIPTPARENT()
+{
+ getScriptObject()->vcpu_setInterface(treeitemGuid, (void *)static_cast<ScriptTreeItem *>(this));
+ getScriptObject()->vcpu_setClassName(L"TreeItem");
+ getScriptObject()->vcpu_setController(treeItemController);
+}
+
+ScriptTreeItem::~ScriptTreeItem()
+{}
+
+int ScriptTreeItem::getNumChildren()
+{
+ ASSERT(item);
+ return item->getNumChildren();
+}
+
+void ScriptTreeItem::setLabel(const wchar_t *label)
+{
+ ASSERT(item);
+ item->setLabel(label);
+}
+
+const wchar_t *ScriptTreeItem::getLabel()
+{
+ ASSERT(item);
+ return item->getLabel();
+}
+
+void ScriptTreeItem::ensureVisible()
+{
+ ASSERT(item);
+ item->ensureVisible();
+}
+
+TreeItem *ScriptTreeItem::getNthChild(int nth)
+{
+ ASSERT(item);
+ return item->getNthChild(nth);
+}
+
+TreeItem *ScriptTreeItem::getChild()
+{
+ ASSERT(item);
+ return item->getChild();
+}
+
+TreeItem *ScriptTreeItem::getChildSibling(TreeItem *_item)
+{
+ ASSERT(item);
+ return item->getChildSibling(_item);
+}
+
+TreeItem *ScriptTreeItem::getSibling()
+{
+ ASSERT(item);
+ return item->getSibling();
+}
+
+TreeItem *ScriptTreeItem::getParent()
+{
+ ASSERT(item);
+ return item->getParent();
+}
+
+void ScriptTreeItem::editLabel()
+{
+ ASSERT(item);
+ item->editLabel();
+}
+
+bool ScriptTreeItem::hasSubItems()
+{
+ ASSERT(item);
+ return item->hasSubItems();
+}
+
+void ScriptTreeItem::setSorted(int issorted)
+{
+ ASSERT(item);
+ item->setSorted(issorted);
+}
+
+void ScriptTreeItem::setChildTab(int haschildtab)
+{
+ ASSERT(item);
+ item->setChildTab(haschildtab);
+}
+
+bool ScriptTreeItem::isSorted()
+{
+ ASSERT(item);
+ return item->isSorted();
+}
+
+bool ScriptTreeItem::isCollapsed()
+{
+ ASSERT(item);
+ return item->isCollapsed();
+}
+
+bool ScriptTreeItem::isExpanded()
+{
+ ASSERT(item);
+ return item->isExpanded();
+}
+
+void ScriptTreeItem::invalidate()
+{
+ ASSERT(item);
+ item->invalidate();
+}
+
+bool ScriptTreeItem::isSelected()
+{
+ ASSERT(item);
+ return item->isSelected();
+}
+
+bool ScriptTreeItem::isHilited()
+{
+ ASSERT(item);
+ return item->isHilited();
+}
+
+void ScriptTreeItem::setHilited(bool ishilited)
+{
+ ASSERT(item);
+ item->setHilited(ishilited);
+}
+
+int ScriptTreeItem::collapse()
+{
+ ASSERT(item);
+ return item->collapse();
+}
+
+int ScriptTreeItem::expand()
+{
+ ASSERT(item);
+ return item->expand();
+}
+
+#if 0
+// This was never implemented!
+void ScriptTreeItem::setCurrent(bool tf)
+{
+ ASSERT(item);
+ item->setCurrent(tf);
+}
+#endif
+
+TreeWnd *ScriptTreeItem::getTree()
+{
+ ASSERT(item);
+ return item->getTree();
+}
+
+// -----------------------------------------------------------------------
+// Script Controller For The Tree Item
+
+TreeItemScriptController _treeItemController;
+TreeItemScriptController *treeItemController = &_treeItemController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct TreeItemScriptController::exportedFunction[] = {
+ {L"getNumChildren", 0, (void*)TreeItemScriptController::treeitem_getNumChildren },
+ {L"setLabel", 1, (void*)TreeItemScriptController::treeitem_setLabel },
+ {L"getLabel", 0, (void*)TreeItemScriptController::treeitem_getLabel },
+ {L"ensureVisible", 0, (void*)TreeItemScriptController::treeitem_ensureVisible },
+ {L"getNthChild", 1, (void*)TreeItemScriptController::treeitem_getNthChild },
+ {L"getChild", 0, (void*)TreeItemScriptController::treeitem_getChild },
+ {L"getChildSibling", 1, (void*)TreeItemScriptController::treeitem_getChildSibling },
+ {L"getSibling", 0, (void*)TreeItemScriptController::treeitem_getSibling },
+ {L"getParent", 0, (void*)TreeItemScriptController::treeitem_getParent },
+ {L"editLabel", 0, (void*)TreeItemScriptController::treeitem_editLabel },
+ {L"hasSubItems", 0, (void*)TreeItemScriptController::treeitem_hasSubItems },
+ {L"setSorted", 1, (void*)TreeItemScriptController::treeitem_setSorted },
+ {L"setChildTab", 1, (void*)TreeItemScriptController::treeitem_setChildTab },
+ {L"isSorted", 0, (void*)TreeItemScriptController::treeitem_isSorted },
+ {L"isCollapsed", 0, (void*)TreeItemScriptController::treeitem_isCollapsed },
+ {L"isExpanded", 0, (void*)TreeItemScriptController::treeitem_isExpanded },
+ {L"invalidate", 0, (void*)TreeItemScriptController::treeitem_invalidate },
+ {L"isSelected", 0, (void*)TreeItemScriptController::treeitem_isSelected },
+ {L"isHilited", 0, (void*)TreeItemScriptController::treeitem_isHilited },
+ {L"setHilited", 1, (void*)TreeItemScriptController::treeitem_setHilited },
+ {L"collapse", 0, (void*)TreeItemScriptController::treeitem_collapse },
+ {L"expand", 0, (void*)TreeItemScriptController::treeitem_expand },
+ {L"getTree", 0, (void*)TreeItemScriptController::treeitem_getTree },
+
+ {L"onTreeAdd", 0, (void*)TreeItemScriptController::treeitem_onTreeAdd },
+ {L"onTreeRemove", 0, (void*)TreeItemScriptController::treeitem_onTreeRemove },
+ {L"onSelect", 0, (void*)TreeItemScriptController::treeitem_onSelect },
+ {L"onDeselect", 0, (void*)TreeItemScriptController::treeitem_onDeselect },
+ {L"onLeftDoubleClick", 0, (void*)TreeItemScriptController::treeitem_onLeftDoubleClick },
+ {L"onRightDoubleClick", 0, (void*)TreeItemScriptController::treeitem_onRightDoubleClick },
+ {L"onChar", 1, (void*)TreeItemScriptController::treeitem_onChar },
+ {L"onExpand", 0, (void*)TreeItemScriptController::treeitem_onExpand },
+ {L"onCollapse", 0, (void*)TreeItemScriptController::treeitem_onCollapse },
+ {L"onBeginLabelEdit", 0, (void*)TreeItemScriptController::treeitem_onBeginLabelEdit },
+ {L"onEndLabelEdit", 1, (void*)TreeItemScriptController::treeitem_onEndLabelEdit },
+ {L"onContextMenu", 2, (void*)TreeItemScriptController::treeitem_onContextMenu },
+
+ };
+
+StringW TreeItemScriptController::staticStr;
+ScriptTreeMap TreeItemScriptController::g_scriptitems;
+
+ScriptObject *TreeItemScriptController::instantiate()
+{
+ ScriptTreeItem *sp = new ScriptTreeItem;
+ ASSERT(sp != NULL);
+ TreeItem *child_item = new TreeItemScript(L"", sp);
+ ASSERT(child_item != NULL);
+ sp->setItem(child_item);
+ TISC::g_scriptitems.insert({ child_item, sp });
+ // We're not attached to a tree. that's okay!
+ return sp->getScriptObject();
+}
+
+// If the script asks to delete the item, delete the internal item as well.
+// We tell the owning ScriptTree to remove this object.
+void TreeItemScriptController::destroy(ScriptObject *o)
+{
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ ASSERT(sp != NULL);
+ if (!sp->destroyScriptTreeItem())
+ {
+ auto item = sp->getItem();
+ // Ask the owner tree to do it for us, but if not owned, we do it ourselves.
+ if (item)
+ {
+ //TISC::g_scriptitems.delItem(sp->getItem());
+ auto it = TISC::g_scriptitems.find(item);
+ if (TISC::g_scriptitems.end() != it)
+ {
+ TISC::g_scriptitems.erase(it);
+ }
+ }
+ // AND we delete our item, since we're not a part of a tree that will do it for us.
+ delete item;
+ delete sp;
+ }
+}
+
+void *TreeItemScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL; // no encapsulation for guitrees yet
+}
+
+void TreeItemScriptController::deencapsulate(void *o)
+{}
+
+int TreeItemScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *TreeItemScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->getNumChildren();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_setLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ StringW _label = GET_SCRIPT_STRING(label);
+ if (sp != NULL)
+ {
+ sp->setLabel(_label);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*String*/ scriptVar TreeItemScriptController::treeitem_getLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ if (sp != NULL)
+ {
+ staticStr = sp->getLabel();
+ }
+ return MAKE_SCRIPT_STRING(staticStr);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_ensureVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ if (sp != NULL)
+ {
+ sp->ensureVisible();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getNthChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar nth)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int _nth = GET_SCRIPT_INT(nth);
+ TreeItem *a = NULL;
+ if (sp != NULL)
+ {
+ a = sp->getNthChild(_nth);
+ }
+ ScriptTree *tree = sp->getScriptTree();
+ ScriptTreeItem *retval = NULL;
+ if (tree && a)
+ {
+ retval = tree->bindScriptTreeItem(a);
+ }
+ if (retval)
+ {
+ return MAKE_SCRIPT_OBJECT(retval->getScriptObject());
+ }
+ return MAKE_SCRIPT_OBJECT(NULL); // Return NULL
+}
+
+/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ TreeItem *a = NULL;
+ if (sp != NULL)
+ {
+ a = sp->getChild();
+ }
+ ScriptTree *tree = sp->getScriptTree();
+ ScriptTreeItem *retval = NULL;
+ if (tree && a)
+ {
+ retval = tree->bindScriptTreeItem(a);
+ }
+ if (retval)
+ {
+ return MAKE_SCRIPT_OBJECT(retval->getScriptObject());
+ }
+ return MAKE_SCRIPT_OBJECT(NULL); // Return NULL
+}
+
+/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getChildSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar _item)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ TreeItem *__item = NULL;
+ ScriptObject *io = GET_SCRIPT_OBJECT(_item);
+ if (io)
+ {
+ ScriptTreeItem *sio = static_cast<ScriptTreeItem *>(io->vcpu_getInterface(treeitemGuid));
+ if (sio)
+ {
+ __item = sio->getItem();
+ }
+ }
+ TreeItem *a = NULL;
+ if (sp != NULL)
+ {
+ a = sp->getChildSibling(__item);
+ }
+ ScriptTree *tree = sp->getScriptTree();
+ ScriptTreeItem *retval = NULL;
+ if (tree && a)
+ {
+ retval = tree->bindScriptTreeItem(a);
+ }
+ if (retval)
+ {
+ return MAKE_SCRIPT_OBJECT(retval->getScriptObject());
+ }
+ return MAKE_SCRIPT_OBJECT(NULL); // Return NULL
+}
+
+/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ TreeItem *a = NULL;
+ if (sp != NULL)
+ {
+ a = sp->getSibling();
+ }
+ ScriptTree *tree = sp->getScriptTree();
+ ScriptTreeItem *retval = NULL;
+ if (tree && a)
+ {
+ retval = tree->bindScriptTreeItem(a);
+ }
+ if (retval)
+ {
+ return MAKE_SCRIPT_OBJECT(retval->getScriptObject());
+ }
+ return MAKE_SCRIPT_OBJECT(NULL); // Return NULL
+}
+
+/*TreeItem*/ scriptVar TreeItemScriptController::treeitem_getParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ TreeItem *a = NULL;
+ if (sp != NULL)
+ {
+ a = sp->getParent();
+ }
+ ScriptTree *tree = sp->getScriptTree();
+ ScriptTreeItem *retval = NULL;
+ if (tree && a)
+ {
+ retval = tree->bindScriptTreeItem(a);
+ }
+ if (retval)
+ {
+ return MAKE_SCRIPT_OBJECT(retval->getScriptObject());
+ }
+ return MAKE_SCRIPT_OBJECT(NULL); // Return NULL
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_editLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ if (sp != NULL)
+ {
+ sp->editLabel();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_hasSubItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->hasSubItems();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar issorted)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int _issorted = GET_SCRIPT_INT(issorted);
+ if (sp != NULL)
+ {
+ sp->setSorted(_issorted);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_setChildTab(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar haschildtab)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int _haschildtab = GET_SCRIPT_INT(haschildtab);
+ if (sp != NULL)
+ {
+ sp->setChildTab(_haschildtab);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_isSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->isSorted();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_isCollapsed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->isCollapsed();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_isExpanded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->isExpanded();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_invalidate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ if (sp != NULL)
+ {
+ sp->invalidate();
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_isSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->isSelected();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_isHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->isHilited();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_setHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar ishilited)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int _ishilited = GET_SCRIPT_INT(ishilited);
+ if (sp != NULL)
+ {
+ sp->setHilited(!!_ishilited);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_collapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->collapse();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_expand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int a = 0;
+ if (sp != NULL)
+ {
+ a = sp->expand();
+ }
+ return MAKE_SCRIPT_INT(a);
+}
+
+#if 0
+// This was never implemented!
+/*void*/ scriptVar TreeItemScriptController::treeitem_setCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar tf)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ int _tf = GET_SCRIPT_INT(tf);
+ if (sp != NULL)
+ {
+ sp->setCurrent(_tf);
+ }
+ RETURN_SCRIPT_VOID;
+}
+#endif
+
+/*GuiTree*/ scriptVar TreeItemScriptController::treeitem_getTree(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ ScriptTreeItem *sp = static_cast<ScriptTreeItem *>(o->vcpu_getInterface(treeitemGuid));
+ ScriptTree *a = NULL;
+ ScriptObject *retval = NULL;
+ if (sp != NULL)
+ {
+ a = sp->getScriptTree();
+ }
+ if (a)
+ {
+ retval = a->getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(retval);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_onTreeAdd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_onTreeRemove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_onDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_onLeftDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_onRightDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _key)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, _key);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, _key);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_onExpand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*void*/ scriptVar TreeItemScriptController::treeitem_onCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_onBeginLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS0(o, guiTreeController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_onEndLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar _newlabel)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS1(o, guiTreeController, _newlabel);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, _newlabel);
+}
+
+/*int*/ scriptVar TreeItemScriptController::treeitem_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _x, /*int*/ scriptVar _y)
+{
+ SCRIPT_FUNCTION_INIT
+ PROCESS_HOOKS2(o, guiTreeController, _x, _y);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, _x, _y);
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuitree.h b/Src/Wasabi/api/skin/widgets/xuitree.h
new file mode 100644
index 00000000..2d386440
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuitree.h
@@ -0,0 +1,326 @@
+#ifndef __XUITREE_H
+#define __XUITREE_H
+
+#include <map>
+#include <api/wnd/wndclass/treewnd.h>
+#include <api/script/objcontroller.h>
+#include <bfc/depend.h>
+
+class HPNode;
+class ScriptTreeItem;
+class svc_textFeed;
+
+#define SCRIPTTREE_PARENT TreeWnd
+
+typedef std::map<TreeItem *,ScriptTreeItem *> ScriptTreeMap;
+
+// -----------------------------------------------------------------------
+class ScriptTree : public SCRIPTTREE_PARENT, public DependentViewerI {
+
+ public:
+
+ ScriptTree();
+ virtual ~ScriptTree();
+
+ virtual int onInit();
+
+ int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+ int onReloadConfig();
+
+ virtual int viewer_onEvent(api_dependent *item, const GUID *classguid, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual void onSetVisible(int i);
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+ // Find a ScriptTreeItem to wrap a TreeItem
+ ScriptTreeItem *bindScriptTreeItem(TreeItem *item);
+
+ // Someone is deleting a ScriptTreeItem so we should stop tracking it.
+ int destroyScriptTreeItem(ScriptTreeItem *item);
+
+ // Transfer a TreeItem from our tree to a different tree (or global space)
+ int transferScriptTreeItem(TreeItem *item, ScriptTree *tree);
+
+ // Callback methods that send hooks into the Script system
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onRightButtonUp(int x, int y);
+ virtual int onMouseMove(int x, int y);
+ virtual int wantAutoContextMenu();
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int onRightButtonDblClk(int x, int y);
+ virtual int onMouseWheelUp(int clicked, int lines);
+ virtual int onMouseWheelDown(int clicked, int lines);
+ virtual int onContextMenu(int x, int y);
+ virtual int onChar(wchar_t c);
+ virtual int onKeyDown(int keycode);
+ virtual void onItemRecvDrop(TreeItem *item);
+ virtual void onLabelChange(TreeItem *item);
+ virtual void onItemSelected(TreeItem *item);
+ virtual void onItemDeselected(TreeItem *item);
+ virtual int onKillFocus();
+
+
+
+ // Valid XML Params for Tree
+ enum {
+ SCRIPTTREE_SETITEMS = 0,
+ SCRIPTTREE_FEED,
+ SCRIPTTREE_SORTED,
+ SCRIPTTREE_CHILDTABS,
+ SCRIPTTREE_EXPANDROOT,
+ };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+
+ private:
+
+#ifdef WASABI_COMPILE_CONFIG
+ void saveToConfig();
+ void selectFromConfig();
+#endif
+ void expandRoot(int val);
+
+ void fillFromParams();
+ void fillFromHPNode(HPNode *node, TreeItem *parent = NULL);
+
+ int selectEntry(const wchar_t *e, int cb=1);
+ void selectEntries(const wchar_t *multientry, int cb=1);
+
+ void openFeed(const wchar_t *feedid);
+ void closeFeed();
+
+ StringW items;
+ int myxuihandle;
+ int childtabs;
+ int expandroot;
+ svc_textFeed *feed;
+ StringW last_feed;
+ static XMLParamPair params[];
+
+// ScriptTreeMap scriptitems;
+};
+
+// -----------------------------------------------------------------------------------------------------
+class GuiTreeScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"GuiTree"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return guitreeGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar /*int*/ guitree_getNumRootItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar /*TreeItem*/ guitree_enumRootItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar /*int*/ which);
+
+ static /*Int*/ scriptVar guitree_onLeftButtonDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_onLeftButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_onRightButtonUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_onMouseMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_wantAutoContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*Int*/ scriptVar guitree_onLeftButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_onRightButtonDblClk(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_onMouseWheelUp(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines);
+ static /*Int*/ scriptVar guitree_onMouseWheelDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar clicked, /*Int*/ scriptVar lines);
+ static /*Int*/ scriptVar guitree_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Int*/ scriptVar guitree_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar c);
+ static /*Int*/ scriptVar guitree_onKeyDown(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar keycode);
+ static /*Void*/ scriptVar guitree_onItemRecvDrop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_onLabelChange(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_onItemSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_onItemDeselected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Int*/ scriptVar guitree_onKillFocus(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static /*Void*/ scriptVar guitree_jumpToNext(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar c);
+ static /*Void*/ scriptVar guitree_ensureItemVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Int*/ scriptVar guitree_getContentsWidth(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*Int*/ scriptVar guitree_getContentsHeight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar guitree_addTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar par, /*Int*/ scriptVar sorted, /*Int*/ scriptVar haschildtab);
+ static /*Int*/ scriptVar guitree_removeTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_moveTreeItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item, /*TreeItem*/ scriptVar newparent);
+ static /*Void*/ scriptVar guitree_deleteAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*Int*/ scriptVar guitree_expandItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_expandItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Int*/ scriptVar guitree_collapseItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_collapseItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_selectItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_selectItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_delItemDeferred(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_hiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_unhiliteItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*TreeItem*/ scriptVar guitree_getCurItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar guitree_hitTest(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+ static /*Void*/ scriptVar guitree_editItemLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_cancelEditLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar destroyit);
+ static /*Void*/ scriptVar guitree_setAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar ae);
+ static /*Int*/ scriptVar guitree_getAutoEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar guitree_getByLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item, /*String*/ scriptVar name);
+ static /*Void*/ scriptVar guitree_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar dosort);
+ static /*Int*/ scriptVar guitree_getSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*Void*/ scriptVar guitree_sortTreeItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar guitree_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Void*/ scriptVar guitree_setAutoCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar doautocollapse);
+ static /*Int*/ scriptVar guitree_setFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar newsize);
+ static /*Int*/ scriptVar guitree_getFontSize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*Int*/ scriptVar guitree_getNumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar c);
+ static /*Int*/ scriptVar guitree_getNumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar guitree_enumVisibleItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar n);
+ static /*TreeItem*/ scriptVar guitree_enumVisibleChildItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar c, /*Int*/ scriptVar n);
+ static /*TreeItem*/ scriptVar guitree_enumAllItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar n);
+ static /*Int*/ scriptVar guitree_getItemRectX(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Int*/ scriptVar guitree_getItemRectY(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Int*/ scriptVar guitree_getItemRectW(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+ static /*Int*/ scriptVar guitree_getItemRectH(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar item);
+// static /*TreeItem*/ scriptVar guitree_getItemFromPoint(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*Int*/ scriptVar x, /*Int*/ scriptVar y);
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+
+ static StringW staticStr;
+};
+
+extern GuiTreeScriptController *guiTreeController;
+
+
+// -----------------------------------------------------------------------
+extern const wchar_t ScriptTreeXuiObjectStr[];
+extern char ScriptTreeXuiSvcName[];
+class ScriptTreeXuiSvc : public XuiObjectSvc<ScriptTree, ScriptTreeXuiObjectStr, ScriptTreeXuiSvcName> {};
+
+
+
+// -----------------------------------------------------------------------
+#define SCRIPTTREEITEM_SCRIPTPARENT RootObjectInstance
+
+class ScriptTreeItem : public SCRIPTTREEITEM_SCRIPTPARENT {
+public:
+ ScriptTreeItem(TreeItem *_item = NULL, ScriptTree *_tree = NULL);
+ virtual ~ScriptTreeItem();
+
+ TreeItem *getItem() {return item;}
+ void setItem(TreeItem *_item) {item = _item;}
+ ScriptTree *getScriptTree() {return tree;}
+ void setScriptTree(ScriptTree *_tree) {tree = _tree;}
+
+ int destroyScriptTreeItem() {
+ if (tree) return tree->destroyScriptTreeItem(this); // CAREFUL, WE GET OURSELVES DELETED HERE!!!!!!!!
+ return 0;
+ }
+
+// These methods all thunk directly to the TreeItem
+public:
+ int getNumChildren();
+ void setLabel(const wchar_t *label);
+ const wchar_t *getLabel();
+ void ensureVisible();
+ TreeItem *getNthChild(int nth);
+ TreeItem *getChild();
+ TreeItem *getChildSibling(TreeItem *_item);
+ TreeItem *getSibling();
+ TreeItem *getParent();
+ void editLabel();
+ bool hasSubItems();
+ void setSorted(int issorted);
+ void setChildTab(int haschildtab);
+ bool isSorted();
+ bool isCollapsed();
+ bool isExpanded();
+ void invalidate();
+ bool isSelected();
+ bool isHilited();
+ void setHilited(bool ishilited);
+ int collapse();
+ int expand();
+// void setCurrent(bool tf);
+ TreeWnd *getTree();
+
+private:
+ ScriptTreeItem *bindScriptTreeItem(TreeItem *item) {
+ if (tree) return tree->bindScriptTreeItem(item);
+ return NULL;
+ }
+
+ TreeItem *item;
+ ScriptTree *tree;
+};
+
+
+// -----------------------------------------------------------------------------------------------------
+class TreeItemScriptController : public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"TreeItem"; }
+ virtual const wchar_t *getAncestorClassName() { return L"Object"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(rootObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return treeitemGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static /*int*/ scriptVar treeitem_getNumChildren(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_setLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar label);
+ static /*String*/ scriptVar treeitem_getLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_ensureVisible(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar treeitem_getNthChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar nth);
+ static /*TreeItem*/ scriptVar treeitem_getChild(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar treeitem_getChildSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*TreeItem*/ scriptVar _item);
+ static /*TreeItem*/ scriptVar treeitem_getSibling(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*TreeItem*/ scriptVar treeitem_getParent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_editLabel(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_hasSubItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_setSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar issorted);
+ static /*void*/ scriptVar treeitem_setChildTab(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar haschildtab);
+ static /*int*/ scriptVar treeitem_isSorted(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_isCollapsed(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_isExpanded(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_invalidate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_isSelected(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_isHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_setHilited(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar ishilited);
+ static /*int*/ scriptVar treeitem_collapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_expand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+// static /*void*/ scriptVar treeitem_setCurrent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar tf);
+ static /*GuiTree*/ scriptVar treeitem_getTree(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ static /*void*/ scriptVar treeitem_onTreeAdd(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_onTreeRemove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_onSelect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*void*/ scriptVar treeitem_onDeselect(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_onLeftDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ;
+ static /*int*/ scriptVar treeitem_onRightDoubleClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ;
+ static /*int*/ scriptVar treeitem_onChar(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _key) ;
+ static /*void*/ scriptVar treeitem_onExpand(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ;
+ static /*void*/ scriptVar treeitem_onCollapse(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) ;
+ static /*int*/ scriptVar treeitem_onBeginLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static /*int*/ scriptVar treeitem_onEndLabelEdit(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*String*/ scriptVar _newlabel);
+ static /*int*/ scriptVar treeitem_onContextMenu(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, /*int*/ scriptVar _x, /*int*/ scriptVar _y);
+
+
+ private:
+ static function_descriptor_struct exportedFunction[];
+
+ static StringW staticStr;
+
+ friend ScriptTree;
+ static ScriptTreeMap g_scriptitems; // items not living in trees are tracked here.
+
+};
+
+extern TreeItemScriptController *treeItemController;
+
+#define TISC TreeItemScriptController
+
+
+#endif
diff --git a/Src/Wasabi/api/skin/widgets/xuiwndholder.cpp b/Src/Wasabi/api/skin/widgets/xuiwndholder.cpp
new file mode 100644
index 00000000..8cd3e116
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiwndholder.cpp
@@ -0,0 +1,272 @@
+#include <precomp.h>
+#include "xuiwndholder.h"
+#include <tataki/canvas/ifc_canvas.h>
+#include <bfc/parse/paramparser.h>
+#include <api/script/objects/sregion.h>
+
+// -----------------------------------------------------------------------
+const wchar_t WindowHolderXuiObjectStr[] = L"WindowHolder"; // This is the xml tag
+const wchar_t WindowHolderXuiObjectStrCompat[] = L"Component"; // This is the old xml tag
+
+char WindowHolderXuiSvcName[] = "WindowHolder xui object";
+char WindowHolderXuiSvcNameCompat[] = "Component xui object";
+
+// {7DB51C8C-36C0-4585-9240-A2DB22B1B8F7}
+static const GUID pvt_xuiWindowHolder =
+{ 0x7db51c8c, 0x36c0, 0x4585, { 0x92, 0x40, 0xa2, 0xdb, 0x22, 0xb1, 0xb8, 0xf7 } };
+
+XMLParamPair XuiWindowHolder::params[] = {
+ {XUIWNDHOLDER_ADDHOLD, L"PARAM"},
+ {XUIWNDHOLDER_ADDHOLD, L"COMPONENT"},
+ {XUIWNDHOLDER_ADDHOLD, L"HOLD"},
+ {XUIWNDHOLDER_SETNOSHOWCMDBAR, L"NOSHOWCMDBAR"},
+ {XUIWNDHOLDER_SETNOANIMRECTS, L"NOANIMATEDRECTS"},
+ {XUIWNDHOLDER_SETNOANIMRECTS, L"DISABLEANIMATEDRECTS"},
+ {XUIWNDHOLDER_SETAUTOOPEN, L"AUTOOPEN"},
+ {XUIWNDHOLDER_SETAUTOCLOSE, L"AUTOCLOSE"},
+ {XUIWNDHOLDER_SETAUTOFOCUS, L"AUTOFOCUS"},
+ {XUIWNDHOLDER_SETAUTOAVAILABLE, L"AUTOAVAILABLE"},
+ };
+// -----------------------------------------------------------------------
+XuiWindowHolder::XuiWindowHolder() {
+ getScriptObject()->vcpu_setInterface(windowHolderGuid, (void *)static_cast<WindowHolder *>(this));
+ getScriptObject()->vcpu_setInterface(pvt_xuiWindowHolder, (void *)static_cast<XuiWindowHolder *>(this));
+ getScriptObject()->vcpu_setClassName(L"WindowHolder"); // this is the script class name
+ getScriptObject()->vcpu_setController(windowHolderController);
+
+ myxuihandle = newXuiHandle();
+ CreateXMLParameters(myxuihandle);
+
+ setXmlParam(L"autofocus", L"1");
+}
+void XuiWindowHolder::CreateXMLParameters(int master_handle)
+{
+ //XUIWNDHOLDER_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(myxuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+XuiWindowHolder::~XuiWindowHolder() {
+}
+
+void XuiWindowHolder::setRegionFromMap(ScriptObject *map, int byte, int inverse) {
+}
+
+void XuiWindowHolder::setRegion(ScriptObject *_region) {
+//#pragma CHAT("bas", "lone", "I implemented setRegion for ya once SRegion is safe")
+#if 1// if SRegion were cross-dll safe this would work
+ const GUID regionGuid =
+{ 0x3a370c02, 0x3cbf, 0x439f, { 0x84, 0xf1, 0x86, 0x88, 0x5b, 0xcf, 0x1e, 0x36 } };
+ void *reg = _region->vcpu_getInterface(regionGuid);
+ ASSERT(reg != NULL);
+ SRegion *sr = static_cast<SRegion*>(reg);
+ ASSERT(sr != NULL);
+ api_region *region = sr->getRegion();
+ ASSERT(region != NULL);
+ api_region *clone = region->clone();
+ clone->scale(getRenderRatio(), getRenderRatio());
+ ifc_window *curRootWnd = getCurRootWnd();
+ if (curRootWnd)
+ {
+#ifdef _WIN32
+ OSWINDOWHANDLE osWnd = curRootWnd->gethWnd();
+ if (osWnd)
+ SetWindowRgn(osWnd, clone->makeWindowRegion(), TRUE);
+#else
+#warning port me
+ // can probably use a mask here
+#endif
+ }
+ region->disposeClone(clone);
+#endif
+}
+
+// -----------------------------------------------------------------------
+int XuiWindowHolder::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
+ if (xuihandle != myxuihandle)
+ return XUIWNDHOLDER_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case XUIWNDHOLDER_ADDHOLD:
+ if (!WCSICMP(value, L"@ALL@") || !WCSICMP(value, L"guid:default"))
+ {
+ setAcceptAllGuids(1);
+ setAcceptAllGroups(1);
+ } else {
+ setAcceptAllGuids(0);
+ setAcceptAllGroups(0);
+ ParamParser pp(value);
+ for (int i=0;i<pp.getNumItems();i++) {
+ const wchar_t *e = pp.enumItem(i);
+ if (*e == '{' || !WCSNICMP(e, L"guid:", 5)) {
+ GUID *g = parseGUID(e);
+ if (g)
+ addAcceptGuid(*g);
+ }
+ else
+ addAcceptGroup(e);
+ }
+ }
+ break;
+ case XUIWNDHOLDER_SETNOSHOWCMDBAR:
+ setNoCmdBar(WTOI(value));
+ break;
+ case XUIWNDHOLDER_SETNOANIMRECTS:
+ setNoAnim(WTOI(value));
+ break;
+ case XUIWNDHOLDER_SETAUTOOPEN:
+ setAutoOpen(WTOI(value));
+ break;
+ case XUIWNDHOLDER_SETAUTOCLOSE:
+ setAutoClose(WTOI(value));
+ break;
+ case XUIWNDHOLDER_SETAUTOFOCUS:
+ setAutoFocus(WTOI(value));
+ break;
+ case XUIWNDHOLDER_SETAUTOAVAILABLE:
+ setAutoAvailable(WTOI(value));
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+GUID *XuiWindowHolder::parseGUID(const wchar_t *id) {
+ if (WCSNICMP(id, L"guid:{",6)==0) {
+ static GUID g;
+ id+=5;
+ g = nsGUID::fromCharW(id);
+ return &g;
+ }
+ if (id && *id == '{') {
+ static GUID g;
+ g = nsGUID::fromCharW(id);
+ return &g;
+ }
+ if(WCSICMP(id,L"guid:avs")==0) {
+ static GUID g={ 10, 12, 16, { 255, 123, 1, 1, 66, 99, 69, 12 } };
+ return &g;
+ }
+ if (WCSICMP(id,L"guid:pl")==0 || WCSICMP(id,L"guid:playlist")==0) {
+ static GUID g={ 0x45f3f7c1, 0xa6f3, 0x4ee6, { 0xa1, 0x5e, 0x12, 0x5e, 0x92, 0xfc, 0x3f, 0x8d } };
+ return &g;
+ }
+ if (WCSICMP(id,L"guid:ml")==0 || WCSICMP(id,L"guid:musiclibrary")==0 || WCSICMP(id,L"guid:library")==0) {
+ static GUID g={ 0x6b0edf80, 0xc9a5, 0x11d3, { 0x9f, 0x26, 0x00, 0xc0, 0x4f, 0x39, 0xff, 0xc6 } };
+ return &g;
+ }
+ if(WCSICMP(id,L"guid:null")==0) {
+ static GUID g=INVALID_GUID;
+ return &g;
+ }
+ if(WCSICMP(id,L"guid:player")==0) {
+ static GUID g = { 0xe6323f86, 0x1724, 0x4cd3, { 0x9d, 0x87, 0x70, 0x59, 0x1f, 0xc1, 0x6e, 0x5e } };
+ return &g;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+// Script Object
+
+WindowHolderScriptController _windowHolderController;
+WindowHolderScriptController *windowHolderController = &_windowHolderController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct WindowHolderScriptController::exportedFunction[] = {
+ {L"getGUID", 1, (void*)WindowHolderScriptController::script_getGUID },
+ {L"setRegionFromMap", 3, (void*)WindowHolderScriptController::script_setRegionFromMap },
+ {L"setRegion", 1, (void*)WindowHolderScriptController::script_setRegion },
+ {L"getContent", 0, (void*)WindowHolderScriptController::script_getContent},
+ {L"getComponentName", 0, (void*)WindowHolderScriptController::script_getComponentName},
+};
+
+ScriptObject *WindowHolderScriptController::instantiate() {
+ XuiWindowHolder *wh = new XuiWindowHolder;
+ ASSERT(wh != NULL);
+ return wh->getScriptObject();
+}
+
+void WindowHolderScriptController::destroy(ScriptObject *o) {
+ XuiWindowHolder *wh = static_cast<XuiWindowHolder *>(o->vcpu_getInterface(pvt_xuiWindowHolder));
+ ASSERT(wh != NULL);
+ delete wh;
+}
+
+void *WindowHolderScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for windowholder yet
+}
+
+void WindowHolderScriptController::deencapsulate(void *o) {
+}
+
+int WindowHolderScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *WindowHolderScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+scriptVar WindowHolderScriptController::script_getComponentName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ XuiWindowHolder *wh = static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder));
+
+ if (wh)
+ {
+ ifc_window *ro = wh->getCurRootWnd();
+ if (ro)
+ {
+ return MAKE_SCRIPT_STRING(ro->getRootWndName());
+ }
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar WindowHolderScriptController::script_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ XuiWindowHolder *wh = static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder));
+
+ if (wh)
+ {
+ static wchar_t guidstr[256];
+ nsGUID::toCharW(wh->getCurGuid(), guidstr);
+ return MAKE_SCRIPT_STRING(guidstr);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar WindowHolderScriptController::script_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv) {
+ SCRIPT_FUNCTION_INIT
+ XuiWindowHolder *xu = static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder));
+ if (xu) xu->setRegionFromMap(GET_SCRIPT_OBJECT(map), GET_SCRIPT_INT(byte), GET_SCRIPT_INT(inv));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar WindowHolderScriptController::script_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg) {
+ SCRIPT_FUNCTION_INIT
+ XuiWindowHolder *xu= static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder));
+ if (xu) xu->setRegion(GET_SCRIPT_OBJECT(reg));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar WindowHolderScriptController::script_getContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ XuiWindowHolder *xu= static_cast<XuiWindowHolder*>(o->vcpu_getInterface(pvt_xuiWindowHolder));
+ if (xu) {
+ ifc_window *w = xu->getRootWndPtr();
+ if (w) {
+ GuiObject *o = w->getGuiObject();
+ if (o)
+ return MAKE_SCRIPT_OBJECT(o->guiobject_getScriptObject());
+ }
+ }
+ RETURN_SCRIPT_NULL;
+}
diff --git a/Src/Wasabi/api/skin/widgets/xuiwndholder.h b/Src/Wasabi/api/skin/widgets/xuiwndholder.h
new file mode 100644
index 00000000..13edc05a
--- /dev/null
+++ b/Src/Wasabi/api/skin/widgets/xuiwndholder.h
@@ -0,0 +1,80 @@
+#ifndef __XUIWNDHOLDER_H
+#define __XUIWNDHOLDER_H
+
+#include <api/wnd/wndclass/wndholder.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objcontroller.h>
+
+#define XUIWNDHOLDER_PARENT WindowHolderWnd
+
+// -----------------------------------------------------------------------
+class XuiWindowHolder : public XUIWNDHOLDER_PARENT
+{
+
+ public:
+
+ XuiWindowHolder();
+ virtual ~XuiWindowHolder();
+
+ virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+
+ void setRegionFromMap(ScriptObject *map, int byte, int inverse);
+ void setRegion(ScriptObject *region);
+ static GUID *parseGUID(const wchar_t *id);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+ private:
+
+ enum {
+ XUIWNDHOLDER_ADDHOLD = 10,
+ XUIWNDHOLDER_SETNOSHOWCMDBAR = 20,
+ XUIWNDHOLDER_SETNOANIMRECTS = 30,
+ XUIWNDHOLDER_SETAUTOOPEN = 40,
+ XUIWNDHOLDER_SETAUTOCLOSE = 50,
+ XUIWNDHOLDER_SETAUTOFOCUS = 60,
+ XUIWNDHOLDER_SETAUTOAVAILABLE = 70,
+ };
+ static XMLParamPair params[];
+ int myxuihandle;
+};
+
+// -----------------------------------------------------------------------------------------------------
+class WindowHolderScriptController: public ScriptObjectControllerI {
+ public:
+
+ virtual const wchar_t *getClassName() { return L"WindowHolder"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return windowHolderGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ public:
+ static scriptVar script_getGUID(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setRegionFromMap(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar map, scriptVar byte, scriptVar inv);
+ static scriptVar script_setRegion(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar reg);
+ static scriptVar script_getContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getComponentName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+};
+
+extern WindowHolderScriptController *windowHolderController;
+
+
+// -----------------------------------------------------------------------
+extern const wchar_t WindowHolderXuiObjectStr[];
+extern const wchar_t WindowHolderXuiObjectStrCompat[];
+extern char WindowHolderXuiSvcName[];
+extern char WindowHolderXuiSvcNameCompat[];
+class WindowHolderXuiSvc : public XuiObjectSvc<XuiWindowHolder, WindowHolderXuiObjectStr, WindowHolderXuiSvcName> {};
+class WindowHolderXuiSvc2 : public XuiObjectSvc<XuiWindowHolder, WindowHolderXuiObjectStrCompat, WindowHolderXuiSvcNameCompat> {};
+
+#endif
diff --git a/Src/Wasabi/api/skin/xmlobject.cpp b/Src/Wasabi/api/skin/xmlobject.cpp
new file mode 100644
index 00000000..b7e43ccf
--- /dev/null
+++ b/Src/Wasabi/api/skin/xmlobject.cpp
@@ -0,0 +1,174 @@
+#include <precomp.h>
+#include <bfc/bfc_assert.h>
+#include "xmlobject.h"
+#include <new>
+#define PILENODE_AUTOINCREMENT 50
+
+/*
+
+CreateXMLParameters(int master_handle)
+addParam(master_handle, this_handle, name, id)
+
+master_handle is key into array of name/this-handle/id
+
+
+*/
+class DeleteOnClose
+{
+public:
+ ~DeleteOnClose()
+ {
+ allocd.freeAll();
+ }
+ PtrList<XmlObjectParam> allocd;
+};
+DeleteOnClose deleter;
+template <class t_>
+struct PileNode
+{
+ PileNode(int num)
+ {
+ sizePile = num;
+ pile = (t_ *)MALLOC(sizeof(t_) * num);
+ deleter.allocd.addItem(pile);
+ }
+ void Rebuild(int num)
+ {
+ sizePile = num;
+ pile = (t_ *)MALLOC(sizeof(t_) * num);
+ deleter.allocd.addItem(pile);
+ }
+ size_t sizePile;
+ t_ *pile;
+ void *Get()
+ {
+ sizePile--;
+ return pile++;
+ }
+};
+template <class t_>
+struct PileList
+{
+ PileList(int numPtrs, PileList<t_> *_next = 0) : node(numPtrs), next(_next)
+ {
+ }
+ PileNode<t_> node;
+ PileList *next;
+ void *Get()
+ {
+ if (node.sizePile)
+ {
+ return node.Get();
+ }
+ else
+ {
+ while (next && !next->node.sizePile)
+ {
+ PileList<t_> *temp = next;
+ next = temp->next;
+ delete temp;
+ }
+ if (next)
+ return next->Get();
+ else
+ {
+ node.Rebuild(PILENODE_AUTOINCREMENT);
+ return node.Get();
+ }
+ }
+ }
+};
+
+PileList<XmlObjectParam> *paramPile = 0;
+
+XmlObjectParam::XmlObjectParam(int xmlhandle, wchar_t *xmlattribute, int xmlattributeid)
+ : xmlattributename(xmlattribute), attributeid(xmlattributeid), handle(xmlhandle)
+{
+KEYWORDUPPER(xmlattribute);
+}
+
+#define CBCLASS XmlObjectI
+START_DISPATCH;
+CB(SETXMLPARAM, setXmlParam);
+CB(GETXMLPARAMVALUE, getXmlParamValue);
+CB(GETXMLPARAM, getXmlParam);
+END_DISPATCH;
+
+XmlObjectI::XmlObjectI()
+{
+ handlepos = 0;
+}
+
+XmlObjectI::~XmlObjectI()
+{
+ params.removeAll();
+}
+
+void XmlObjectI::addParam(int xmlhandle, XMLParamPair &param, int unused)
+//void XmlObjectI::addXmlParam(int xmlhandle, const wchar_t *xmlattribute, int xmlattributeid)
+{
+ if (!paramPile)
+ paramPile = new PileList<XmlObjectParam>(PILENODE_AUTOINCREMENT);
+
+ params.addItem(new(paramPile->Get()) XmlObjectParam(xmlhandle, param.name, param.id));
+}
+
+int XmlObjectI::setXmlParamById(int xmlhandle, int xmlattribute, const wchar_t *param, const wchar_t *value)
+{
+ return 0;
+}
+
+int XmlObjectI::setXmlParam(const wchar_t *param, const wchar_t *value)
+{
+ int pos = -1;
+ int r = 0;
+ params.findItem(param, &pos);
+ if (pos >= 0)
+ {
+ XmlObjectParam *xuop = params.enumItem(pos);
+ ASSERT(xuop != NULL);
+ r = setXmlParamById(xuop->getXmlHandle(), xuop->getXmlAttributeId(), param, value);
+ xuop->setLastValue(value);
+ }
+ else
+ {
+ onUnknownXmlParam(param, value);
+ }
+ return r;
+}
+
+const wchar_t *XmlObjectI::getXmlParamValue(int n)
+{
+ return params.enumItem(n)->getLastValue();
+}
+
+int XmlObjectI::getXmlParam(const wchar_t *param)
+{
+ int pos=-1;
+ params.findItem(param, &pos);
+ return pos;
+}
+
+const wchar_t *XmlObjectI::getXmlParamByName(const wchar_t *paramname)
+{
+ int pos = getXmlParam(paramname);
+ if (pos < 0) return NULL;
+ return getXmlParamValue(pos);
+}
+
+int XmlObjectI::newXmlHandle()
+{
+ return handlepos++;
+}
+
+int XmlObjectI::onUnknownXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ return 0;
+}
+
+void XmlObjectI::hintNumberOfParams(int xmlhandle, int numParams)
+{
+ paramPile = new PileList<XmlObjectParam>(numParams, paramPile);
+
+ params.setMinimumSize(params.getNumItems() + numParams);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/skin/xmlobject.h b/Src/Wasabi/api/skin/xmlobject.h
new file mode 100644
index 00000000..1a45797f
--- /dev/null
+++ b/Src/Wasabi/api/skin/xmlobject.h
@@ -0,0 +1,132 @@
+#ifndef __XMLOBJECT_H
+#define __XMLOBJECT_H
+
+#include <bfc/nsguid.h>
+#include <bfc/ptrlist.h>
+#include <bfc/dispatch.h>
+#include <bfc/string/StringW.h>
+#include <bfc/wasabi_std.h>
+
+#define XML_ATTRIBUTE_IMPLIED 0
+#define XML_ATTRIBUTE_REQUIRED 1
+
+class XmlObject : public Dispatchable
+{
+public:
+ int setXmlParam(const wchar_t *name, const wchar_t *strvalue);
+ const wchar_t *getXmlParamValue(int n);
+ int getXmlParam(const wchar_t *paramname);
+
+ enum
+ {
+ SETXMLPARAM=10,
+ GETXMLPARAMVALUE=40,
+ GETXMLPARAM=50,
+ };
+};
+
+inline int XmlObject::setXmlParam(const wchar_t *name, const wchar_t *strvalue)
+{
+ return _call(SETXMLPARAM, 0, name, strvalue);
+}
+
+inline const wchar_t *XmlObject::getXmlParamValue(int n)
+{
+ return _call(GETXMLPARAMVALUE, (const wchar_t *)0, n);
+}
+
+inline int XmlObject::getXmlParam(const wchar_t *paramname)
+{
+ return _call(GETXMLPARAM, 0, paramname);
+}
+
+class XmlObjectParam
+{
+
+public:
+
+ XmlObjectParam(int xmlhandle, wchar_t *xmlattribute, int xmlattributeid);
+ virtual ~XmlObjectParam() {}
+
+ const wchar_t *getXmlAttribute()
+ {
+ return xmlattributename;
+ }
+ int getXmlAttributeId()
+ {
+ return attributeid;
+ }
+ int getXmlHandle()
+ {
+ return handle;
+ }
+ void setLastValue(const wchar_t *val)
+ {
+ lastvalue = val;
+ }
+ const wchar_t *getLastValue()
+ {
+ return lastvalue;
+ }
+
+private:
+ const wchar_t *xmlattributename;
+ StringW lastvalue;
+ int attributeid;
+ int handle;
+
+};
+
+class XmlObjectParamSort
+{
+public:
+ static inline int compareItem(XmlObjectParam *p1, XmlObjectParam*p2)
+ {
+ return wcscmp(p1->getXmlAttribute(), p2->getXmlAttribute());
+ }
+ static inline int compareAttrib(const wchar_t *attrib, XmlObjectParam *item)
+ {
+ return WCSICMP(attrib, item->getXmlAttribute());
+ }
+};
+
+struct XMLParamPair
+{
+ int id;
+ wchar_t name[64];
+};
+
+class XmlObjectI : public XmlObject
+{
+public:
+ XmlObjectI();
+ virtual ~XmlObjectI();
+
+ virtual int setXmlParam(const wchar_t *name, const wchar_t *strvalue); // receives from system
+ virtual int setXmlParamById(int xmlhandle, int xmlattributeid, const wchar_t *name, const wchar_t *strvalue); // distributes to inheritors
+ virtual const wchar_t *getXmlParamValue(int n);
+ virtual int getXmlParam(const wchar_t *paramname);
+ const wchar_t *getXmlParamByName(const wchar_t *paramname);
+ void addParam(int xmlhandle, XMLParamPair &param, int unused=0);
+ //void addXmlParam(int xmlhandle, const wchar_t *xmlattribute, int xmlattributeid);
+protected:
+ virtual int onUnknownXmlParam(const wchar_t *param, const wchar_t *value);
+ int newXmlHandle();
+ void hintNumberOfParams(int xmlhandle, int params);
+
+private:
+ XmlObjectParam *enumParam(int n)
+ {
+ return params[n];
+ }
+
+ PtrListInsertSorted<XmlObjectParam, XmlObjectParamSort> params;
+ int handlepos;
+
+protected:
+
+ RECVS_DISPATCH;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/syscb/api_syscb.cpp b/Src/Wasabi/api/syscb/api_syscb.cpp
new file mode 100644
index 00000000..f88c93ff
--- /dev/null
+++ b/Src/Wasabi/api/syscb/api_syscb.cpp
@@ -0,0 +1,14 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:14 2003]
+//
+// File : api_syscb.cpp
+// Class : api_syscb
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "api_syscb.h"
+
+api_syscb *sysCallbackApi=NULL;
+
+
diff --git a/Src/Wasabi/api/syscb/api_syscb.h b/Src/Wasabi/api/syscb/api_syscb.h
new file mode 100644
index 00000000..2e8a1323
--- /dev/null
+++ b/Src/Wasabi/api/syscb/api_syscb.h
@@ -0,0 +1,77 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:14 2003]
+//
+// File : api_syscb.h
+// Class : api_syscb
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_SYSCB_H
+#define __API_SYSCB_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+
+class SysCallback;
+
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE api_syscb: public Dispatchable
+{
+ protected:
+ api_syscb() {}
+ ~api_syscb() {}
+ public:
+ int syscb_registerCallback(SysCallback *cb, void *param = 0);
+ int syscb_deregisterCallback(SysCallback *cb);
+ int syscb_issueCallback(int eventtype, int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+
+ /** pass eventtype == 0 to enumerate all syscallbacks
+ ** call Release() on the returned SysCallback when you are done
+ ** although very few wasabi objects support this at this time (2 June 2008)
+ **/
+ SysCallback *syscb_enum(int eventtype, size_t n);
+
+ protected:
+ enum {
+ API_SYSCB_SYSCB_REGISTERCALLBACK = 20,
+ API_SYSCB_SYSCB_DEREGISTERCALLBACK = 10,
+ API_SYSCB_SYSCB_ISSUECALLBACK = 30,
+ API_SYSCB_SYSCB_ENUM = 40,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline int api_syscb::syscb_registerCallback(SysCallback *cb, void *param) {
+ int __retval = _call(API_SYSCB_SYSCB_REGISTERCALLBACK, (int)0, cb, param);
+ return __retval;
+}
+
+inline int api_syscb::syscb_deregisterCallback(SysCallback *cb) {
+ int __retval = _call(API_SYSCB_SYSCB_DEREGISTERCALLBACK, (int)0, cb);
+ return __retval;
+}
+
+inline int api_syscb::syscb_issueCallback(int eventtype, int msg, intptr_t param1 , intptr_t param2) {
+ int __retval = _call(API_SYSCB_SYSCB_ISSUECALLBACK, (int)0, eventtype, msg, param1, param2);
+ return __retval;
+}
+
+inline SysCallback *api_syscb::syscb_enum(int eventtype, size_t n)
+{
+ return _call(API_SYSCB_SYSCB_ENUM, (SysCallback *)0, eventtype, n);
+}
+// ----------------------------------------------------------------------------
+
+
+// -- generated code - edit in api_syscbi.h
+
+// {57B7A1B6-700E-44ff-9CB0-70B92BAF3959}
+static const GUID syscbApiServiceGuid =
+{ 0x57b7a1b6, 0x700e, 0x44ff, { 0x9c, 0xb0, 0x70, 0xb9, 0x2b, 0xaf, 0x39, 0x59 } };
+
+extern api_syscb *sysCallbackApi;
+
+#endif // __API_SYSCB_H
diff --git a/Src/Wasabi/api/syscb/api_syscbi.cpp b/Src/Wasabi/api/syscb/api_syscbi.cpp
new file mode 100644
index 00000000..92f0f765
--- /dev/null
+++ b/Src/Wasabi/api/syscb/api_syscbi.cpp
@@ -0,0 +1,35 @@
+#include <precomp.h>
+#ifndef NOCBMGR
+//<?#include "<class data="implementationheader"/>"
+#include "api_syscbi.h"
+//?>
+
+#include <api/api.h>
+//#include <api/syscb/cbmgr.h>
+
+api_syscb *sysCallbackApi = NULL;
+
+int api_syscbI::syscb_registerCallback(SysCallback *cb, void *param) {
+#ifdef WASABI_COMPILE_COMPONENTS
+ WASABI_API_SYSCB->syscb_registerCallback(cb, param, WASABI_API_COMPONENT->getThisComponent());
+#else
+ WASABI_API_SYSCB->syscb_registerCallback(cb, param);
+#endif
+ return 1;
+}
+
+int api_syscbI::syscb_deregisterCallback(SysCallback *cb) {
+#ifdef WASABI_COMPILE_COMPONENTS
+ WASABI_API_SYSCB->syscb_deregisterCallback(cb, WASABI_API_COMPONENT->getThisComponent());
+#else
+ WASABI_API_SYSCB->syscb_deregisterCallback(cb);
+#endif
+ return 1;
+}
+
+int api_syscbI::syscb_issueCallback(int eventtype, int msg, int p1, int p2) {
+ WASABI_API_SYSCB->syscb_issueCallback(eventtype, msg, p1, p2);
+ return 1;
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/api_syscbi.h b/Src/Wasabi/api/syscb/api_syscbi.h
new file mode 100644
index 00000000..be73f739
--- /dev/null
+++ b/Src/Wasabi/api/syscb/api_syscbi.h
@@ -0,0 +1,28 @@
+#ifndef __API_SYSCBI_IMPL_H
+#define __API_SYSCBI_IMPL_H
+
+/*<?<autoheader/>*/
+#include "api_syscb.h"
+#include "api_syscbx.h"
+
+class SysCallback;
+/*?>*/
+
+class api_syscbI : public api_syscbX {
+public:
+ DISPATCH(20) int syscb_registerCallback(SysCallback *cb, void *param = NULL);
+ DISPATCH(10) int syscb_deregisterCallback(SysCallback *cb);
+ DISPATCH(30) int syscb_issueCallback(int eventtype, int msg, intptr_t p1=0, intptr_t p2=0);
+};
+
+/*[interface.footer.h]
+// -- generated code - edit in api_syscbi.h
+
+// {57B7A1B6-700E-44ff-9CB0-70B92BAF3959}
+static const GUID syscbApiServiceGuid =
+{ 0x57b7a1b6, 0x700e, 0x44ff, { 0x9c, 0xb0, 0x70, 0xb9, 0x2b, 0xaf, 0x39, 0x59 } };
+
+extern api_syscb *sysCallbackApi;
+*/
+
+#endif // __API_SYSCBI_IMPL_H
diff --git a/Src/Wasabi/api/syscb/api_syscbx.cpp b/Src/Wasabi/api/syscb/api_syscbx.cpp
new file mode 100644
index 00000000..932a82f6
--- /dev/null
+++ b/Src/Wasabi/api/syscb/api_syscbx.cpp
@@ -0,0 +1,22 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:14 2003]
+//
+// File : api_syscbx.cpp
+// Class : api_syscb
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "api_syscbx.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS api_syscbX
+START_DISPATCH;
+ CB(API_SYSCB_SYSCB_REGISTERCALLBACK, syscb_registerCallback);
+ CB(API_SYSCB_SYSCB_DEREGISTERCALLBACK, syscb_deregisterCallback);
+ CB(API_SYSCB_SYSCB_ISSUECALLBACK, syscb_issueCallback);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/syscb/api_syscbx.h b/Src/Wasabi/api/syscb/api_syscbx.h
new file mode 100644
index 00000000..9c060d43
--- /dev/null
+++ b/Src/Wasabi/api/syscb/api_syscbx.h
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:14 2003]
+//
+// File : api_syscbx.h
+// Class : api_syscb
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __API_SYSCBX_H
+#define __API_SYSCBX_H
+
+#include "api_syscb.h"
+
+class SysCallback;
+
+
+
+// ----------------------------------------------------------------------------
+
+class api_syscbX : public api_syscb {
+ protected:
+ api_syscbX() {}
+ public:
+ virtual int syscb_registerCallback(SysCallback *cb, void *param = NULL)=0;
+ virtual int syscb_deregisterCallback(SysCallback *cb)=0;
+ virtual int syscb_issueCallback(int eventtype, int msg, intptr_t p1=0, intptr_t p2=0)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __API_SYSCBX_H
diff --git a/Src/Wasabi/api/syscb/callbacks/authcb.h b/Src/Wasabi/api/syscb/callbacks/authcb.h
new file mode 100644
index 00000000..b3e7cae1
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/authcb.h
@@ -0,0 +1,20 @@
+#ifndef __WASABI_AUTHCB_H
+#define __WASABI_AUTHCB_H
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+#pragma once
+#endif
+
+#include <api/syscb/callbacks/syscb.h>
+
+namespace AuthCallback
+{
+ enum
+ {
+ CREDENTIALS_CHANGED=10, //param1 = (api_auth*)auth; param2 = (const GUID*)realm; no return value.
+ CREDENTIALS_ABOUTTOCHANGE=20, //param1 = (api_auth*)auth; param2 = (const GUID*)realm; no return value.
+
+ };
+};
+
+#endif //__WASABI_AUTHCB_H
diff --git a/Src/Wasabi/api/syscb/callbacks/browsercb.cpp b/Src/Wasabi/api/syscb/callbacks/browsercb.cpp
new file mode 100644
index 00000000..e722d357
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/browsercb.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "browsercb.h" \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/browsercb.h b/Src/Wasabi/api/syscb/callbacks/browsercb.h
new file mode 100644
index 00000000..55c876a8
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/browsercb.h
@@ -0,0 +1,11 @@
+#ifndef __WASABI_BROWSERCB_H
+#define __WASABI_BROWSERCB_H
+
+#include <api/syscb/callbacks/syscb.h>
+
+namespace BrowserCallback {
+ enum {
+ ONOPENURL=10,
+ };
+};
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/browsercbi.h b/Src/Wasabi/api/syscb/callbacks/browsercbi.h
new file mode 100644
index 00000000..843ddb67
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/browsercbi.h
@@ -0,0 +1,32 @@
+#ifndef NULLSOFT_WASABI_BROWSERCBI_H
+#define NULLSOFT_WASABI_BROWSERCBI_H
+
+#include "syscbi.h"
+#include "browsercb.h"
+
+class waServiceFactory;
+#define SVCCALLBACK_PARENT SysCallbackI
+class BrowserCallbackI : public SVCCALLBACK_PARENT {
+protected:
+ BrowserCallbackI() { }
+
+public:
+ // set *override = true to prevent the URL from being opened
+ // leave it alone otherwise (in case someone else wanted to override it)
+ virtual void browsercb_onOpenURL(wchar_t *url, bool *override) { }
+
+private:
+ virtual FOURCC syscb_getEventType() { return SysCallback::BROWSER; }
+
+ virtual int syscb_notify(int msg, intptr_t param1, intptr_t param2) {
+ switch (msg) {
+ case BrowserCallback::ONOPENURL:
+ browsercb_onOpenURL(reinterpret_cast<wchar_t*>(param1), reinterpret_cast<bool *>(param2));
+ break;
+ default: return 0;
+ }
+ return 1;
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/consolecb.cpp b/Src/Wasabi/api/syscb/callbacks/consolecb.cpp
new file mode 100644
index 00000000..a91c33b9
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/consolecb.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+#if 0
+#include "consolecb.h"
+
+using namespace ConsoleCallback;
+
+int ConsoleCallbackI::syscb_notify(int msg, int param1, int param2) {
+ switch (msg) {
+ case DEBUGMESSAGE:
+ return consolecb_outputString(param1, reinterpret_cast<const char *>(param2));
+ }
+ return 0;
+}
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/consolecb.h b/Src/Wasabi/api/syscb/callbacks/consolecb.h
new file mode 100644
index 00000000..9f706c23
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/consolecb.h
@@ -0,0 +1,24 @@
+#ifndef _CONSOLECB_H
+#define _CONSOLECB_H
+
+#include <api/syscb/callbacks/syscbi.h>
+
+namespace ConsoleCallback {
+ enum {
+ DEBUGMESSAGE=10,
+ };
+};
+/*
+#define CONSOLECALLBACKI_PARENT SysCallbackI
+
+class ConsoleCallbackI : public CONSOLECALLBACKI_PARENT {
+public:
+ virtual FOURCC syscb_getEventType() { return SysCallback::CONSOLE; }
+
+protected:
+ virtual int consolecb_outputString(int severity, const char *string)=0;
+private:
+ virtual int syscb_notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+};
+*/
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/corecb.cpp b/Src/Wasabi/api/syscb/callbacks/corecb.cpp
new file mode 100644
index 00000000..160715f2
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/corecb.cpp
@@ -0,0 +1,79 @@
+#include <precomp.h>
+#include "corecbi.h"
+
+#define CBCLASS CoreCallbackI
+START_DISPATCH;
+ CB(CCB_NOTIFY, ccb_notify);
+END_DISPATCH;
+
+int CoreCallbackI::ccb_notify(int msg, intptr_t param1, intptr_t param2) {
+ ReentryFilter f(&filter, msg);
+ if (f.mustLeave()) return 0;
+ switch (msg) {
+ case STARTED:
+ return corecb_onStarted();
+ case STOPPED:
+ return corecb_onStopped();
+ case PAUSED:
+ return corecb_onPaused();
+ case UNPAUSED:
+ return corecb_onUnpaused();
+ case SEEKED:
+ return corecb_onSeeked(param1);
+ case VOLCHANGE:
+ return corecb_onVolumeChange(param1);
+ case PANCHANGE:
+ return corecb_onPanChange(param1);
+ case EQSTATUSCHANGE:
+ return corecb_onEQStatusChange(param1);
+ case EQPREAMPCHANGE:
+ return corecb_onEQPreampChange(param1);
+ case EQBANDCHANGE:
+ return corecb_onEQBandChange(param1, param2);
+ case EQFREQCHANGE:
+ return corecb_onEQFreqChange(param1);
+ case EQAUTOCHANGE:
+ return corecb_onEQAutoChange(param1);
+ case STATUSMSG:
+ return corecb_onStatusMsg((const wchar_t *)param1);
+ case WARNINGMSG:
+ return corecb_onWarningMsg((const wchar_t *)param1);
+ case ERRORMSG:
+ return corecb_onErrorMsg((const wchar_t *)param1);
+ case TITLECHANGE:
+ return corecb_onTitleChange((const wchar_t *)param1);
+ case TITLE2CHANGE:
+ return corecb_onTitle2Change((const wchar_t *)param1);
+ case INFOCHANGE:
+ return corecb_onInfoChange((const wchar_t *)param1);
+ case URLCHANGE:
+ return corecb_onUrlChange((const wchar_t *)param1);
+ case LENGTHCHANGE:
+ return corecb_onLengthChange(param1);
+ case NEXTFILE:
+ return corecb_onNextFile();
+ case NEEDNEXTFILE:
+ return corecb_onNeedNextFile(param1);
+ case SETNEXTFILE:
+ return corecb_onSetNextFile((const wchar_t *)param1);
+ case ERROROCCURED:
+ return corecb_onErrorOccured(param1, (const wchar_t *)param2);
+ case ABORTCURRENTSONG:
+ return corecb_onAbortCurrentSong();
+ case ENDOFDECODE:
+ return corecb_onEndOfDecode();
+ case ONFILECOMPLETE:
+ return corecb_onFileComplete((const wchar_t *)param1);
+ case CONVERTERSCHAINREBUILT:
+ return corecb_onConvertersChainRebuilt();
+ case MEDIAFAMILYCHANGE:
+ return corecb_onMediaFamilyChange((const wchar_t *)param1);
+ case BITRATECHANGE:
+ return corecb_onBitrateChange(param1);
+ case SAMPLERATECHANGE:
+ return corecb_onSampleRateChange(param1);
+ case CHANNELSCHANGE:
+ return corecb_onChannelsChange(param1);
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/corecb.h b/Src/Wasabi/api/syscb/callbacks/corecb.h
new file mode 100644
index 00000000..d96bc506
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/corecb.h
@@ -0,0 +1,71 @@
+#ifndef _CORECB_H
+#define _CORECB_H
+
+#include <bfc/dispatch.h>
+
+// don't derive from this
+class NOVTABLE CoreCallback : public Dispatchable
+{
+protected:
+ CoreCallback() {}
+
+public:
+ int ccb_notify(int msg, intptr_t param1=0, intptr_t param2=0) {
+ return _call(CCB_NOTIFY, 0, msg, param1, param2);
+ }
+
+ // class Dispatchable codes
+ enum {
+ CCB_NOTIFY = 100,
+ };
+
+ // various ccb_notify notifications. these are *not* the Dispatchable codes
+ enum {
+ REGISTER = 100,
+ DEREGISTER = 200,
+ NEXTFILE = 300,
+
+ STARTED = 500,
+ STOPPED = 600,
+ PAUSED = 700,
+ UNPAUSED = 800,
+ SEEKED = 900,
+
+ VOLCHANGE = 2000,
+ EQSTATUSCHANGE = 2100,
+ EQPREAMPCHANGE = 2200,
+ EQBANDCHANGE = 2300,
+ EQFREQCHANGE = 2310,
+ EQAUTOCHANGE = 2400,
+ PANCHANGE = 2500,
+
+ STATUSMSG = 3000,
+ WARNINGMSG = 3100,
+ ERRORMSG = 3200,
+ ERROROCCURED = 3300,
+
+ TITLECHANGE = 4000,
+ TITLE2CHANGE = 4100,
+ INFOCHANGE = 4200,
+ SAMPLERATECHANGE = 4210,
+ BITRATECHANGE = 4220,
+ CHANNELSCHANGE = 4230,
+ URLCHANGE = 4300,
+ LENGTHCHANGE = 4400,
+
+ NEEDNEXTFILE = 5100,
+ SETNEXTFILE = 5200,
+
+ ABORTCURRENTSONG= 6000,
+
+ ENDOFDECODE = 7000,
+
+ ONFILECOMPLETE = 8000,
+
+ CONVERTERSCHAINREBUILT = 9000,
+
+ MEDIAFAMILYCHANGE = 10000,
+ };
+};
+
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/corecbi.h b/Src/Wasabi/api/syscb/callbacks/corecbi.h
new file mode 100644
index 00000000..97c903a6
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/corecbi.h
@@ -0,0 +1,67 @@
+#ifndef __WASABI_CORECBI_H
+#define __WASABI_CORECBI_H
+
+#include <bfc/wasabi_std.h>
+#include <api/syscb/callbacks/corecb.h>
+#include <bfc/reentryfilter.h>
+
+// this class does NOT automatically deregister itself when you destruct it
+// that is up to you, and obviously, if you fail to do so, you'll crash the
+// whole app. and they'll all laugh at you. see class CoreHandle
+class NOVTABLE CoreCallbackI : public CoreCallback {
+protected:
+ CoreCallbackI() { } // no instantiating this on its own
+
+public:
+ virtual int corecb_onStarted() { return 0; }
+ virtual int corecb_onStopped() { return 0; }
+ virtual int corecb_onPaused() { return 0; }
+ virtual int corecb_onUnpaused() { return 0; }
+ virtual int corecb_onSeeked(int newpos) { return 0; }
+
+ virtual int corecb_onVolumeChange(int newvol) { return 0; }
+ virtual int corecb_onPanChange(int newpan) { return 0; }
+
+ virtual int corecb_onEQStatusChange(int newval) { return 0; }
+ virtual int corecb_onEQPreampChange(int newval) { return 0; }
+ virtual int corecb_onEQBandChange(int band, int newval) { return 0; }
+ virtual int corecb_onEQFreqChange(int newval) { return 0; }
+ virtual int corecb_onEQAutoChange(int newval) { return 0; }
+
+ virtual int corecb_onStatusMsg(const wchar_t *text) { return 0; }
+ virtual int corecb_onWarningMsg(const wchar_t *text) { return 0; }
+ virtual int corecb_onErrorMsg(const wchar_t *text) { return 0; }
+
+ virtual int corecb_onTitleChange(const wchar_t *title) { return 0; }
+ virtual int corecb_onTitle2Change(const wchar_t *title2) { return 0; }
+ virtual int corecb_onInfoChange(const wchar_t *info) { return 0; }
+ virtual int corecb_onBitrateChange(int kbps) { return 0; }
+ virtual int corecb_onSampleRateChange(int khz) { return 0; }
+ virtual int corecb_onChannelsChange(int nch) { return 0; }
+ virtual int corecb_onUrlChange(const wchar_t *url) { return 0; }
+ virtual int corecb_onLengthChange(int newlength) { return 0; }
+
+ virtual int corecb_onNextFile() { return 0; }
+ virtual int corecb_onNeedNextFile(int fileid) { return 0; }
+ virtual int corecb_onSetNextFile(const wchar_t *playstring) { return 0; }
+
+ virtual int corecb_onErrorOccured(int severity, const wchar_t *text) { return 0; }
+
+ // return 1 in this callback to make the current callback chain to abort
+ virtual int corecb_onAbortCurrentSong() { return 0; }
+
+ virtual int corecb_onEndOfDecode() { return 0; }
+
+ virtual int corecb_onFileComplete(const wchar_t *playstring) { return 0; }
+
+ virtual int corecb_onConvertersChainRebuilt() { return 0; }
+
+ virtual int corecb_onMediaFamilyChange(const wchar_t *newfamily) { return 0; }
+
+ virtual int ccb_notify(int msg, intptr_t param1=0, intptr_t param2=0);
+protected:
+ RECVS_DISPATCH;
+ ReentryFilterObject filter;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/gccb.h b/Src/Wasabi/api/syscb/callbacks/gccb.h
new file mode 100644
index 00000000..1e408792
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/gccb.h
@@ -0,0 +1,31 @@
+#ifndef _GCCB_H
+#define _GCCB_H
+
+#include "syscbi.h"
+
+namespace GarbageCollectCallback {
+ enum {
+ GARBAGECOLLECT=1,
+ };
+};
+
+#define GARBAGECOLLECTCALLBACK_PARENT SysCallbackI
+class GarbageCollectCallbackI : public GARBAGECOLLECTCALLBACK_PARENT {
+protected:
+ GarbageCollectCallbackI() {}
+
+public:
+ virtual int gccb_onGarbageCollect() { return 0; }
+
+private:
+ virtual FOURCC syscb_getEventType() { return SysCallback::GC; }
+ virtual int syscb_notify(int msg, intptr_t param1=0, intptr_t param2=0) {
+ switch (msg) {
+ case GarbageCollectCallback::GARBAGECOLLECT:
+ return gccb_onGarbageCollect();
+ }
+ return 0;
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/metacb.h b/Src/Wasabi/api/syscb/callbacks/metacb.h
new file mode 100644
index 00000000..93469d0a
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/metacb.h
@@ -0,0 +1,41 @@
+#pragma once
+#include <api/syscb/callbacks/syscbi.h>
+
+namespace MetadataCallback {
+ enum {
+ FILE_UPDATED = 10,
+ ART_UPDATED = 20,
+ FILE_MAY_UPDATE = 30,
+ };
+};
+
+#define METADATACALLBACK_PARENT SysCallbackI
+class MetadataCallbackI : public METADATACALLBACK_PARENT
+{
+protected:
+ MetadataCallbackI() { }
+
+public:
+ virtual void metacb_FileUpdated(const wchar_t *filename) { }
+ virtual void metacb_ArtUpdated(const wchar_t *filename) { }
+ virtual void metacb_FileMayUpdate(const wchar_t *filename) { }
+
+private:
+ virtual FOURCC syscb_getEventType() { return SysCallback::META; }
+
+ virtual int syscb_notify(int msg, intptr_t param1, intptr_t param2) {
+ switch (msg) {
+ case MetadataCallback::FILE_UPDATED:
+ metacb_FileUpdated((const wchar_t *)param1);
+ break;
+ case MetadataCallback::ART_UPDATED:
+ metacb_ArtUpdated((const wchar_t *)param1);
+ break;
+ case MetadataCallback::FILE_MAY_UPDATE:
+ metacb_FileMayUpdate((const wchar_t *)param1);
+ break;
+ default: return 0;
+ }
+ return 1;
+ }
+}; \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/playlistcb.cpp b/Src/Wasabi/api/syscb/callbacks/playlistcb.cpp
new file mode 100644
index 00000000..13b3d614
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/playlistcb.cpp
@@ -0,0 +1,10 @@
+#include "playlistcb.h"
+
+int PlaylistCallbackI::syscb_notify(int msg, intptr_t param1, intptr_t param2)
+{
+ switch (msg) {
+ case api_playlists::PLAYLIST_ADDED: return playlistcb_added(static_cast<size_t>(param1));
+ case api_playlists::PLAYLIST_SAVED: return playlistcb_saved(static_cast<size_t>(param1));
+ }
+ return 0;
+}
diff --git a/Src/Wasabi/api/syscb/callbacks/playlistcb.h b/Src/Wasabi/api/syscb/callbacks/playlistcb.h
new file mode 100644
index 00000000..e0f261c8
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/playlistcb.h
@@ -0,0 +1,26 @@
+#ifndef NULLSOFT_AGAVE_PLAYLISTCB_H
+#define NULLSOFT_AGAVE_PLAYLISTCB_H
+
+#include "../playlist/api_playlists.h"
+
+#include "api/syscb/callbacks/syscbi.h"
+
+
+#define PLAYLISTCALLBACKI_PARENT SysCallbackI
+class PlaylistCallbackI : public PLAYLISTCALLBACKI_PARENT
+{
+public:
+ virtual FOURCC syscb_getEventType() { return api_playlists::SYSCALLBACK; }
+
+protected:
+ // override these
+ virtual int playlistcb_added( size_t index ) { return 0; }
+ virtual int playlistcb_saved( size_t index ) { return 0; }
+
+private:
+ virtual int syscb_notify( int msg, intptr_t param1 = 0, intptr_t param2 = 0 );
+};
+
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/runlevelcb.h b/Src/Wasabi/api/syscb/callbacks/runlevelcb.h
new file mode 100644
index 00000000..4ead8d5e
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/runlevelcb.h
@@ -0,0 +1,39 @@
+#ifndef _RUNLEVELCB_H
+#define _RUNLEVELCB_H
+
+#include <api/syscb/callbacks/syscbi.h>
+#include <api/service/service.h>
+
+#define RUNLEVELCALLBACKI_PARENT SysCallbackI
+class RunlevelCallbackI : public RUNLEVELCALLBACKI_PARENT {
+public:
+ virtual FOURCC syscb_getEventType() { return SysCallback::RUNLEVEL; }
+
+ // override these
+ virtual void runlevelcb_onStartup() {}
+ virtual void runlevelcb_onAppRunning() {}
+ virtual void runlevelcb_onShutdown() {}
+ virtual void runlevelcb_onBeforeShutdown() {}
+
+private:
+ virtual int syscb_notify(int msg, intptr_t param1=0, intptr_t param2=0) {
+ switch (msg) {
+ case SvcNotify::ONSTARTUP:
+ runlevelcb_onStartup();
+ break;
+ case SvcNotify::ONAPPRUNNING:
+ runlevelcb_onAppRunning();
+ break;
+ case SvcNotify::ONSHUTDOWN:
+ runlevelcb_onShutdown();
+ break;
+ case SvcNotify::ONBEFORESHUTDOWN:
+ runlevelcb_onBeforeShutdown();
+ break;
+ default: return 0;
+ }
+ return 1;
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/skincb.cpp b/Src/Wasabi/api/syscb/callbacks/skincb.cpp
new file mode 100644
index 00000000..df2073e0
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/skincb.cpp
@@ -0,0 +1,20 @@
+#include <precomp.h>
+#include "skincb.h"
+int SkinCallbackI::syscb_notify(int msg, intptr_t param1, intptr_t param2) {
+ switch (msg) {
+ case SkinCallback::UNLOADING: return skincb_onUnloading();
+ case SkinCallback::RESET: return skincb_onReset();
+ case SkinCallback::RELOAD: return skincb_onReload();
+ case SkinCallback::BEFORELOADINGELEMENTS: return skincb_onBeforeLoadingElements();
+ case SkinCallback::GUILOADED: return skincb_onGuiLoaded();
+ case SkinCallback::LOADED: return skincb_onLoaded();
+ case SkinCallback::COLORTHEMECHANGED: return skincb_onColorThemeChanged(WASABI_API_SKIN->colortheme_getColorSet());
+ case SkinCallback::COLORTHEMESLISTCHANGED: return skincb_onColorThemesListChanged();
+ case SkinCallback::CHECKPREVENTSWITCH: {
+ int r = skincb_onCheckPreventSwitch((const wchar_t *)param1);
+ if (r && param2)
+ *(int *)param2 = r;
+ }
+ }
+ return 0;
+}
diff --git a/Src/Wasabi/api/syscb/callbacks/skincb.h b/Src/Wasabi/api/syscb/callbacks/skincb.h
new file mode 100644
index 00000000..41df3aa7
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/skincb.h
@@ -0,0 +1,41 @@
+#ifndef _SKINCB_H
+#define _SKINCB_H
+
+#include <api/syscb/callbacks/syscbi.h>
+
+namespace SkinCallback {
+ enum {
+ UNLOADING=100, // beginning, haven't killed anything yet
+ RESET=200, // skin is gone
+ RELOAD=300, // stuff is loading
+ BEFORELOADINGELEMENTS=350,
+ GUILOADED=400, // skin gui objects loaded from xml
+ LOADED=500, // all done, new skin in place
+ CHECKPREVENTSWITCH=600, // we're about to switch skin, wanna abort ? return 1 if so
+ COLORTHEMECHANGED=700, // color theme has been changed, trap this if you're not using automaticly themed widgets
+ COLORTHEMESLISTCHANGED=710, // color theme list has been modified, trap this if you're showing a list of the colorthemes and you want to mirror changes
+ };
+};
+
+#define SKINCALLBACKI_PARENT SysCallbackI
+class SkinCallbackI : public SKINCALLBACKI_PARENT {
+public:
+ virtual FOURCC syscb_getEventType() { return SysCallback::SKINCB; }
+
+protected:
+ // override these
+ virtual int skincb_onUnloading() { return 0; }
+ virtual int skincb_onReset() { return 0; }
+ virtual int skincb_onReload() { return 0; }
+ virtual int skincb_onBeforeLoadingElements() { return 0; }
+ virtual int skincb_onGuiLoaded() { return 0; }
+ virtual int skincb_onLoaded() { return 0; }
+ virtual int skincb_onCheckPreventSwitch(const wchar_t *skinname) { return 0; }
+ virtual int skincb_onColorThemeChanged(const wchar_t *newcolortheme) { return 0; }
+ virtual int skincb_onColorThemesListChanged() { return 0; }
+
+private:
+ virtual int syscb_notify(int msg, intptr_t param1=0, intptr_t param2=0);
+};
+
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/svccb.h b/Src/Wasabi/api/syscb/callbacks/svccb.h
new file mode 100644
index 00000000..36488a49
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/svccb.h
@@ -0,0 +1,12 @@
+#ifndef _SVCCB_H
+#define _SVCCB_H
+
+#include <api/syscb/callbacks/syscb.h>
+
+namespace SvcCallback {
+ enum {
+ ONREGISTER=10,
+ ONDEREGISTER=20,
+ };
+};
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/svccbi.h b/Src/Wasabi/api/syscb/callbacks/svccbi.h
new file mode 100644
index 00000000..a3fb79b9
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/svccbi.h
@@ -0,0 +1,34 @@
+#ifndef NULLSOFT_WASABI_SVCCBI_H
+#define NULLSOFT_WASABI_SVCCBI_H
+
+#include "syscbi.h"
+#include "svccb.h"
+
+class waServiceFactory;
+#define SVCCALLBACK_PARENT SysCallbackI
+class SvcCallbackI : public SVCCALLBACK_PARENT {
+protected:
+ SvcCallbackI() { }
+
+public:
+ virtual void svccb_onSvcRegister(FOURCC type, waServiceFactory *svc) { }
+ virtual void svccb_onSvcDeregister(FOURCC type, waServiceFactory *svc) { }
+
+private:
+ virtual FOURCC syscb_getEventType() { return SysCallback::SERVICE; }
+
+ virtual int syscb_notify(int msg, intptr_t param1, intptr_t param2) {
+ switch (msg) {
+ case SvcCallback::ONREGISTER:
+ svccb_onSvcRegister((FOURCC)param1, reinterpret_cast<waServiceFactory*>(param1));
+ break;
+ case SvcCallback::ONDEREGISTER:
+ svccb_onSvcRegister((FOURCC)param1, reinterpret_cast<waServiceFactory*>(param1));
+ break;
+ default: return 0;
+ }
+ return 1;
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/callbacks/syscb.cpp b/Src/Wasabi/api/syscb/callbacks/syscb.cpp
new file mode 100644
index 00000000..3ab8b878
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/syscb.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:36 2003]
+//
+// File : syscb.cpp
+// Class : SysCallback
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "syscb.h"
+
+
diff --git a/Src/Wasabi/api/syscb/callbacks/syscb.h b/Src/Wasabi/api/syscb/callbacks/syscb.h
new file mode 100644
index 00000000..1347ff6e
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/syscb.h
@@ -0,0 +1,73 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:36 2003]
+//
+// File : syscb.h
+// Class : SysCallback
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __SYSCALLBACK_H
+#define __SYSCALLBACK_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+//#include <bfc/common.h>
+#include <bfc/std_mkncc.h>
+#include <stddef.h>
+
+// ----------------------------------------------------------------------------
+
+class SysCallback: public Dispatchable {
+ protected:
+ SysCallback() {}
+ ~SysCallback() {}
+ public:
+
+public:
+// -- begin generated - edit in syscbi.h
+enum { // event types
+ NONE = 0,
+ RUNLEVEL = MK4CC('r','u','n','l'), // system runlevel
+ CONSOLE = MK3CC('c','o','n'), // debug messages
+ SKINCB = MK4CC('s','k','i','n'), // skin unloading/loading
+ DB = MK2CC('d','b'), // database change messages
+ WINDOW = MK3CC('w','n','d'), // window events
+ GC = MK2CC('g','c'), // garbage collection event
+ POPUPEXIT = MK4CC('p','o','p','x'), // popup exit
+ CMDLINE = MK4CC('c','m','d','l'), // command line sent (possibly from outside)
+ SYSMEM = MK4CC('s','y','s','m'), // api->sysMalloc/sysFree
+ SERVICE = MK3CC('s','v','c'),
+ BROWSER = MK3CC('u','r','l'), // browser open requests
+ META = MK4CC('m','e','t','a'), // metadata changes
+ AUTH = MK4CC('a','u','t','h'), // credentials change
+};
+// -- end generated
+
+ public:
+ FOURCC getEventType();
+ int notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+
+ protected:
+ enum {
+ SYSCALLBACK_GETEVENTTYPE = 101,
+ SYSCALLBACK_NOTIFY = 200,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline FOURCC SysCallback::getEventType() {
+ FOURCC __retval = _call(SYSCALLBACK_GETEVENTTYPE, (FOURCC)NULL);
+ return __retval;
+}
+#pragma warning(push)
+#pragma warning(disable:4244)
+inline int SysCallback::notify(int msg, intptr_t param1, intptr_t param2) {
+ int __retval = _call(SYSCALLBACK_NOTIFY, (int)0, msg, param1, param2);
+ return __retval;
+}
+#pragma warning(pop)
+
+// ----------------------------------------------------------------------------
+
+#endif // __SYSCALLBACK_H
diff --git a/Src/Wasabi/api/syscb/callbacks/syscbi.cpp b/Src/Wasabi/api/syscb/callbacks/syscbi.cpp
new file mode 100644
index 00000000..a684fa22
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/syscbi.cpp
@@ -0,0 +1,4 @@
+#include "precomp.h"
+#include "syscbi.h"
+
+
diff --git a/Src/Wasabi/api/syscb/callbacks/syscbi.h b/Src/Wasabi/api/syscb/callbacks/syscbi.h
new file mode 100644
index 00000000..e0067c43
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/syscbi.h
@@ -0,0 +1,46 @@
+#ifndef _SYSCBI_H
+#define _SYSCBI_H
+
+//<?<autoheader/>
+#include "syscb.h"
+#include "syscbx.h"
+
+//?>
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/platform.h>
+//#include <bfc/common.h>
+
+//derive from this one (see skincb.h for a good example)
+class SysCallbackI : public SysCallbackX {
+public:
+ DISPATCH(101) FOURCC getEventType() { return syscb_getEventType(); }
+ DISPATCH(200) int notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0) { return syscb_notify(msg, param1, param2); }
+
+protected:
+ NODISPATCH virtual FOURCC syscb_getEventType()=0;
+ NODISPATCH virtual int syscb_notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0)=0;
+
+// This is where you should edit the enum block
+/*[interface]
+public:
+// -- begin generated - edit in syscbi.h
+enum { // event types
+ NONE = 0,
+ RUNLEVEL = MK4CC('r','u','n','l'), // system runlevel
+ CONSOLE = MK3CC('c','o','n'), // debug messages
+ SKINCB = MK4CC('s','k','i','n'), // skin unloading/loading
+ DB = MK2CC('d','b'), // database change messages
+ WINDOW = MK3CC('w','n','d'), // window events
+ GC = MK2CC('g','c'), // garbage collection event
+ POPUPEXIT = MK4CC('p','o','p','x'), // popup exit
+ CMDLINE = MK4CC('c','m','d','l'), // command line sent (possibly from outside)
+ SYSMEM = MK4CC('s','y','s','m'), // api->sysMalloc/sysFree
+ SERVICE = MK3CC('s','v','c'),
+};
+// -- end generated
+*/
+
+};
+
+#endif // _SYSCB_I
diff --git a/Src/Wasabi/api/syscb/callbacks/syscbx.cpp b/Src/Wasabi/api/syscb/callbacks/syscbx.cpp
new file mode 100644
index 00000000..fe99c7d4
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/syscbx.cpp
@@ -0,0 +1,21 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:36 2003]
+//
+// File : syscbx.cpp
+// Class : SysCallback
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include "precomp.h"
+
+#include "syscbx.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS SysCallbackX
+START_DISPATCH;
+ CB(SYSCALLBACK_GETEVENTTYPE, getEventType);
+ CB(SYSCALLBACK_NOTIFY, notify);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/syscb/callbacks/syscbx.h b/Src/Wasabi/api/syscb/callbacks/syscbx.h
new file mode 100644
index 00000000..fbff0e72
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/syscbx.h
@@ -0,0 +1,30 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:58:36 2003]
+//
+// File : syscbx.h
+// Class : SysCallback
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __SYSCALLBACKX_H
+#define __SYSCALLBACKX_H
+
+#include "syscb.h"
+
+
+
+
+// ----------------------------------------------------------------------------
+
+class SysCallbackX : public SysCallback {
+ protected:
+ SysCallbackX() {}
+ public:
+ virtual FOURCC getEventType()=0;
+ virtual int notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __SYSCALLBACKX_H
diff --git a/Src/Wasabi/api/syscb/callbacks/sysmemcb.h b/Src/Wasabi/api/syscb/callbacks/sysmemcb.h
new file mode 100644
index 00000000..a060cb90
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/sysmemcb.h
@@ -0,0 +1,53 @@
+#ifndef _SYSMEMCB_H
+#define _SYSMEMCB_H
+
+
+
+namespace SysMemCallback {
+ enum {
+ ONMALLOC=10,
+ ONFREE=20,
+ ONREALLOC=30,
+ ONCHANGE=40,
+ };
+};
+
+
+#include <api/syscb/callbacks/syscbi.h>
+
+#define SYSMEMCALLBACK_PARENT SysCallbackI
+class SysMemCallbackI : public SYSMEMCALLBACK_PARENT {
+protected:
+ SysMemCallbackI() { }
+
+public:
+ virtual void sysmem_onMalloc(void *memory, int size)=0;
+ virtual void sysmem_onFree(void *memory)=0;
+ virtual void sysmem_onRealloc(void *prev_memory, void *new_memory, int new_size)=0;
+ virtual void sysmem_onChange(void *memory)=0;
+
+private:
+ virtual FOURCC syscb_getEventType() { return SysCallback::SYSMEM; }
+ virtual int syscb_notify(int msg, intptr_t param1=0, intptr_t param2=0) {
+ switch (msg) {
+ case SysMemCallback::ONMALLOC:
+ sysmem_onMalloc((void *)param1, param2);
+ break;
+ case SysMemCallback::ONFREE:
+ sysmem_onFree((void *)param1);
+ break;
+ case SysMemCallback::ONREALLOC: {
+ void **ptrs = (void **)param1;
+ sysmem_onRealloc(ptrs[0], ptrs[1], param2);
+ }
+ break;
+ case SysMemCallback::ONCHANGE:
+ sysmem_onChange((void *)param1);
+ break;
+ default: return 0;
+ }
+ return 1;
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/syscb/callbacks/wndcb.cpp b/Src/Wasabi/api/syscb/callbacks/wndcb.cpp
new file mode 100644
index 00000000..69a95bce
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/wndcb.cpp
@@ -0,0 +1,36 @@
+#include "precomp.h"
+#include "wndcb.h"
+
+using namespace WndCallback;
+
+int WndCallbackI::syscb_notify(int msg, intptr_t param1, intptr_t param2)
+{
+ switch (msg)
+ {
+ case SHOWWINDOW:
+ {
+ WndInfo *i = reinterpret_cast<WndInfo *>((void *)param1);
+ if (!i) return 0;
+ return onShowWindow(i->c, i->guid, i->groupid);
+ }
+ case HIDEWINDOW:
+ {
+ WndInfo *i = reinterpret_cast<WndInfo *>((void *)param1);
+ if (!i) return 0;
+ return onHideWindow(i->c, i->guid, i->groupid);
+ }
+ case GROUPCHANGE:
+ {
+ WndInfo *i = reinterpret_cast<WndInfo *>((void *)param1);
+ if (!i) return 0;
+ return onGroupChange(i->groupid);
+ }
+ case TYPECHANGE:
+ {
+ WndInfo *i = reinterpret_cast<WndInfo *>((void *)param1);
+ if (!i) return 0;
+ return onTypeChange(i->wndtype);
+ }
+ }
+ return 0;
+}
diff --git a/Src/Wasabi/api/syscb/callbacks/wndcb.h b/Src/Wasabi/api/syscb/callbacks/wndcb.h
new file mode 100644
index 00000000..752c5c09
--- /dev/null
+++ b/Src/Wasabi/api/syscb/callbacks/wndcb.h
@@ -0,0 +1,43 @@
+#ifndef _WNDCB_H
+#define _WNDCB_H
+
+#include <api/syscb/callbacks/syscbi.h>
+#include <bfc/common.h>
+
+class Container;
+class ifc_window;
+
+class WndInfo {
+ public:
+ GUID guid;
+ const wchar_t *groupid;
+ const wchar_t *wndtype;
+ Container *c;
+};
+
+namespace WndCallback {
+ enum {
+ SHOWWINDOW=10,
+ HIDEWINDOW=20,
+ GROUPCHANGE=30,
+ TYPECHANGE=40,
+ };
+};
+
+#define WNDCALLBACKI_PARENT SysCallbackI
+class WndCallbackI : public WNDCALLBACKI_PARENT {
+public:
+ virtual FOURCC syscb_getEventType() { return SysCallback::WINDOW; }
+
+protected:
+ virtual int onShowWindow(Container *c, GUID guid, const wchar_t *groupid) { return 0; }
+ virtual int onHideWindow(Container *c, GUID guid, const wchar_t *groupid) { return 0; }
+ virtual int onGroupChange(const wchar_t *groupid) { return 0; }
+ virtual int onTypeChange(const wchar_t *type) { return 0; }
+
+private:
+ virtual int syscb_notify(int msg, intptr_t param1=0, intptr_t param2=0);
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/syscb/cbmgr.cpp b/Src/Wasabi/api/syscb/cbmgr.cpp
new file mode 100644
index 00000000..93633693
--- /dev/null
+++ b/Src/Wasabi/api/syscb/cbmgr.cpp
@@ -0,0 +1,41 @@
+#include <precomp.h>
+#ifndef NOCBMGR
+#include "cbmgr.h"
+#include <api/syscb/callbacks/syscb.h>
+
+#include <bfc/multimap.h>
+
+static MultiMap<int, SysCallback> cblist;
+static PtrList<SysCallback> delete_list;
+static int reentry_counter=0;
+
+void CallbackManager::registerCallback(SysCallback *cb, void *param, WaComponent *owner) {
+ cblist.multiAddItem(cb->getEventType(), cb, TRUE);
+}
+
+void CallbackManager::deregisterCallback(SysCallback *cb, WaComponent *owner) {
+ delete_list.addItem(cb);
+ cblist.multiDelItem(cb->getEventType(), cb); // remove ref
+}
+
+void CallbackManager::issueCallback(int eventtype, int msg, int param1, int param2) {
+ ASSERT(reentry_counter >= 0);
+ reentry_counter++;
+ const PtrList<SysCallback> *mlist = cblist.getListForIndex(eventtype);
+ if (mlist != NULL) {
+ foreach(mlist)
+ SysCallback *cb = mlist->getfor();
+ ASSERT(cb != NULL);
+ if (!delete_list.haveItem(cb))
+ cb->notify(msg, param1, param2);
+ endfor
+ }
+ reentry_counter--;
+ if (reentry_counter == 0)
+ delete_list.removeAll();
+}
+
+int CallbackManager::getNumCallbacks() {
+ return cblist.getNumItems();
+}
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/syscb/cbmgr.h b/Src/Wasabi/api/syscb/cbmgr.h
new file mode 100644
index 00000000..54efdd75
--- /dev/null
+++ b/Src/Wasabi/api/syscb/cbmgr.h
@@ -0,0 +1,18 @@
+#ifndef _CBMGR_H
+#define _CBMGR_H
+
+#include <bfc/std.h>
+
+class SysCallback;
+class WaComponent;
+
+class CallbackManager {
+public:
+ static void registerCallback(SysCallback *cb, void *param, WaComponent *owner);
+ static void deregisterCallback(SysCallback *cb, WaComponent *owner);
+
+ static void issueCallback(int eventtype, int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+ static int getNumCallbacks();
+};
+
+#endif
diff --git a/Src/Wasabi/api/timer/api_timer.h b/Src/Wasabi/api/timer/api_timer.h
new file mode 100644
index 00000000..4bc8cb81
--- /dev/null
+++ b/Src/Wasabi/api/timer/api_timer.h
@@ -0,0 +1,47 @@
+#ifndef __TIMER_API_H
+#define __TIMER_API_H
+
+// Under linux, the Timer API requires the Linux API
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/platform.h>
+
+class TimerClient;
+
+#ifdef _WIN32
+typedef UINT_PTR TimerToken ;
+#elif defined(__APPLE__)
+typedef EventLoopTimerRef TimerToken;
+#else
+#error port me!
+#endif
+
+class timer_api : public Dispatchable
+{
+ public:
+ TimerToken timer_add(TimerClient *client, intptr_t id, int ms);
+ void timer_remove(TimerClient *client, TimerToken token);
+
+ enum {
+ TIMER_API_ADD = 1,
+ TIMER_API_REMOVE = 11,
+ };
+};
+
+inline TimerToken timer_api::timer_add(TimerClient *client, intptr_t id, int ms)
+{
+ return _call(TIMER_API_ADD, (TimerToken)0, client, id, ms);
+}
+
+inline void timer_api::timer_remove(TimerClient *client, TimerToken token)
+{
+ _voidcall(TIMER_API_REMOVE, client, token);
+}
+
+// {3130D81C-AE1F-4954-9765-698473B627B0}
+static const GUID timerApiServiceGuid =
+{ 0x3130d81c, 0xae1f, 0x4954, { 0x97, 0x65, 0x69, 0x84, 0x73, 0xb6, 0x27, 0xb0 } };
+
+extern timer_api *timerApi;
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/timer/osx_timer.cpp b/Src/Wasabi/api/timer/osx_timer.cpp
new file mode 100644
index 00000000..450c58e1
--- /dev/null
+++ b/Src/Wasabi/api/timer/osx_timer.cpp
@@ -0,0 +1,38 @@
+#include "osx_timer.h"
+#include <api/timer/timerclient.h>
+
+timer_api *timerApi = NULL;
+
+
+TimerApi::TimerApi()
+{
+ mainEventLoop = GetMainEventLoop();
+}
+
+static void WasabiTimerProc(EventLoopTimerRef inTimer, void * inUserData)
+{
+ TimerClient *client = (TimerClient *)inUserData;
+ if (client)
+ client->timerclient_timerCallback(inTimer);
+}
+
+
+TimerToken TimerApi::timer_add(TimerClient *client, int id, int ms)
+{
+ EventLoopTimerRef token;
+ OSStatus err = InstallEventLoopTimer(mainEventLoop,
+ (float)ms/1000.0f,
+ (float)ms/1000.0f,
+ WasabiTimerProc,
+ client,
+ &token);
+ if (err == noErr)
+ return token;
+ else
+ return 0;
+}
+
+void TimerApi::timer_remove(TimerClient *client, TimerToken token)
+{
+ RemoveEventLoopTimer(token);
+}
diff --git a/Src/Wasabi/api/timer/osx_timer.h b/Src/Wasabi/api/timer/osx_timer.h
new file mode 100644
index 00000000..9084ef3a
--- /dev/null
+++ b/Src/Wasabi/api/timer/osx_timer.h
@@ -0,0 +1,17 @@
+#ifndef NULLSOFT_WASABI_OSX_TIMER_H
+#define NULLSOFT_WASABI_OSX_TIMER_H
+
+#include <api/timer/api_timer.h>
+
+class TimerApi : public timer_apiI
+{
+public:
+ TimerApi();
+ TimerToken timer_add(TimerClient *client, int id, int ms);
+ void timer_remove(TimerClient *client, TimerToken);
+private:
+ EventLoopRef mainEventLoop;
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/timer/timerclient.cpp b/Src/Wasabi/api/timer/timerclient.cpp
new file mode 100644
index 00000000..e44e03ce
--- /dev/null
+++ b/Src/Wasabi/api/timer/timerclient.cpp
@@ -0,0 +1,108 @@
+#include "api.h"
+#include <api/timer/api_timer.h>
+#include <api/timer/timerclient.h>
+
+#define CBCLASS TimerClientI
+START_DISPATCH;
+// this one doesn't map directly so that we can catch deferredcb timers
+VCB(TIMERCLIENT_TIMERCALLBACK, timerclient_handleDeferredCallback);
+CB(TIMERCLIENT_GETMASTERCLIENT, timerclient_getMasterClient);
+VCB(TIMERCLIENT_ONMASTERMUX, timerclient_onMasterClientMultiplex);
+CB(TIMERCLIENT_GETDEPPTR, timerclient_getDependencyPtr);
+CB(TIMERCLIENT_GETSKIPPED, timerclient_getSkipped);
+VCB(TIMERCLIENT_SETSKIPPED, timerclient_setSkipped);
+VCB(TIMERCLIENT_POSTDEFERREDCB , timerclient_postDeferredCallback);
+CB(TIMERCLIENT_ONDEFERREDCB , timerclient_onDeferredCallback);
+CB(TIMERCLIENT_GETNAME, timerclient_getName);
+END_DISPATCH;
+
+TimerClientI::TimerClientI()
+ : skipped(0), timerdelay(0), disallowset(0)
+{ }
+
+TimerClientI::~TimerClientI()
+{
+ disallowset = 1;
+ if (cbs.getNumItems() > 0)
+ {
+ TimerToken token;
+ if (tokens.reverseGetItem(DEFERREDCB_TIMERID, &token)) // TODO: it would be nice to have a combo get/del, so we don't have to search twice
+ {
+ WASABI_API_TIMER->timer_remove(this, token);
+ tokens.delItem(token);
+ }
+ }
+ cbs.deleteAll();
+}
+
+int TimerClientI::timerclient_setTimer(intptr_t id, int ms)
+{
+ if (disallowset) return 0;
+ ASSERTPR(id > 0, "A timer id cannot be <= 0");
+ ASSERTPR(id != DEFERREDCB_TIMERID, "please chose another timer id");
+ TimerToken token = WASABI_API_TIMER->timer_add(this, id, ms);
+ tokens.addItem(token, id);
+ return 1;
+}
+
+int TimerClientI::timerclient_killTimer(intptr_t id)
+{
+ TimerToken token;
+ if (tokens.reverseGetItem(id, &token)) // TODO: it would be nice to have a combo get/del, so we don't have to search twice
+ {
+ WASABI_API_TIMER->timer_remove(this, token);
+ tokens.delItem(token);
+ }
+ return 1;
+}
+
+void TimerClientI::timerclient_postDeferredCallback(intptr_t param1, intptr_t param2, int mindelay)
+{
+ if (disallowset) return ;
+ for (int i = 0;i < cbs.getNumItems();i++)
+ {
+ deferred_callback *cb = cbs.enumItem(i);
+ if (cb->param1 == param1 && cb->param2 == param2)
+ {
+ cbs.removeByPos(i);
+ break;
+ }
+ }
+ deferred_callback *c = new deferred_callback;
+ c->origin = this;
+ c->param1 = param1;
+ c->param2 = param2;
+ cbs.addItem(c);
+ TimerToken token = WASABI_API_TIMER->timer_add(this, DEFERREDCB_TIMERID, MAX(1, mindelay));
+ tokens.addItem(token, DEFERREDCB_TIMERID);
+}
+
+void TimerClientI::timerclient_handleDeferredCallback(TimerToken token)
+{
+ // let deriving class handle it. note we call into here even if
+ // it's the deferred cb id, since older versions did that too,
+ // expecting the user to call down on the method.
+
+#ifdef WIN64
+ LPARAM id;
+#else
+ intptr_t id;
+#endif
+ if (tokens.getItem(token, &id))
+ {
+ timerclient_timerCallback((int)id);
+
+ // process our deferred cb id
+ if (id == DEFERREDCB_TIMERID)
+ {
+ WASABI_API_TIMER->timer_remove(this, token);
+ PtrList<deferred_callback> temp(cbs);
+ cbs.removeAll();
+ foreach(temp)
+ deferred_callback *c = temp.getfor();
+ c->origin->timerclient_onDeferredCallback(c->param1, c->param2);
+ delete c;
+ endfor
+ }
+ }
+}
diff --git a/Src/Wasabi/api/timer/timerclient.h b/Src/Wasabi/api/timer/timerclient.h
new file mode 100644
index 00000000..52860a01
--- /dev/null
+++ b/Src/Wasabi/api/timer/timerclient.h
@@ -0,0 +1,183 @@
+#ifndef __TIMER_CLIENT_H
+#define __TIMER_CLIENT_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+#include <bfc/depend.h>
+#include <map>
+
+#define DEFERREDCB_TIMERID -2
+
+class TimerClient;
+
+#ifdef _WIN32
+typedef UINT_PTR TimerToken ;
+#elif defined(__APPLE__)
+typedef EventLoopTimerRef TimerToken;
+#else
+#error port me!
+#endif
+
+typedef struct {
+ TimerClient *origin;
+ intptr_t param1;
+ intptr_t param2;
+} deferred_callback;
+
+class NOVTABLE TimerClient : public Dispatchable
+{
+protected:
+ TimerClient() { }
+
+public:
+ int timerclient_setTimer(int id, int ms);
+ int timerclient_killTimer(int id);
+ void timerclient_postDeferredCallback(intptr_t param1, intptr_t param2=0, int mindelay=0);
+ int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2);
+ void timerclient_timerCallback(TimerToken token);
+
+ TimerClient *timerclient_getMasterClient();
+ void timerclient_onMasterClientMultiplex();
+ api_dependent *timerclient_getDependencyPtr();
+ void timerclient_setSkipped(int s);
+ int timerclient_getSkipped();
+ void timerclient_setTimerDelay(int td);
+ int timerclient_getTimerDelay();
+ const wchar_t *timerclient_getName();
+
+ enum {
+ TIMERCLIENT_TIMERCALLBACK = 101,
+ TIMERCLIENT_SETTIMER = 110,
+ TIMERCLIENT_KILLTIMER = 120,
+ TIMERCLIENT_GETMASTERCLIENT = 130,
+ TIMERCLIENT_ONMASTERMUX = 140,
+ TIMERCLIENT_GETDEPPTR = 150,
+ TIMERCLIENT_SETSKIPPED = 160,
+ TIMERCLIENT_GETSKIPPED = 170,
+ TIMERCLIENT_SETTIMERDELAY = 180,
+ TIMERCLIENT_GETTIMERDELAY = 190,
+ TIMERCLIENT_POSTDEFERREDCB = 200,
+ TIMERCLIENT_ONDEFERREDCB = 210,
+ TIMERCLIENT_GETNAME = 220,
+ };
+};
+
+inline void TimerClient::timerclient_timerCallback(TimerToken token) {
+ _voidcall(TIMERCLIENT_TIMERCALLBACK, token);
+}
+
+inline int TimerClient::timerclient_setTimer(int id, int ms) {
+ return _call(TIMERCLIENT_SETTIMER, 0, id, ms);
+}
+
+inline int TimerClient::timerclient_killTimer(int id) {
+ return _call(TIMERCLIENT_KILLTIMER, 0, id);
+}
+
+inline TimerClient *TimerClient::timerclient_getMasterClient() {
+ return _call(TIMERCLIENT_GETMASTERCLIENT, (TimerClient *)NULL);
+}
+
+inline void TimerClient::timerclient_onMasterClientMultiplex() {
+ _voidcall(TIMERCLIENT_ONMASTERMUX);
+}
+
+inline api_dependent *TimerClient::timerclient_getDependencyPtr() {
+ return _call(TIMERCLIENT_GETDEPPTR, (api_dependent *)NULL);
+}
+
+inline void TimerClient::timerclient_setSkipped(int s) {
+ _voidcall(TIMERCLIENT_SETSKIPPED, s);
+}
+
+inline int TimerClient::timerclient_getSkipped() {
+ return _call(TIMERCLIENT_GETSKIPPED, 0);
+}
+
+inline void TimerClient::timerclient_setTimerDelay(int td) {
+ _voidcall(TIMERCLIENT_SETTIMERDELAY, td);
+}
+
+inline int TimerClient::timerclient_getTimerDelay() {
+ return _call(TIMERCLIENT_GETTIMERDELAY, 0);
+}
+
+inline void TimerClient::timerclient_postDeferredCallback(intptr_t param1, intptr_t param2, int mindelay) {
+ _voidcall(TIMERCLIENT_POSTDEFERREDCB, param1, param2, mindelay);
+}
+
+inline int TimerClient::timerclient_onDeferredCallback(intptr_t param1, intptr_t param2) {
+ return _call(TIMERCLIENT_ONDEFERREDCB, 0, param1, param2);
+}
+
+inline const wchar_t *TimerClient::timerclient_getName() {
+ return _call(TIMERCLIENT_GETNAME, (const wchar_t *)NULL);
+}
+
+class NOVTABLE TimerClientI : public TimerClient {
+protected:
+ TimerClientI();
+
+public:
+ virtual ~TimerClientI();
+
+ virtual int timerclient_setTimer(intptr_t id, int ms);
+ virtual int timerclient_killTimer(intptr_t id);
+
+ // override this to catch your timer events
+ virtual void timerclient_timerCallback(int id) { }
+
+ virtual TimerClient *timerclient_getMasterClient() { return NULL; }
+ virtual void timerclient_onMasterClientMultiplex() { };
+ virtual api_dependent *timerclient_getDependencyPtr()=0;
+ virtual void timerclient_setSkipped(int s) { skipped = s; }
+ virtual int timerclient_getSkipped() { return skipped; }
+ virtual void timerclient_setTimerDelay(int td) { timerdelay = td; }
+ virtual int timerclient_getTimerDelay() { return timerdelay; }
+ virtual void timerclient_postDeferredCallback(intptr_t param1, intptr_t param2=0, int mindelay=0);
+ virtual int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2) { return 1; };
+ virtual const wchar_t *timerclient_getName() { return NULL; }
+
+protected:
+ RECVS_DISPATCH;
+
+private:
+ virtual void timerclient_handleDeferredCallback(TimerToken token);
+
+ int skipped;
+ int timerdelay;
+ int disallowset;
+ PtrList<deferred_callback> cbs;
+#ifdef _WIN32
+ class TokenMap
+ {
+ public:
+ void delItem(TimerToken) {}
+ bool reverseGetItem(intptr_t id, TimerToken *token)
+ {
+ *token = id;
+ return true;
+ }
+ bool getItem(TimerToken token, intptr_t *id)
+ {
+ *id = token;
+ return true;
+ }
+ void addItem(TimerToken, intptr_t) {}
+ };
+#else
+ typedef std::map<TimerToken, intptr_t> TokenMap;
+#endif
+ TokenMap tokens;
+};
+
+class NOVTABLE TimerClientDI : public TimerClientI, public DependentI {
+protected:
+ TimerClientDI() { }
+
+public:
+ api_dependent *timerclient_getDependencyPtr() { return this; }
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/timer/timeslicer.cpp b/Src/Wasabi/api/timer/timeslicer.cpp
new file mode 100644
index 00000000..04d37421
--- /dev/null
+++ b/Src/Wasabi/api/timer/timeslicer.cpp
@@ -0,0 +1,62 @@
+#include "precomp.h"
+#include "timeslicer.h"
+
+#define TIMER_SLICE 0x7816
+
+TimeSlicer::TimeSlicer(int percent_cpu_usage/* =50 */, int slice_duration/* =-1 */) {
+ max_cpu_usage = MIN((float)percent_cpu_usage, 99.0f) / 100.0f;
+ duration = slice_duration;
+ started = 0;
+ slicecount = 0;
+ firstslicetime = -1;
+}
+
+TimeSlicer::~TimeSlicer() {
+}
+
+void TimeSlicer::startSlicer() {
+ if (started) return;
+ started = 1;
+ timerclient_setTimer(TIMER_SLICE, duration);
+ onSlicerStart();
+ timerclient_timerCallback(TIMER_SLICE);
+}
+
+void TimeSlicer::stopSlicer() {
+ if (!started) return;
+ started = 0;
+ timerclient_killTimer(TIMER_SLICE);
+ onSlicerStop();
+ firstslicetime = -1;
+}
+
+void TimeSlicer::onSlicerStop() {
+}
+
+void TimeSlicer::onSlicerStart() {
+}
+
+int TimeSlicer::isSlicerStarted() {
+ return started;
+}
+
+void TimeSlicer::timerclient_timerCallback(int id) {
+ if (id == TIMER_SLICE) {
+ DWORD now = Std::getTickCount();
+ runSlice(now, now + (int)((float)duration * max_cpu_usage));
+ } else
+ TimerClient::timerclient_timerCallback(id);
+}
+
+void TimeSlicer::runSlice(DWORD start, DWORD stopwhen) {
+ DWORD now = Std::getTickCount();
+ slicecount = 0;
+ onBeginSliceBatch();
+ if (slicecount == 0 && firstslicetime != -1) stopwhen = now + firstslicetime;
+ while (Std::getTickCount() < stopwhen) {
+ onSlice();
+ slicecount++;
+ if (!started) break; // got aborted
+ }
+ onEndSliceBatch();
+}
diff --git a/Src/Wasabi/api/timer/timeslicer.h b/Src/Wasabi/api/timer/timeslicer.h
new file mode 100644
index 00000000..06ae67f4
--- /dev/null
+++ b/Src/Wasabi/api/timer/timeslicer.h
@@ -0,0 +1,64 @@
+#ifndef __TIMESLICER_H
+#define __TIMESLICER_H
+
+// TimeSlicer allows you to create a background job to perform while not blocking
+// the main GUI thread. You give it the max percentage of CPU it should use, call star()
+// and it'll start calling onSlice as many times as it can without using more cpu than requested
+//
+// To use this class, you need to break down your job into multiple tiny chunks that
+// you perform in onSlice. Typical uses include adding files to or filtering entries from
+// the database, driving state machines, etc.
+//
+// onSlice will be called multiple times per timer.
+
+#include "timerclient.h"
+
+enum {
+ GRANULARITY_EXTRALOW = 20,
+ GRANULARITY_LOW = 50,
+ GRANULARITY_MEDIUM = 100,
+ GRANULARITY_HIGH = 250,
+ GRANULARITY_EXTRAHIGH = 1000,
+};
+
+class TimeSlicer : public TimerClientI {
+ public:
+
+ TimeSlicer(int percent_cpu_usage=25, int slice_duration=GRANULARITY_LOW);
+ virtual ~TimeSlicer();
+
+ virtual void timerclient_timerCallback(int id);
+
+ void startSlicer();
+ void stopSlicer();
+ int isSlicerStarted();
+
+ virtual void onSlicerStart();
+ virtual void onSlicerStop();
+ virtual void onBeginSliceBatch() {}
+ virtual void onEndSliceBatch() {}
+ api_dependent *timerclient_getDependencyPtr() { return timeslicer_getDependencyPtr(); }
+ virtual api_dependent *timeslicer_getDependencyPtr()=0;
+ virtual void setFirstSliceMinTime(int ms) { firstslicetime = ms; }
+ virtual int getSliceCount() { return slicecount; }
+
+
+ // override this to do your work
+ virtual void onSlice() { }
+
+ private:
+
+ virtual void runSlice(DWORD start, DWORD stopwhen);
+ float max_cpu_usage;
+ int duration;
+ int started;
+ int firstslicetime;
+ int slicecount;
+};
+
+class TimeSlicerD : public TimeSlicer, public DependentI {
+ public:
+ virtual api_dependent *timeslicer_getDependencyPtr() { return this; }
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/util/savefile.cpp b/Src/Wasabi/api/util/savefile.cpp
new file mode 100644
index 00000000..f7766fa7
--- /dev/null
+++ b/Src/Wasabi/api/util/savefile.cpp
@@ -0,0 +1,228 @@
+#include "precomp.h"
+//NONPORTABLE
+
+#include <windows.h>
+#include <commdlg.h>
+#include "savefile.h"
+
+#include "../bfc/basewnd.h"
+
+#include "../studio/api.h"
+#include "../studio/assert.h"
+
+#include "../bfc/encodedstr.h"
+#include "../studio/services/svc_stringconverter.h"
+
+SaveFileWnd::SaveFileWnd(const char *ident) : identifier(ident),
+ force_initial_dir(0) {}
+
+void SaveFileWnd::setInitialDir(const char *dir, int force) {
+ initial_dir = dir;
+ force_initial_dir = force;
+}
+
+int SaveFileWnd::getSaveFile(api_window *parent, const char *ext, const char *suggext) {
+ int retcode, failed = 0;
+ if (ext == NULL) return 0;
+
+ if (Std::encodingSupportedByOS(SvcStrCnv::UTF16)) {
+ int ret = getSaveFileW(parent, ext, suggext);
+ // If ret returns -1, the service is not available, we will call our own
+ // OSNative translation failure routines below:
+ if (ret != -1) {
+ return ret;
+ }
+ }
+
+ char savedir[WA_MAX_PATH];
+ Std::getCurDir(savedir, WA_MAX_PATH);
+
+ char filenamebuf[MAX_PATH]="";
+ filename = NULL;
+
+ OPENFILENAME ofn;
+ ofn.lStructSize = sizeof ofn;
+ ofn.hwndOwner = parent->gethWnd();
+ ofn.hInstance = NULL;
+ ofn.lpstrFilter = ext;
+ ofn.lpstrCustomFilter = NULL;
+ ofn.nMaxCustFilter = 0;
+ ofn.nFilterIndex = 0;
+ ofn.lpstrFile = filenamebuf;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+
+ ofn.lpstrInitialDir = NULL;
+ const char *initDir8 = NULL;
+
+ // Figure out the initial directory in UTF8
+ char dir[WA_MAX_PATH]="";
+ String tname;
+ if (identifier != NULL) {
+ tname.printf("Recent directories/SaveFile/%s", identifier.getValue());
+ if (force_initial_dir)
+ initial_dir.strncpyTo(dir, sizeof(dir));
+ else
+ WASABI_API_CONFIG->getStringPublic(tname, dir, WA_MAX_PATH, initial_dir);
+ if (*dir) initDir8 = dir;
+ }
+
+ // And then convert it when you're done to OSNATIVE.
+ EncodedStr initDirOSenc;
+ retcode = initDirOSenc.convertFromUTF8(SvcStrCnv::OSNATIVE, String(initDir8));
+ if (retcode == SvcStrCnv::ERROR_UNAVAILABLE) {
+ failed = 1;
+ ofn.lpstrInitialDir = initDir8;
+ } else {
+ ofn.lpstrInitialDir = static_cast<char *>(initDirOSenc.getEncodedBuffer());
+ }
+
+ ofn.lpstrTitle = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOREADONLYRETURN|OFN_HIDEREADONLY;
+ ofn.nFileOffset = 0;
+ ofn.nFileExtension = 0;
+ ofn.lpstrDefExt = suggext;
+ ofn.lCustData = 0;
+ ofn.lpfnHook = NULL;
+ ofn.lpTemplateName = NULL;
+ api->pushModalWnd();
+ int ret = GetSaveFileName(&ofn);
+ api->popModalWnd();
+
+ if (failed) {
+ if (ret)
+ filename = filenamebuf;
+ } else {
+ // Okay, at this point we have the string in OSNATIVE format.
+ // Now we downconvert everything to UTF8 and pass our information to the engine API's
+ if (ret) {
+ EncodedStr bufOSstr(SvcStrCnv::OSNATIVE, filenamebuf, STRLEN(filenamebuf)+1, 0/*no delete*/);
+ bufOSstr.convertToUTF8(filename);
+ }
+ }
+
+ // get new cur dir & save it off
+ if ((identifier != NULL) && ret) {
+ char newdir[WA_MAX_PATH];
+ Std::getCurDir(newdir, WA_MAX_PATH);
+
+ WASABI_API_CONFIG->setStringPublic(tname, newdir);
+ }
+ // put back old one
+ Std::setCurDir(savedir);
+
+ return ret;
+}
+
+int SaveFileWnd::getSaveFileW(api_window *parent, const char *ext, const char *suggext) {
+
+ // The ultimate top level retrohack. (sigh).
+ // Test to see if the service is available. If not, return -1.
+ // The OSNATIVE codepath will include the proper failure handling.
+ StringConverterEnum myServiceEnum(SvcStrCnv::UTF16); // _ASSUME_ that there is a converter for U16 (we should, but still...)
+ svc_stringConverter *myConv = myServiceEnum.getFirst();
+ if (myConv != NULL) {
+ myServiceEnum.release(myConv);
+ } else {
+ return -1;
+ }
+
+ char savedir[WA_MAX_PATH];
+ Std::getCurDir(savedir, WA_MAX_PATH);
+
+ WCHAR filenamebufW[MAX_PATH] = L"";
+ filename = NULL;
+
+ // convert multi const char* ext to U16 (Ascii7 assumptive)
+ int thisz = 0, lastz = 0;
+ const char *px;
+ WCHAR *pr, *ext16 = static_cast<WCHAR *>(MALLOC(WA_MAX_PATH));
+ for (px = ext, pr = ext16; *px | (lastz); px++, pr++) {
+ lastz = (thisz)?1:0;
+ *pr = (*px) & 0xFF;
+ thisz = (*pr)?1:0;
+ }
+ *pr = *px; // the last 0
+
+ EncodedStr suggext16;
+ suggext16.convertFromUTF8(SvcStrCnv::UTF16, String(suggext));
+
+ OPENFILENAMEW ofnW;
+ ofnW.lStructSize = sizeof ofnW;
+ ofnW.hwndOwner = parent->gethWnd();
+ ofnW.hInstance = NULL;
+ ofnW.lpstrFilter = ext16;
+ ofnW.lpstrCustomFilter = NULL;
+ ofnW.nMaxCustFilter = 0;
+ ofnW.nFilterIndex = 0;
+ ofnW.lpstrFile = filenamebufW;
+ ofnW.nMaxFile = MAX_PATH;
+ ofnW.lpstrFileTitle = NULL;
+ ofnW.nMaxFileTitle = 0;
+
+ ofnW.lpstrInitialDir = NULL;
+
+ char dir[WA_MAX_PATH]="";
+ String tname;
+
+ // Figure out the initial directory in UTF8
+ const char *initDir8 = NULL;
+ if (identifier != NULL) {
+ tname.printf("Recent directories/SaveFile/%s", identifier.getValue());
+ if (force_initial_dir)
+ initial_dir.strncpyTo(dir, sizeof(dir));
+ else
+ WASABI_API_CONFIG->getStringPublic(tname, dir, WA_MAX_PATH, "");
+ if (*dir) initDir8 = dir;
+ }
+
+ // And then convert it when you're done to UTF16.
+ WCHAR *initDir16 = NULL;
+ EncodedStr initDir16enc;
+ if (initDir8 != NULL) {
+ int written = initDir16enc.convertFromUTF8(SvcStrCnv::UTF16, String(initDir8));
+ if (written > 0) {
+ initDir16 = static_cast<WCHAR *>(initDir16enc.getEncodedBuffer());
+ } else {
+ return -1;
+ }
+ }
+
+ // And then stuff it here. Phew!
+ ofnW.lpstrInitialDir = initDir16;
+
+ ofnW.lpstrTitle = NULL;
+ ofnW.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOREADONLYRETURN|OFN_HIDEREADONLY;
+ ofnW.nFileOffset = 0;
+ ofnW.nFileExtension = 0;
+ ofnW.lpstrDefExt = static_cast<WCHAR *>(suggext16.getEncodedBuffer());
+ ofnW.lCustData = 0;
+ ofnW.lpfnHook = NULL;
+ ofnW.lpTemplateName = NULL;
+ api->pushModalWnd();
+ int ret = GetSaveFileNameW(&ofnW);
+ api->popModalWnd();
+
+ // Okay, at this point we have the string in UTF16 widechar format.
+ // Now we downconvert everything to UTF8 and pass our information to the engine API's
+ if (ret) {
+ EncodedStr buf16str(SvcStrCnv::UTF16, filenamebufW, (WSTRLEN(filenamebufW)+1)*2, 0/*no delete*/);
+ buf16str.convertToUTF8(filename);
+ }
+
+ // get new cur dir & save it off
+ if ((identifier != NULL) && ret) {
+ char newdir[WA_MAX_PATH];
+ Std::getCurDir(newdir, WA_MAX_PATH);
+
+ WASABI_API_CONFIG->setStringPublic(tname, newdir);
+ }
+
+ FREE(ext16);
+
+ // put back old one
+ Std::setCurDir(savedir);
+
+ return ret;
+}
diff --git a/Src/Wasabi/api/util/savefile.h b/Src/Wasabi/api/util/savefile.h
new file mode 100644
index 00000000..3df65287
--- /dev/null
+++ b/Src/Wasabi/api/util/savefile.h
@@ -0,0 +1,31 @@
+#ifndef _SAVEFILE_H
+#define _SAVEFILE_H
+
+#include "common.h"
+
+#include "modal.h"
+#include "../bfc/string.h"
+
+class ifc_window;
+
+class SaveFileWnd : public Modal {
+public:
+ SaveFileWnd(const char *ident=NULL);
+/**
+ Sets the initial directory for the picker. If force is FALSE, this directory
+ will only be used if no previous directory has been saved for the indent.
+ If TRUE, it will always be used.
+*/
+ void setInitialDir(const char *dir, int force=FALSE);
+ int getSaveFile(ifc_window *parent, const char *ext, const char *suggext);
+ int getSaveFileW(ifc_window *parent, const char *ext, const char *suggext);
+ const char *getFilename() { return filename; }
+
+private:
+ String identifier;
+ String filename;
+ String initial_dir;
+ int force_initial_dir;
+};
+
+#endif
diff --git a/Src/Wasabi/api/util/selectfile.cpp b/Src/Wasabi/api/util/selectfile.cpp
new file mode 100644
index 00000000..08e70314
--- /dev/null
+++ b/Src/Wasabi/api/util/selectfile.cpp
@@ -0,0 +1,111 @@
+#include <precomp.h>
+
+#include "selectfile.h"
+
+#include <api/wnd/popup.h>
+#include <api/service/svcs/svc_filesel.h>
+
+SelectFile::SelectFile(ifc_window *parent, const wchar_t *menu_prefix, const wchar_t *menu_suffix)
+ : parentWnd(parent),
+ prefix_str(menu_prefix),
+ suffix_str(menu_suffix)
+{
+ svc = NULL;
+ ASSERT(parent != NULL);
+ xpos = ypos = 0;
+ pos_set = 0;
+}
+
+SelectFile::~SelectFile()
+{
+ if (svc) WASABI_API_SVC->service_release(svc);
+ types.deleteAll();
+}
+
+void SelectFile::setDefaultDir(const wchar_t *dir)
+{
+ default_dir = dir;
+}
+
+const wchar_t *SelectFile::getDirectory()
+{
+ if (svc) return svc->getDirectory();
+ return NULL;
+}
+
+void SelectFile::setIdent(const wchar_t *id)
+{
+ ident = id;
+}
+
+void SelectFile::setPopPosition(int x, int y)
+{
+ xpos = x;
+ ypos = y;
+ pos_set = 1;
+}
+
+int SelectFile::runSelector(const wchar_t *type, int allow_multiple, const wchar_t *extlist)
+{
+ if (svc) WASABI_API_SVC->service_release(svc); svc = NULL;
+ types.deleteAll();
+ if (type == NULL)
+ {
+ int pos = 0;
+ for (;;)
+ {
+ waServiceFactory *wasvc = WASABI_API_SVC->service_enumService(WaSvc::FILESELECTOR, pos++);
+ if (wasvc == NULL) break;
+ svc_fileSelector *sfs = castService<svc_fileSelector>(wasvc);
+ const wchar_t *pref = sfs->getPrefix();
+ if (pref != NULL)
+ types.addItem(new StringW(pref));
+ WASABI_API_SVC->service_release(sfs);
+ }
+ if (types.getNumItems() <= 0) return 0; // none?!
+
+ PopupMenu *pop = new PopupMenu(parentWnd);
+ for (int i = 0; i < types.getNumItems(); i++)
+ {
+ StringW str;
+ str += prefix_str;
+ str += types[i]->getValue();
+ str += suffix_str;
+ pop->addCommand(str, i);
+ }
+ int cmd = pos_set ? pop->popAtXY(xpos, ypos) : pop->popAtMouse();
+ StringW *s = types[cmd];
+ if (s == NULL) return 0;
+ type = *s;
+ }
+ ASSERT(type != NULL);
+
+ saved_type = type;
+
+ svc = FileSelectorEnum(type).getFirst();
+ ASSERT(svc != NULL); // we just enumed it
+ if (extlist != NULL) svc->setExtList(extlist);
+ //FUCKO : need to set open vs. save as
+ WASABI_API_WND->pushModalWnd();
+ int r = svc->runSelector(parentWnd, FileSel::OPEN, allow_multiple,
+ ident.isempty() ? type : ident.getValue(),
+ default_dir);
+ WASABI_API_WND->popModalWnd();
+ ASSERT(svc != NULL); // we just enumed it
+ return r;
+}
+
+const wchar_t *SelectFile::getType()
+{
+ return saved_type;
+}
+
+int SelectFile::getNumFiles()
+{
+ return svc ? svc->getNumFilesSelected() : 0;
+}
+
+const wchar_t *SelectFile::enumFilename(int n)
+{
+ return svc ? svc->enumFilename(n) : NULL;
+}
diff --git a/Src/Wasabi/api/util/selectfile.h b/Src/Wasabi/api/util/selectfile.h
new file mode 100644
index 00000000..5dc378a7
--- /dev/null
+++ b/Src/Wasabi/api/util/selectfile.h
@@ -0,0 +1,41 @@
+#ifndef _SELECTFILE_H
+#define _SELECTFILE_H
+
+#include <bfc/common.h>
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+class svc_fileSelector;
+class ifc_window;
+
+class SelectFile
+{
+public:
+ SelectFile(ifc_window *parent, const wchar_t *menu_prefix = NULL, const wchar_t *menu_suffix = NULL);
+ ~SelectFile();
+
+ void setDefaultDir(const wchar_t *dir); // default dir to use
+ const wchar_t *getDirectory(); // return base directory after ok clicked
+ void setIdent(const wchar_t *id); // unless you saved one under this id
+
+ void setPopPosition(int x, int y); // in screen coords
+
+ int runSelector(const wchar_t *type = NULL, int allow_multiple = FALSE, const wchar_t *extlist = NULL); // if NULL, generate popup
+ const wchar_t *getType();
+
+ int getNumFiles();
+ const wchar_t *enumFilename(int n);
+
+private:
+ int xpos, ypos;
+ int pos_set;
+ ifc_window *parentWnd;
+ svc_fileSelector *svc;
+ PtrList<StringW> types;
+ StringW prefix_str, suffix_str;
+ StringW default_dir, ident;
+ StringW saved_type;
+};
+
+#endif
diff --git a/Src/Wasabi/api/util/systray.cpp b/Src/Wasabi/api/util/systray.cpp
new file mode 100644
index 00000000..921d21d7
--- /dev/null
+++ b/Src/Wasabi/api/util/systray.cpp
@@ -0,0 +1,93 @@
+#include <precomp.h>
+#ifdef WIN32
+#include <windows.h>
+#include <shellapi.h>
+#endif
+#include "systray.h"
+#include <bfc/assert.h>
+#include <bfc/wasabi_std.h>
+
+Systray::Systray(HWND wnd, int uid, int msg, HICON smallicon)
+{
+ id = uid;
+ hwnd = wnd;
+ message = msg;
+ icon = smallicon;
+ /*int r = */addIcon();
+ // always asserts with desktop with no systray support (litestep, WINE, etc...)
+ // ASSERT(r == TRUE);
+}
+
+Systray::~Systray()
+{
+ /*int r = */deleteIcon();
+ // always asserts with desktop with no systray support (litestep, WINE, etc...)
+ // ASSERT(r == TRUE);
+}
+
+void Systray::setTip(const wchar_t *_tip)
+{
+ tip = _tip;
+ tip.trunc(64);
+ if (!tip.isempty())
+ {
+ /*int r = */setTip();
+ // always asserts with desktop with no systray support (litestep, WINE, etc...)
+ // ASSERT(r == TRUE);
+ }
+}
+
+bool Systray::addIcon()
+{
+#ifdef WIN32
+ NOTIFYICONDATAW tnid = {0};
+ tnid.cbSize = sizeof(NOTIFYICONDATAW);
+ tnid.uID = id;
+ tnid.hWnd = hwnd;
+ tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+ tnid.uCallbackMessage = message;
+ tnid.hIcon = icon;
+ if (tip)
+ WCSCPYN(tnid.szTip, tip, sizeof(tnid.szTip)/sizeof(wchar_t));
+
+ return !!Shell_NotifyIconW(NIM_ADD, &tnid);
+#else
+ DebugString("portme Systray::addIcon\n");
+ return 1;
+#endif
+}
+
+bool Systray::setTip()
+{
+#ifdef WIN32
+ NOTIFYICONDATAW tnid = {0};
+ tnid.cbSize = sizeof(NOTIFYICONDATAW);
+ tnid.uFlags = NIF_TIP;
+ tnid.uID = id;
+ tnid.hWnd = hwnd;
+ if (tip)
+ WCSCPYN(tnid.szTip, tip, sizeof(tnid.szTip)/sizeof(wchar_t));
+
+ return !!Shell_NotifyIconW(NIM_MODIFY, &tnid);
+#else
+ DebugString("portme Systray::setTip\n");
+ return 1;
+#endif
+}
+
+
+bool Systray::deleteIcon()
+{
+#ifdef WIN32
+ NOTIFYICONDATA tnid = {0};
+ tnid.cbSize = sizeof(NOTIFYICONDATAW);
+ tnid.hWnd = hwnd;
+ tnid.uID = id;
+
+ return !!Shell_NotifyIcon(NIM_DELETE, &tnid);
+#else
+ DebugString("portme Systray::deleteIcon\n");
+ return 1;
+#endif
+}
+
diff --git a/Src/Wasabi/api/util/systray.h b/Src/Wasabi/api/util/systray.h
new file mode 100644
index 00000000..3e4f6d93
--- /dev/null
+++ b/Src/Wasabi/api/util/systray.h
@@ -0,0 +1,23 @@
+#ifndef __SYSTRAY_H
+#define __SYSTRAY_H
+
+#include <bfc/string/StringW.h>
+
+class Systray
+{
+public:
+ Systray(HWND wnd, int uid, int msg, HICON smallicon);
+ ~Systray();
+ void setTip(const wchar_t *tip);
+private:
+ bool addIcon();
+ bool deleteIcon();
+ bool setTip();
+ int id, message;
+ HWND hwnd;
+ HICON icon;
+ StringW tip;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/util/varmgr.cpp b/Src/Wasabi/api/util/varmgr.cpp
new file mode 100644
index 00000000..d8a4e54f
--- /dev/null
+++ b/Src/Wasabi/api/util/varmgr.cpp
@@ -0,0 +1,111 @@
+#include <precomp.h>
+#include "varmgr.h"
+#include <api/script/objects/guiobj.h>
+#include <api/skin/widgets/group.h>
+#include <api/skin/skinparse.h>
+#include <api/wac/wac.h>
+#include <bfc/parse/pathparse.h>
+
+// for now only translates special text like :componentname etc but in the future
+// this will translate xml variables
+
+StringW *PublicVarManager::translate_nocontext(const wchar_t *str)
+{
+ return translate(str, NULL, NULL);
+}
+
+//Martin> TODO: Split this method for <include/>, <bitmap/>,... and <text/> objects
+StringW *PublicVarManager::translate(const wchar_t *str, GuiObject *o, Container *c)
+{
+ if (str == NULL) return NULL;
+ //test if @ or : is present
+ {
+ const wchar_t *p=str;
+ int found=0;
+ while(p && *p && !found) {
+ wchar_t a=*p++;
+ if(a==':' || a=='@') found=1;
+ }
+ if(!found)
+ return NULL;
+ }
+
+ // lone> this needs to be a service, but it may slow shit down if we enum too often since this is called for all xml values, so carfull when you add this, lone
+ #ifdef CUSTOM_VARS
+ const wchar_t *rpl=NULL;
+ CUSTOM_VARS(str, rpl);
+ if (rpl != NULL) return new StringW(rpl);
+ #endif
+
+ const wchar_t *skinname = NULL;
+ if (WASABI_API_SKIN != NULL)
+ skinname=WASABI_API_SKIN->getSkinName();
+
+ static int in=0;
+ if (in)
+ return NULL;
+ in = 1;
+
+ StringW *ret = new StringW(str);
+
+ if (skinname)
+ {
+ StringW colorThemePath = WASABI_API_APP->path_getAppPath();
+ colorThemePath.AppendPath(L"ColorThemes");
+ colorThemePath.AppendPath(skinname);
+
+ ret->replace(L"@COLORTHEMESPATH@", colorThemePath);
+ ret->replace(L"@SKINPATH@", WASABI_API_SKIN->getSkinPath());
+ ret->replace(L"@SKINSPATH@", WASABI_API_SKIN->getSkinsPath());
+ ret->replace(L"@APPDATAPATH@", WASABI_API_APP->path_getUserSettingsPath());
+ //ret->replace(L"@DEFAULTSKINPATH@", StringPathCombine(WASABI_API_SKIN->getSkinsPath(), L"Default")); //Martin> doesn't exist in winamp5, so cut to speed loading
+ ret->replace(L"@WINAMPPATH@", StringPrintfW(L"%s\\", WASABI_API_APP->path_getAppPath()));
+ }
+#ifdef WASABI_COMPILE_COMPONENTS
+ ret->replace("@WACDATAPATH@", WASABI_API_APP->path_getComponentDataPath());
+#endif
+
+ if (!o && !c) { in = 0; return ret; }
+
+//CUT wtf? if (!str) return NULL;
+
+ const wchar_t *containerid = NULL;
+ const wchar_t *groupid = NULL;
+ const wchar_t *componentName = NULL;
+
+ if (o && o->guiobject_getParentGroup())
+ {
+ groupid = o->guiobject_getParentGroup()->getGuiObject()->guiobject_getId();
+ if (o->guiobject_getParentGroup()->getParentContainer())
+ {
+ containerid = o->guiobject_getParentGroup()->getParentContainer()->getId();
+ componentName = o->guiobject_getParentGroup()->getParentContainer()->getName();
+ }
+ }
+ else {
+ groupid = SkinParser::getCurrentGroupId();
+ if (c) {
+ containerid = c->getId();
+ componentName = /*c->hasComponent() ? api->getComponentName(c->getGUID()) : */c->getName();
+ } else {
+ containerid = SkinParser::getCurrentContainerId();
+ componentName = NULL;
+ }
+ }
+
+ if (componentName != NULL) {
+ ret->replace(L":componentname", componentName); // DEPRECATED
+ ret->replace(L"@COMPONENTNAME@", componentName);
+ }
+ if (containerid != NULL) {
+ ret->replace(L":containerid", containerid); // DEPRECATED
+ ret->replace(L"@CONTAINERID@", containerid);
+ }
+ if (groupid != NULL) {
+ ret->replace(L":groupid", groupid); // DEPRECATED
+ ret->replace(L"@GROUPID@",groupid);
+ }
+
+ in = 0;
+ return ret;
+}
diff --git a/Src/Wasabi/api/util/varmgr.h b/Src/Wasabi/api/util/varmgr.h
new file mode 100644
index 00000000..8759cddf
--- /dev/null
+++ b/Src/Wasabi/api/util/varmgr.h
@@ -0,0 +1,17 @@
+#ifndef __VARMGR_H
+#define __VARMGR_H
+
+#include <bfc/wasabi_std.h>
+
+class GuiObject;
+class Container;
+class WaComponent;
+
+
+class PublicVarManager {
+public:
+ static StringW *translate_nocontext(const wchar_t *str);
+ static StringW *translate(const wchar_t *str, GuiObject *o=NULL, Container *c=NULL);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wac/compdb.h b/Src/Wasabi/api/wac/compdb.h
new file mode 100644
index 00000000..9985d971
--- /dev/null
+++ b/Src/Wasabi/api/wac/compdb.h
@@ -0,0 +1,28 @@
+#ifndef __COMP_DB_H
+#define __COMP_DB_H
+
+#define DB_DENY 0
+#define DB_ALLOW 1
+
+#define DB_READ 0
+#define DB_WRITE 1
+#define DB_DELETE 2
+#define DB_GETSCANNER 3
+#define DB_DROPINDEX 4
+
+#define DB_ERROR 0
+#define DB_SUCCESS 1
+#define DB_NOSUCHFIELD 2
+#define DB_RECORDNOTFOUND 3
+#define DB_UNKNOWNDATATYPE 4
+#define DB_DATATYPEMISMATCH 5
+#define DB_OPERATIONDENIED 6
+#define DB_INVALIDGUID 7
+#define DB_EMPTYFIELD 8
+#define DB_NOTAVAILABLE 9
+
+#define DB_ENDOFENUM 0
+#define DB_FOUND TRUE
+#define DB_NOTFOUND FALSE
+
+#endif
diff --git a/Src/Wasabi/api/wac/compon.cpp b/Src/Wasabi/api/wac/compon.cpp
new file mode 100644
index 00000000..12f66313
--- /dev/null
+++ b/Src/Wasabi/api/wac/compon.cpp
@@ -0,0 +1,480 @@
+#include <precomp.h>
+
+#include <bfc/wasabi_std.h>
+
+#include "compon.h"
+//#include <api/wac/main.h> // CUT!
+
+#ifndef WASABINOMAINAPI
+#include <api/metadb/metadb.h>
+#include <api/wac/papi.h>
+#endif
+#include <api/script/objects/compoobj.h>
+#include <api/wndmgr/container.h>
+#include <api/skin/skinparse.h>
+#include <api/wac/wac.h>
+#include <api/script/objects/wacobj.h>
+#include <api/wnd/wndtrack.h>
+#include <api/script/objecttable.h>
+
+#include <api/config/items/cfgitemi.h>
+
+#include <bfc/loadlib.h>
+//#include <bfc/util/profiler.h>
+#include <api/locales/xlatstr.h>
+#include <bfc/file/recursedir.h>
+
+#include <api/service/svc_enum.h>
+#include <api/service/services.h>
+#include <api/service/servicei.h>
+#include <api/skin/skin.h>
+#include <api/script/scriptmgr.h>
+#include <bfc/parse/pathparse.h>
+
+#ifndef WASABINOMAINAPI
+#include <api/api1.h>
+#endif
+
+#include <api/application/wkc.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/script/objects/compoobj.h>
+
+#include <api/wnd/usermsg.h>
+#include <bfc/util/inifile.h>
+
+class CShutdownCallback {
+ public:
+ virtual void rl_onShutdown()=0;
+};
+
+
+extern GUID baseGUID;
+
+static TList<GUID> loadlist, banlist;
+
+// compon.cpp : maintains the list of installed components, and installs
+// each one
+
+// keep a list of component pointers as well as instances
+class component_slot
+{
+public:
+#ifndef WASABINOMAINAPI
+ component_slot(Library *_dll, WaComponent *_wac, ComponentAPI *_api, GUID g, const wchar_t *orig_path)
+ : dll(_dll), wac(_wac), path(orig_path), guid(g), componentapi(_api) {
+#else
+ component_slot(Library *_dll, WaComponent *_wac, GUID g, const wchar_t *orig_path)
+ : dll(_dll), wac(_wac), path(orig_path), guid(g) {
+#endif
+ int fnlen = wcslen(Wasabi::Std::filename(orig_path));
+ path.trunc(-fnlen);
+ postonregsvcs = 0;
+ postoncreate = 0;
+ loadearly = 0; // will be filled in later
+ }
+ ~component_slot() {
+#ifndef WASABINOMAINAPI
+ if (dll != NULL) PAPI::destroyAPI(componentapi);
+#endif
+ delete dll;
+ }
+ void registerServices() {
+#ifndef WASABINOMAINAPI
+ if (!postonregsvcs) wac->registerServices(componentapi);
+#else
+ if (!postonregsvcs) wac->registerServices(WASABI_API_SVC);
+#endif
+ postonregsvcs = 1;
+ }
+ void onCreate() {
+ if (!postoncreate) wac->onCreate();
+ postoncreate = 1;
+ }
+
+ Library *dll;
+ WaComponent *wac; // we don't delete this
+ StringW path;
+ GUID guid; // prevent spoofing
+#ifndef WASABINOMAINAPI
+ ComponentAPI *componentapi;
+#endif
+ int postoncreate;
+ int postonregsvcs;
+ int loadearly;
+};
+
+static PtrList<component_slot> components;
+
+/*static PtrList<cd_entry> cd_list;
+static PtrList<ComponentObject> co_list;*/
+
+// the minimum SDK version # we accept
+const int WA_COMPONENT_VER_MIN = WA_COMPONENT_VERSION;
+
+ static int postComponentCommand(GUID guid, const wchar_t *command, int p1, int p2, void *ptr, int ptrlen, int waitforanswer);
+
+class ComponPostEntry {
+public:
+ ComponPostEntry(GUID pguid, const wchar_t *pcommand, int pp1, int pp2, void *pptr, int pptrlen, int pwait) :
+ guid(pguid), command(pcommand), p1(pp1), p2(pp2), ptr(pptr), ptrlen(pptrlen), waitforanswer(pwait),
+ posted(0), result(0) { }
+ GUID guid;
+ StringW command;
+ int p1, p2;
+ void *ptr;
+ int ptrlen;
+ int waitforanswer;
+ int posted;
+ int result;
+};
+
+static PtrList<StringW> preloads;
+
+void ComponentManager::addStaticComponent(WaComponent *component) {
+ GUID guid = component->getGUID();
+ if (!checkGUID(guid)) return; // guid check (banlist etc.)
+
+#ifndef WASABINOMAINAPI
+ // reuse main api *
+ components.addItem(new component_slot(NULL, component, api, guid, NULL));
+#else
+ components.addItem(new component_slot(NULL, component, guid, NULL));
+#endif
+}
+
+void ComponentManager::addPreloadComponent(const wchar_t *filename)
+{
+ foreach(preloads)
+ if (PATHEQL(filename, preloads.getfor()->getValue())) return;// no dups
+ endfor
+ preloads.addItem(new StringW(filename));
+}
+
+void ComponentManager::loadPreloads() {
+ foreach(preloads)
+ load(preloads.getfor()->getValue());
+ endfor
+ preloads.deleteAll();
+}
+
+void ComponentManager::load(const wchar_t *filename) {
+ // ensure no duplicate filenames
+ foreach(components)
+ if (PATHEQL(filename, components.getfor()->dll->getName())) return;
+ endfor
+
+ #ifdef WA3COMPATIBILITY
+ // let kernel controller test the file
+ WasabiKernelController *wkc = Main::getKernelController();
+ if (wkc && !wkc->testComponent(filename)) return;
+ #endif
+
+ // check if they have an ini (to get guid faster)
+ StringW inifile = filename;
+ const wchar_t *ext = Wasabi::Std::extension(inifile);
+ int len = wcslen(ext);
+ inifile.trunc(-len);
+ inifile.cat(L"ini");
+ IniFile ini(inifile);
+ GUID ini_guid = ini.getGuid(L"component", L"guid");
+ if (!checkGUID(ini_guid, TRUE)) return;
+
+// PR_ENTER2("load component", filename);
+
+ // attach the DLL
+ Library *dll = new Library(filename);
+ if (!dll->load()) {
+ delete dll;
+ return;
+ }
+
+ // check the version of SDK it was compiled with
+ WACGETVERSION wac_get_version = (WACGETVERSION)dll->getProcAddress("WAC_getVersion");
+ if (wac_get_version == NULL) {
+ delete dll;
+ return;
+ }
+
+ int version = (*wac_get_version)();
+ if (version < WA_COMPONENT_VER_MIN || // defined above
+ version > WA_COMPONENT_VERSION) { // from wac.h
+ delete dll;
+ return;
+ }
+
+ // init the dll itself
+ WACINIT wacinit = (WACINIT)dll->getProcAddress("WAC_init");
+ if (wacinit != NULL) (*wacinit)(dll->getHandle());
+
+ WACENUMCOMPONENT wec = (WACENUMCOMPONENT)dll->getProcAddress("WAC_enumComponent");
+ if (wec == NULL) {
+ delete dll;
+ return;
+ }
+
+ // fetch the pointer
+ WaComponent *wac = (*wec)(0);
+
+ GUID guid = wac->getGUID();
+
+ if (ini_guid != INVALID_GUID && guid != ini_guid) {
+ delete dll;
+ DebugString("guids didn't match! %s", filename);
+ return;
+ }
+
+ // check if we want to load this GUID
+ if (!checkGUID(guid)) {
+ delete dll;
+ return;
+ }
+
+#ifndef WASABINOMAINAPI
+ // allocate an api pointer bound to their GUID
+ ComponentAPI *newapi = PAPI::createAPI(wac, guid);
+ if (newapi == NULL) {
+ delete dll;
+ return;
+ }
+#endif
+
+ PathParserW pp(filename);
+ StringW path;
+ for (int i=0;i<pp.getNumStrings()-1;i++)
+ {
+ path.AppendFolder(pp.enumString(i));
+ }
+
+ wac->setComponentPath(path);
+
+ // keep track of dll handles for shutdown
+ components.addItem(new component_slot(dll, wac,
+#ifndef WASABINOMAINAPI
+ newapi,
+#endif
+ guid, filename));
+
+// PR_LEAVE();
+}
+
+const wchar_t *ComponentManager::getComponentPath(GUID g) {
+ foreach(components)
+ if (g == components.getfor()->guid) {
+ return components.getfor()->path;
+ }
+ endfor
+ return NULL;
+}
+
+void ComponentManager::startupDBs() {
+/* for (int i=0;i<components.getNumItems();i++)
+ MetaDB::addComponentDB(components.enumItem(i)->wac);*/
+}
+
+void ComponentManager::shutdownDBs() {
+#ifndef WASABINOMAINAPI
+ for (int i = 0; i < components.getNumItems(); i++) {
+ //MetaDB::getBaseDB()->removeComponentDB(components[i]->wac);
+ (static_cast<ComponentAPI1 *>(components[i]->componentapi))->shutdownDB();
+ }
+#else
+//MULTIAPI-FIXME: solve the shutdownDB puzzle
+#endif
+}
+
+void ComponentManager::unloadAll() {
+ // cable out! let 'er go!
+// deleteAllCD(); // deletes compwnds
+ foreach(components)
+ components.getfor()->wac->deregisterServices();
+ endfor
+ foreach(components)
+ components.getfor()->wac->onDestroy();
+ endfor
+ components.deleteAll(); // free the DLLs, and kill their API *'s
+}
+
+int ComponentManager::checkGUID(GUID &g, int invalid_ok) {
+ // no invalid guid
+ if (!invalid_ok && g == INVALID_GUID) return FALSE;
+
+ // check against banlist
+ if (banlist.haveItem(g)) return FALSE;
+
+ // check against load-only list
+ if (loadlist.getNumItems() && !loadlist.haveItem(g)) return FALSE;
+
+ // ensure no duplicate GUIDs
+ foreach(components)
+ if (g == components.getfor()->guid) {
+//CUT StringPrintf s("%s and %s", components.getfor()->dll->getName(), filename);
+//CUT Std::messageBox(s, "Duplicate component guid", MB_OK);
+ return FALSE;
+ }
+ endfor
+
+ // ok
+ return TRUE;
+}
+
+WaComponent *ComponentManager::enumComponent(int component) {
+ if (component < 0 || component >= components.getNumItems()) return NULL;
+ return components[component]->wac;
+}
+
+void ComponentManager::loadAll(const wchar_t *path) {
+
+#if 0//CUT
+ static const char *loadorder[] = {
+ "wasabi.system/pngload.wac",
+ "wasabi.player/core.wac",
+ "metrics.wac", // so metrics dialog appears before the splash screen
+ "winamp/winamp.wac", // so splash screen displays right after startup
+ "winamp/pledit.wac",
+ "winamp/library.wac",
+ "preferences.wac", // so prefs has the system groups at the top
+ "skinswitch.wac", // so skinswitch is the first non internal prefs screen, ignored if not present. fucko: need to modify prefs system so we don't need to load in any particular order
+ NULL
+ };
+
+ for (int i = 0; loadorder[i] != NULL; i++) {
+ StringPrintf fn("%s%s%s", WACDIR, DIRCHARSTR, loadorder[i]);
+ ComponentManager::load(fn);
+ }
+#endif
+ RecurseDir dir(path, L"*.*");// have to do *.* to get subdirs
+ while (dir.next()) {
+ StringPathCombine fn(dir.getPath(), dir.getFilename());
+ const wchar_t *ext = Wasabi::Std::extension(fn);
+ if (!WCSICMP(ext, L"wac"))
+ ComponentManager::load(fn);
+ }
+}
+
+void ComponentManager::postLoad(int f) { // two-level startup procedure
+ // note we're calling the slot, not the component directly
+
+ // allow punk-ass bitches to load early if need be
+ foreach(components)
+ if ((components.getfor()->loadearly = !!components.getfor()->wac->onNotify(WAC_NOTIFY_LOADEARLY))) {
+ components.getfor()->registerServices();
+ }
+ endfor
+
+ foreach(components)
+ if (!components.getfor()->loadearly)
+ components.getfor()->registerServices();
+ endfor
+ foreach(components)
+ components.getfor()->onCreate();
+ endfor
+ if (f) ObjectTable::loadExternalClasses();
+}
+
+void ComponentManager::broadcastNotify(int cmd, int param1, int param2) {
+ foreach(components)
+ if ((components.getfor()->loadearly = !!components.getfor()->wac->onNotify(WAC_NOTIFY_LOADEARLY, cmd, param1, param2)))
+ components.getfor()->wac->onNotify(cmd, param1, param2);
+ endfor
+ foreach(components)
+ if (!components.getfor()->loadearly)
+ components.getfor()->wac->onNotify(cmd, param1, param2);
+ endfor
+}
+
+void ComponentManager::sendNotify(GUID guid, int cmd, int param1, int param2) {
+ WaComponent *wac = getComponentFromGuid(guid);
+ if (wac)
+ wac->onNotify(cmd, param1, param2);
+}
+
+int ComponentManager::sendCommand(GUID guid, const wchar_t *command, int p1, int p2, void *ptr, int ptrlen) {
+ if (command == NULL) return 0;
+ WaComponent *wac = getComponentFromGuid(guid);
+ if (wac) return wac->onCommand(command, p1, p2, ptr, ptrlen);
+ return 0;
+}
+
+int ComponentManager::postCommand(GUID guid, const wchar_t *command, int p1, int p2, void *ptr, int ptrlen, int waitforanswer) {
+#ifdef WA3COMPATIBILITY // todo: make thread id part of application api
+ if(Std::getCurrentThreadId()==Main::getThreadId() && waitforanswer) {
+ // if it is already the main thread calling, just pass the command to sendCommand
+ return sendCommand(guid,command,p1,p2,ptr,ptrlen);
+ }
+#endif
+ ComponPostEntry *cpe=new ComponPostEntry(guid,command,p1,p2,ptr,ptrlen,waitforanswer);
+ componPostEntries.addItem(cpe);
+#ifdef WIN32
+#ifdef WA3COMPATIBILITY // todo: make this a call to application api
+ PostMessage(Main::gethWnd(),UMSG_COMPON_POSTMESSAGE,0,0); // ask the main thread to call mainthreadpostCommands();
+#endif
+#else
+ PostMessage(None,UMSG_COMPON_POSTMESSAGE,0,0); // ask the main thread to call mainthreadpostCommands();
+#endif
+ if(waitforanswer) {
+ while(!cpe->posted) Sleep(1);
+ int res=cpe->result;
+ componPostEntries.removeItem(cpe);
+ delete(cpe);
+ return res;
+ }
+ return 0; // cpe will get deleted by mainthreadpostCommands();
+}
+
+
+void ComponentManager::broadcastCommand(const wchar_t *command, int p1, int p2, void *ptr, int ptrlen) {
+ if (command == NULL) return;
+ for (int i = 0; i < components.getNumItems(); i++) {
+ components[i]->wac->onCommand(command, p1, p2, ptr, ptrlen);
+ }
+}
+
+int ComponentManager::getNumComponents() {
+ return components.getNumItems();
+}
+
+GUID ComponentManager::getComponentGUID(int c) {
+ if (c >= components.getNumItems()) return INVALID_GUID;
+ return components[c]->guid;
+}
+
+const wchar_t *ComponentManager::getComponentName(GUID g)
+{
+ WaComponent *wac = getComponentFromGuid(g);
+ if (wac)
+ return wac->getName();
+ return NULL;
+}
+
+CfgItem *ComponentManager::getCfgInterface(GUID g) {
+ WaComponent *wac = getComponentFromGuid(g);
+ if (wac == NULL) return NULL;
+ return wac->getCfgInterface(0);
+}
+
+WaComponent *ComponentManager::getComponentFromGuid(GUID g) {
+ if (g == INVALID_GUID) return NULL;
+ for (int i=0;i<components.getNumItems();i++) {
+ if (g == components[i]->guid)
+ return components[i]->wac;
+ }
+ return NULL;
+}
+
+void ComponentManager::mainThread_handlePostCommands() {
+ // critical section
+ for(int i=0;i<componPostEntries.getNumItems();i++) {
+ ComponPostEntry *cpe=componPostEntries[i];
+ if(!cpe->posted) {
+ sendCommand(cpe->guid,cpe->command.getValue(),cpe->p1,cpe->p2,cpe->ptr,cpe->ptrlen);
+ if(cpe->waitforanswer) cpe->posted=1;
+ else {
+ delete cpe;
+ componPostEntries.removeByPos(i);
+ i--;
+ }
+ }
+ }
+}
+
+PtrList<ComponPostEntry> ComponentManager::componPostEntries;
diff --git a/Src/Wasabi/api/wac/compon.h b/Src/Wasabi/api/wac/compon.h
new file mode 100644
index 00000000..3dcae3b4
--- /dev/null
+++ b/Src/Wasabi/api/wac/compon.h
@@ -0,0 +1,56 @@
+//PORTABLE
+#ifndef _COMPON_H
+#define _COMPON_H
+
+#include <bfc/wasabi_std.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/ptrlist.h>
+
+class ifc_canvas;
+class CfgItem; // see cfgitem.h
+class CompWnd;
+class ComponentObject;
+class Container;
+class WaComponent;
+class ComponPostEntry;
+
+
+class ComponentManager {
+public:
+ static void addStaticComponent(WaComponent *component);
+ static void addPreloadComponent(const wchar_t *filename);
+ static void loadPreloads();
+
+ static void loadAll(const wchar_t *path);
+
+ static void postLoad(int f=TRUE);
+
+ static void unloadAll();
+
+ static int checkGUID(GUID &g, int invalid_ok=FALSE); // boolean of if we should load it
+
+ static WaComponent *enumComponent(int component);
+
+ static void broadcastNotify(int cmd, int param1=0, int param2=0);
+ static void sendNotify(GUID guid, int cmd, int param1=0, int param2=0);
+ static int sendCommand(GUID guid, const wchar_t *command, int p1=0, int p2=0, void *ptr=NULL, int ptrlen=0);
+ static int postCommand(GUID guid, const wchar_t *command, int p1, int p2, void *ptr, int ptrlen, int waitforanswer);
+ static void broadcastCommand(const wchar_t *command, int p1=0, int p2=0, void *ptr=NULL, int ptrlen=0);
+ static int getNumComponents();
+ static GUID getComponentGUID(int c);
+ static const wchar_t *getComponentName(GUID g);
+ static CfgItem *getCfgInterface(GUID g);
+ static WaComponent *getComponentFromGuid(GUID g);
+
+ static void load(const wchar_t *filename);
+
+ static const wchar_t *getComponentPath(GUID g);
+
+ static void startupDBs();
+ static void shutdownDBs();
+
+ static void mainThread_handlePostCommands();
+ static PtrList<ComponPostEntry> componPostEntries;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wac/main.h b/Src/Wasabi/api/wac/main.h
new file mode 100644
index 00000000..b77cb00a
--- /dev/null
+++ b/Src/Wasabi/api/wac/main.h
@@ -0,0 +1,134 @@
+// THIS FILE SHOULD FUCKING DISAPPEAR DAMMIT
+
+//NONPORTABLE -- HWND and HINSTANCE references
+#ifndef _MAIN_H
+#define _MAIN_H
+
+#warning don't include me
+
+#include <bfc/std.h>
+#include <bfc/string/string.h>
+#include <bfc/ptrlist.h>
+
+#define WM_SYSTRAY WM_USER+1102 //FG> Arbitrary value. Would probably be better with a registered message
+#define WM_SETSKIN WM_USER+0x1000
+
+class Systray;
+class MetricsCallback;
+class ScriptObjectManager;
+class CfgItem;
+class api_window;
+class GenWnd;
+class WasabiKernelController;
+class CoreHandle;
+class CompCommandEntry;
+class Layout;
+
+class Main {
+public:
+ friend class WasabiKernel;
+ static HINSTANCE gethInstance();
+ static HWND gethWnd();
+ static DWORD getThreadId();
+ static WasabiKernelController *getKernelController();
+ static int isMaximized();
+ static int isMinimized();
+ static int minimizeWnd();
+ static int restoreWnd();
+ static int invalidate();
+
+ static void outputDebugString(int severity, const char *string);
+ static void outputDebugString(const char *string) {
+ outputDebugString(0, string);
+ }
+
+ // sets the ownerwnd title
+ static void setWindowTitle(const wchar_t *text);
+
+ // status
+ static void setOverlayText(const wchar_t *text, int interval);//displays then reverts
+ static void setTrayTipText(const wchar_t *text); // set systrem tray icon tooltip text
+
+ // ontop status
+ static void setOnTop(BOOL set);
+ static BOOL getOnTop();
+
+ // systray
+ // 0 = nothing
+ // 1 = taskbar
+ // 2 = systray
+ // 3 = both :)
+ static void setIconMode(int mode);
+
+ // skin
+ static void setSkinDelayed(const wchar_t *skinName);
+
+ // path to wasabi.dll
+ static const wchar_t *getWasabiPath();
+ // path to main EXE
+ static const wchar_t *getMainAppPath();
+
+ static GUID getGuid();
+
+ static void shutdown();
+ static void cancelShutdown();
+
+ static void savePosition();
+
+ static void navigateUrl(const wchar_t *url); // displays in minibrowser if present, otherwise launch external
+
+ static int appContextMenu(api_window *parent, BOOL canScale, BOOL canAlpha);
+ static int thingerContextMenu(api_window *parent);
+
+ static void doAction(int action, int param=0);
+ static void doMenu(const wchar_t *which);
+
+ static void processCommandLine(const wchar_t *cmdLine);
+
+ static void setSkinsPath(const wchar_t *path);
+ static const wchar_t *getSkinsPath();
+
+ static GenWnd *getGenericWnd();
+ static int isShutingDown();
+
+ static HICON smallicon;
+ static HICON bigicon;
+ static bool ontop;
+ static Systray *systray;
+ static GenWnd *genericwnd;
+ static int shuting_down;
+
+ // maintains a stack of modal windows so basewnds can discard messages in WM_MOUSEACTIVATE, should only be used by MsgboxWnd & ModalWnd when we write it ;)
+ static api_window *getModalWnd();
+ static void pushModalWnd(api_window *wnd);
+ static int popModalWnd(api_window *wnd);
+
+ static void metrics_addCallback(MetricsCallback *);
+ static void metrics_delCallback(MetricsCallback *);
+ static int metrics_getDelta();
+ static int metrics_setDelta(int newdelta);
+
+ static int isInetAvailable(); //return 1 if connected, 0 if not available
+
+ static String lastwindowtitle;
+ static int taskbaractive;
+
+ static CoreHandle *getMainCoreHandle();
+ static CoreHandle *mainCoreHandle;
+
+ static const wchar_t *getCommandLine();
+ static String commandLine;
+ static String skinspath;
+
+ static int revert_on_error;
+ static int cancel_shutdown;
+ static PtrList<api_window> ontoplist;
+ static void saveTopMosts();
+ static void restoreTopMosts();
+ static int onMouseWheel(int l, int a);
+
+private:
+ static int isRASActive();
+};
+
+#endif
diff --git a/Src/Wasabi/api/wac/papi.h b/Src/Wasabi/api/wac/papi.h
new file mode 100644
index 00000000..73ac11d7
--- /dev/null
+++ b/Src/Wasabi/api/wac/papi.h
@@ -0,0 +1,12 @@
+#ifndef _PAPI_H
+#define _PAPI_H
+
+class ComponentAPI;
+class WaComponent;
+
+namespace PAPI {
+ ComponentAPI *createAPI(WaComponent *, GUID owner, GUID*config=NULL);
+ void destroyAPI(ComponentAPI *);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wac/wac.h b/Src/Wasabi/api/wac/wac.h
new file mode 100644
index 00000000..d19f5615
--- /dev/null
+++ b/Src/Wasabi/api/wac/wac.h
@@ -0,0 +1,266 @@
+#ifndef _WAC_H
+#define _WAC_H
+
+#include <api/wac/compdb.h>//CUT
+#include <bfc/ptrlist.h>
+#include <api/config/items/cfgitemi.h>
+
+class ifc_canvas; // see canvas.h
+class CfgItem; // see cfgitem
+class CfgItemI;
+class ComponentAPI; // see api.h
+class api_window; // see rootwnd.h
+class LoadableResource; // see below
+
+// this tells wasabi what version of the SDK we're compiled with
+// this number will be incremented every once in a while. when it is, you'll
+// have to recompile
+// 5 -> build #471
+// 6 -> build rc1
+// 7 -> build 484 (rc5)
+// 8 -> Winamp 5.23 (build 608)
+// 9 -> Winamp 5.4
+#define WA_COMPONENT_VERSION 9
+
+#define DB_DENY 0
+#define DB_ALLOW 1
+
+// commands for onNotify below
+
+#define WAC_NOTIFY_NOP 0
+
+#define WAC_NOTIFY_ACTIVATE 10
+#define WAC_NOTIFY_DEACTIVATE 20
+
+#define WAC_NOTIFY_FULLSCREEN 30
+#define WAC_NOTIFY_RESTORE 40
+
+#define WAC_NOTIFY_ENTERRESIZE 50
+#define WAC_NOTIFY_LEAVERESIZE 51
+
+#define WAC_NOTIFY_SYSTRAYDONE 60
+#define WAC_NOTIFY_POPUPDONE 61
+
+#define WAC_NOTIFY_BASETEXTUREWINDOW 78
+
+#define WAC_NOTIFY_LOADEARLY 90
+
+#define WAC_NOTIFY_MENU_COMMAND 10000
+
+// this message is sent when service runlevel notifies are sent
+// param1 = msg
+// param2 = param1
+// param3 = param2
+#define WAC_NOTIFY_SERVICE_NOTIFY 100
+
+#define WAC_NOTIFY_SKINUNLOADING 0xE300 // before unloading current skin
+#define WAC_NOTIFY_SWITCHINGSKIN 0xE301 // right after unloading current skin and right before loading new one, getSkinName/Path points to new skin
+#define WAC_NOTIFY_SKINELEMENTSLOADED 0xE302 // after skin elements definitions are loaded
+#define WAC_NOTIFY_BEFORELOADINGSKINELEMENTS 0xE303 // before skin elements definitions are loaded, trap this to load your elements/groups and let people override them
+#define WAC_NOTIFY_SKINGUILOADED 0xE304 // after skin GUI objects are loaded from xml
+#define WAC_NOTIFY_SKINLOADED 0xE305 // after skin is fully loaded
+
+enum {
+ RSF_STATIC=0,
+ RSF_RELATIVETOWAC=1,
+ RSF_RELATIVETOTHEME=2,
+};
+
+// -----------
+
+#include <bfc/dispatch.h>
+
+class NOVTABLE WaComponent : public Dispatchable {
+public:
+ // provide your component name & other info here
+ const wchar_t *getName() { return _call(GETNAME, (wchar_t *)NULL); }
+ GUID getGUID() { return _call(GETGUID, INVALID_GUID); }
+
+#ifdef WASABINOMAINAPI
+ void registerServices(api_service *a) { _voidcall(REGISTERSERVICES2, a); }
+#else
+ void registerServices(ComponentAPI *a) { _voidcall(REGISTERSERVICES, a); }
+#endif
+ void deregisterServices() { _voidcall(DEREGISTERSERVICES); }
+
+ void onCreate() { _voidcall(ONCREATE); }
+ void onDestroy() { _voidcall(ONDESTROY); }
+//DEPRECATED: will go away
+ api_window *createWindow(int n, api_window *parentWnd) { return _call(CREATEWINDOW, (api_window*)NULL, n, parentWnd); }
+
+ int onNotify(int cmd, int param1=0, int param2=0, int param3=0, int param4=0){
+ return _call(ONNOTIFY, 0, cmd, param1, param2, param3, param4);
+ }
+ // everything after cmd is for future expansion
+ int onCommand(const wchar_t *cmd, int param1, int param2, void *ptr, int ptrlen){
+ return _call(ONCOMMAND, 0, cmd, param1, param2, ptr, ptrlen);
+ }
+
+ // gets the CfgItem * from WAComponentClient
+ CfgItem *getCfgInterface(int n) {
+ return _call(GETCFGINTERFACE, (CfgItem*)NULL, n);
+ }
+
+ // saves the OSMODULEHANDLE of your WAC for you
+ void setOSModuleHandle(OSMODULEHANDLE modulehandle) {
+ _voidcall(SETOSMODULEHANDLE, modulehandle);
+ }
+ OSMODULEHANDLE getOSModuleHandle() {
+ return _call(GETOSMODULEHANDLE, (OSMODULEHANDLE)0);
+ }
+ // saves the path of your WAC for you
+ void setComponentPath(const wchar_t *path) {
+ _voidcall(SETPATH, path);
+ }
+ const wchar_t *getComponentPath() {
+ return _call(GETPATH, (const wchar_t *)NULL);
+ }
+
+ enum {
+ GETNAME=100,
+ GETGUID=120,
+ REGISTERSERVICES=200,
+ REGISTERSERVICES2=210,
+ ONCREATE=400,
+ ONDESTROY=410,
+ CREATEWINDOW=420,
+ ONNOTIFY=500,
+ ONCOMMAND=600,
+ GETCFGINTERFACE=800,
+ SETHINSTANCE=900, SETOSMODULEHANDLE=900, // note dups for back-compat
+ GETHINSTANCE=910, GETOSMODULEHANDLE=910, // note dups for back-compat
+ DEREGISTERSERVICES=1000,
+ SETPATH=1100,
+ GETPATH=1200,
+ };
+};
+
+// hides the dispatchable interface
+class NOVTABLE WaComponentI : public WaComponent {
+protected:
+ WaComponentI() {} // protect constructor
+public:
+ virtual const wchar_t *getName()=0;
+ virtual GUID getGUID()=0;
+
+#ifdef WASABINOMAINAPI
+ virtual void registerServices(api_service *)=0;
+#else
+ virtual void registerServices(ComponentAPI *)=0;
+#endif
+ virtual int RegisterServicesSafeModeOk()=0;
+ virtual void deregisterServices()=0;
+
+ virtual void onCreate()=0;
+ virtual void onDestroy()=0;
+
+ virtual api_window *createWindow(int n, api_window *parentWnd)=0; //DEPRECATED
+
+ virtual int onNotify(int cmd, int param1, int param2, int param3, int param4)=0;
+ virtual int onCommand(const wchar_t *cmd, int param1, int param2, void *ptr, int ptrlen)=0;
+
+ virtual CfgItem *getCfgInterface(int n)=0;
+
+ virtual void setOSModuleHandle(OSMODULEHANDLE moduleHandle)=0;
+ virtual OSMODULEHANDLE getOSModuleHandle()=0;
+ virtual void setComponentPath(const wchar_t *path)=0;
+ virtual const wchar_t *getComponentPath()=0;
+
+private:
+ virtual void internal_onDestroy()=0;
+ virtual int internal_onNotify(int cmd, int param1, int param2, int param3, int param4)=0; // calls thru to onNotify after processing
+ RECVS_DISPATCH;
+};
+
+class waServiceFactoryI;
+
+/**
+*/
+class NOVTABLE WAComponentClient : public WaComponentI, public CfgItemI
+{
+protected:
+ WAComponentClient(const wchar_t *name=NULL);
+public:
+ virtual ~WAComponentClient() {}
+
+ // provide your component name & other info here
+ virtual const wchar_t *getName(); //OVERRIDE ME (or just set name in constructor)
+ virtual GUID getGUID()=0; // be sure to override this one //OVERRIDE ME
+
+#ifdef WASABINOMAINAPI
+ void registerServices(api_service *); // don't override
+#else
+ void registerServices(ComponentAPI *); // don't override
+#endif
+ int RegisterServicesSafeModeOk();
+ void deregisterServices(); // don't override
+
+ // override these to receive notifications
+ virtual void onRegisterServices() {}// register extra services here
+ virtual void onCreate() {} // init stuff
+ virtual void onDestroy() {} // destroy everything here, not in ~
+//DEPRECATED: will go away
+// this is moving to svc_wndcreate
+ virtual api_window *createWindow(int n, api_window *parentWnd) { return NULL; }
+
+ // OVERRIDE ME for various events
+ virtual int onNotify(int cmd, int param1, int param2, int param3, int param4) { return 0; }
+ // everything after cmd is for future expansion
+ virtual int onCommand(const wchar_t *cmd, int param1, int param2, void *ptr, int ptrlen) { return 0; }
+
+ // config ptr... you can override this and provide a different *
+ // otherwise 'this' will be returned
+ virtual CfgItem *getCfgInterface(int n);
+
+ // saves the OSMODULEHANDLE of your WAC for you
+ void setOSModuleHandle(OSMODULEHANDLE moduleHandle) { OSModuleHandle = moduleHandle; };
+ OSMODULEHANDLE getOSModuleHandle() { return OSModuleHandle; }
+ void setComponentPath(const wchar_t *path) { componentpath = path; };
+ const wchar_t *getComponentPath() { return componentpath; }
+ OSMODULEHANDLE gethInstance() { return getOSModuleHandle(); } //DEPRECATED
+
+ // various options to register during your constructor, like services,
+ // skin parts, and autopop guids. just register them and forget them
+
+ void registerService(waServiceFactoryI* service);
+ void registerSkinFile(const wchar_t *filename, int relative=RSF_RELATIVETOWAC);
+
+ /* benski> cut
+ void registerAutoPopup(GUID guid, const wchar_t *description, const wchar_t *prefered_container=NULL, int container_required=FALSE);
+ void registerAutoPopup(const wchar_t *groupid, const wchar_t *description, const wchar_t *container_layout=NULL, int container_required=FALSE);
+ void registerCfgItem(CfgItemI *cfgitem, int autodelete=FALSE);
+ void registerExtension(const wchar_t *extension, const wchar_t *description, const wchar_t *family=NULL);
+ void registerCallback(SysCallback *_callback, void *_param = NULL);
+ void registerPrefGroup(const wchar_t *groupname, const wchar_t *dest, GUID pref_guid, GUID pref_guid_parent=INVALID_GUID);*/
+ // or register your own resource types here
+ void registerResource(LoadableResource *res);
+
+ virtual void onSkinLoaded() {}
+
+private:
+ virtual void internal_onDestroy();
+ virtual int internal_onNotify(int cmd, int param1, int param2, int param3, int param4);
+ OSMODULEHANDLE OSModuleHandle;
+ int postregisterservices; // if 1, onRegisterServices has been called
+ PtrList<LoadableResource> resources;
+ StringW componentpath;
+};
+
+extern "C" {
+ typedef void (*WACINIT)(OSMODULEHANDLE);
+ typedef UINT (*WACGETVERSION)(void); // returns the interface version component was compiled with
+ typedef WaComponent *(*WACENUMCOMPONENT)(int n);
+};
+
+class LoadableResource {
+public:
+ virtual ~LoadableResource() {}
+
+ virtual int deleteOnShutdown() { return TRUE; } // return FALSE if you're static
+
+ virtual void onRegisterServices() {}
+ virtual void onDeregisterServices() {} // unload during this one
+ virtual void beforeLoadingSkinElements() {}
+};
+
+#endif
diff --git a/Src/Wasabi/api/wac/waclient.cpp b/Src/Wasabi/api/wac/waclient.cpp
new file mode 100644
index 00000000..3cc394c8
--- /dev/null
+++ b/Src/Wasabi/api/wac/waclient.cpp
@@ -0,0 +1,347 @@
+// the glue!
+#include <precomp.h>
+#include <wasabicfg.h>
+#include <bfc/assert.h>
+#include "wac.h"
+
+#include <api/service/servicei.h>
+#include <api/memmgr/api_memmgr.h>
+
+#ifndef STATIC_COMPONENT
+extern WAComponentClient *the;
+
+#ifndef WASABINOMAINAPI
+ComponentAPI *api; // we do NOT delete this on shutdown!!!
+#endif
+
+OSMODULEHANDLE g_modulehandle;
+#endif //STATIC_COMPONENT
+
+WAComponentClient::WAComponentClient(const wchar_t *name) :
+ CfgItemI(name) {
+ OSModuleHandle = NULL;
+}
+
+const wchar_t *WAComponentClient::getName() {
+ return cfgitem_getName();
+}
+
+#ifdef WASABINOMAINAPI
+void WAComponentClient::registerServices(api_service *_serviceapi)
+{
+ serviceApi = _serviceapi;
+
+ waServiceFactory *sf = serviceApi->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf) applicationApi = reinterpret_cast<api_application*>(sf->getInterface());
+
+#ifdef WASABI_COMPILE_SYSCB
+ sf = serviceApi->service_getServiceByGuid(syscbApiServiceGuid);
+ if (sf) sysCallbackApi = reinterpret_cast<api_syscb *>(sf->getInterface());
+#endif
+
+ sf = serviceApi->service_getServiceByGuid(memMgrApiServiceGuid);
+ if (sf) memmgrApi = reinterpret_cast<api_memmgr *>(sf->getInterface());
+
+#ifdef WASABI_COMPILE_CONFIG
+ sf = serviceApi->service_getServiceByGuid(configApiServiceGuid);
+ if (sf) configApi = reinterpret_cast<api_config *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_IMGLDR
+ sf = serviceApi->service_getServiceByGuid(imgLdrApiServiceGuid);
+ if (sf) imgLoaderApi = reinterpret_cast<imgldr_api *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+ sf = serviceApi->service_getServiceByGuid(fontApiServiceGuid);
+ if (sf) fontApi = reinterpret_cast<api_font *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_FILEREADER
+ sf = serviceApi->service_getServiceByGuid(fileReaderApiServiceGuid);
+ if (sf) fileApi = reinterpret_cast<api_fileReader *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_LOCALES
+ sf = serviceApi->service_getServiceByGuid(localesApiServiceGuid);
+ if (sf) localesApi = reinterpret_cast<api_locales *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_TIMERS
+ sf = serviceApi->service_getServiceByGuid(timerApiServiceGuid);
+ if (sf) timerApi = reinterpret_cast<timer_api *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_WND
+ sf = serviceApi->service_getServiceByGuid(wndApiServiceGuid);
+ if (sf) wndApi = reinterpret_cast<wnd_api *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+ sf = serviceApi->service_getServiceByGuid(wndMgrApiServiceGuid);
+ if (sf) wndManagerApi = reinterpret_cast<wndmgr_api *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_COMPONENTS
+#endif
+
+#ifdef WASABI_COMPILE_METADB
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+ sf = serviceApi->service_getServiceByGuid(makiApiServiceGuid);
+ if (sf) makiApi = reinterpret_cast<api_maki *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+ sf = serviceApi->service_getServiceByGuid(skinApiServiceGuid);
+ if (sf) skinApi = reinterpret_cast<api_skin *>(sf->getInterface());
+#endif
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+ sf = serviceApi->service_getServiceByGuid(makiDebugApiServiceGuid);
+ if (sf) debugApi = reinterpret_cast<api_makiDebugger *>(sf->getInterface());
+#endif
+
+#else
+void WAComponentClient::registerServices(ComponentAPI *_api) {
+ // save API *
+ api = _api;
+#endif
+
+ // propagate name from component to cfgitemi
+ if (cfgitem_getName() == NULL) CfgItemI::setName(WaComponent::getName());
+
+ // register resources
+ foreach(resources)
+ resources.getfor()->onRegisterServices();
+ endfor
+
+ // our CfgItem GUID defaults to our component GUID
+ cfgitem_setGUID(getGUID());
+
+ // by default, peg us under "Installed Components" in config
+ // {99CFD75C-1CA7-49e5-B8C0-7D78AA443C10}
+ const GUID installed_guid =
+ { 0x99cfd75c, 0x1ca7, 0x49e5, { 0xb8, 0xc0, 0x7d, 0x78, 0xaa, 0x44, 0x3c, 0x10 } };
+ if (cfgitem_getParentGuid() == INVALID_GUID)
+ setParentGuid(installed_guid);
+
+ WASABI_API_CONFIG->config_registerCfgItem(this);
+
+ // allow overridden component class to do stuff
+ onRegisterServices();
+}
+
+int WAComponentClient::RegisterServicesSafeModeOk()
+{
+ return 1;
+}
+
+void WAComponentClient::deregisterServices() {
+ foreach(resources)
+ resources.getfor()->onDeregisterServices();
+ endfor
+ WASABI_API_CONFIG->config_deregisterCfgItem(this);
+}
+
+CfgItem *WAComponentClient::getCfgInterface(int n) {
+ if (n == 0) return this;
+ return NULL;
+}
+
+class RegService : public LoadableResource {
+public:
+ RegService(waServiceFactoryI *sf) : factory(sf) {}
+
+ virtual void onRegisterServices() {
+ WASABI_API_SVC->service_register(factory);
+ }
+ virtual void onDeregisterServices() {
+ WASABI_API_SVC->service_deregister(factory);
+ }
+
+private:
+ waServiceFactoryI *factory;
+};
+
+void WAComponentClient::registerService(waServiceFactoryI* service) {
+ registerResource(new RegService(service));
+}
+
+class SkinPart : public LoadableResource {
+public:
+ SkinPart(const wchar_t *name, int rel) : filename(name), id(-1), relative(rel) {}
+
+ void beforeLoadingSkinElements() {
+ ASSERT(!filename.isempty());
+ StringW fn(filename);
+ switch (relative) {
+ case RSF_RELATIVETOWAC:
+ fn.prepend(the->getComponentPath());// api->path_getComponentPath());
+ break;
+ case RSF_RELATIVETOTHEME: {
+ wchar_t theme[WA_MAX_PATH]=L"";
+ WASABI_API_CONFIG->getStringPrivate(L"theme", theme, WA_MAX_PATH, L"default");
+ StringW path = WASABI_API_APP->path_getAppPath();
+ path.AppendPath(L"themes");
+ path.AppendPath(theme);
+ fn = StringPathCombine(path, fn);
+ }
+ break;
+ }
+ id = WASABI_API_SKIN->loadSkinFile(fn);
+ }
+ virtual void onDeregisterServices() {
+ if (id >= 0 && WASABI_API_SKIN) WASABI_API_SKIN->unloadSkinPart(id);
+ id = -1;
+ }
+
+private:
+ StringW filename;
+ int id;
+ int relative;
+};
+
+void WAComponentClient::registerSkinFile(const wchar_t *filename, int relative)
+{
+ registerResource(new SkinPart(filename, relative));
+}
+
+void WAComponentClient::registerResource(LoadableResource *res) {
+ ASSERT(!resources.haveItem(res));
+ resources.addItem(res);
+ if (postregisterservices) res->onRegisterServices();
+}
+
+void WAComponentClient::internal_onDestroy() {
+ onDestroy();
+ foreach(resources)
+ if (resources.getfor()->deleteOnShutdown()) delete resources.getfor();
+ endfor
+ resources.removeAll();
+}
+
+int WAComponentClient::internal_onNotify(int cmd, int param1, int param2, int param3, int param4) {
+ switch (cmd) {
+ case WAC_NOTIFY_BEFORELOADINGSKINELEMENTS:
+ foreach(resources)
+ resources.getfor()->beforeLoadingSkinElements();
+ endfor
+ break;
+ case WAC_NOTIFY_SKINLOADED:
+ onSkinLoaded();
+ break;
+ }
+ return onNotify(cmd, param1, param2, param3, param4);
+}
+
+#ifndef STATIC_COMPONENT
+extern "C" {
+
+__declspec(dllexport) UINT WAC_getVersion(void) {
+ return WA_COMPONENT_VERSION;
+}
+
+__declspec(dllexport) int WAC_init(OSMODULEHANDLE moduleHandle) {
+ the->setOSModuleHandle(moduleHandle);
+ if (g_modulehandle == NULL) g_modulehandle = moduleHandle;
+ return TRUE;
+}
+
+__declspec(dllexport) WaComponent *WAC_enumComponent(int n) {
+ return the;
+}
+
+} // end extern "C"
+#endif
+
+#define CBCLASS WaComponentI
+START_DISPATCH;
+ CB(GETNAME, getName);
+ CB(GETGUID, getGUID);
+#ifndef WASABINOMAINAPI
+ VCB(REGISTERSERVICES, registerServices);
+#else
+ VCB(REGISTERSERVICES2, registerServices);
+#endif
+ CB(15, RegisterServicesSafeModeOk)
+ VCB(DEREGISTERSERVICES, deregisterServices);
+ VCB(ONCREATE, onCreate);
+ VCB(ONDESTROY, internal_onDestroy);
+ CB(CREATEWINDOW, createWindow);
+ CB(ONNOTIFY, internal_onNotify);
+ CB(ONCOMMAND, onCommand);
+ CB(GETCFGINTERFACE, getCfgInterface);
+ VCB(SETOSMODULEHANDLE, setOSModuleHandle);
+ CB(GETOSMODULEHANDLE, getOSModuleHandle);
+ VCB(SETPATH, setComponentPath);
+ CB(GETPATH, getComponentPath);
+END_DISPATCH;
+#undef CBCLASS
+
+#ifdef WASABINOMAINAPI
+
+api_application *applicationApi = NULL;
+api_service *serviceApi = NULL;
+api_syscb *sysCallbackApi = NULL;
+
+
+api_memmgr *memmgrApi = NULL;
+
+#ifdef WASABI_COMPILE_CONFIG
+api_config *configApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_IMGLDR
+imgldr_api *imgLoaderApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_FONTS
+api_font *fontApi = NULL;
+#endif
+
+
+#ifdef WASABI_COMPILE_FILEREADER
+api_fileReader *fileApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_LOCALES
+api_locales *localesApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_TIMERS
+timer_api *timerApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_WND
+wnd_api *wndApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+wndmgr_api *wndManagerApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_COMPONENTS
+#endif
+
+#ifdef WASABI_COMPILE_METADB
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+api_maki *makiApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+api_skin *skinApi;
+#endif
+
+#ifdef WASABI_COMPILE_MAKIDEBUG
+api_makiDebugger *debugApi = NULL;
+#endif
+
+#ifdef WASABI_COMPILE_MEDIACORE
+api_core *coreApi = NULL;
+#endif
+
+#endif // ifdef WASABINOMAINAPI \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/PaintCanvas.h b/Src/Wasabi/api/wnd/PaintCanvas.h
new file mode 100644
index 00000000..165dcd23
--- /dev/null
+++ b/Src/Wasabi/api/wnd/PaintCanvas.h
@@ -0,0 +1,3 @@
+#ifdef __APPLE__
+#include <api/wnd/platform/osx/PaintCanvas.h>
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/accessible.cpp b/Src/Wasabi/api/wnd/accessible.cpp
new file mode 100644
index 00000000..2cefc41b
--- /dev/null
+++ b/Src/Wasabi/api/wnd/accessible.cpp
@@ -0,0 +1,16 @@
+#include "precomp.h"
+#include "accessible.h"
+
+#define CBCLASS AccessibleI
+START_DISPATCH;
+ CB(ACCESSIBLE_GETIACCESSIBLE, getIAccessible);
+ CB(ACCESSIBLE_GETOSHANDLE, getOSHandle);
+ VCB(ACCESSIBLE_RELEASE, release);
+ VCB(ACCESSIBLE_ADDREF, addRef);
+ CB(ACCESSIBLE_GETNUMREFS, getNumRefs);
+ VCB(ACCESSIBLE_ONGETFOCUS, onGetFocus);
+ VCB(ACCESSIBLE_ONSETNAME, onSetName);
+ CB(ACCESSIBLE_GETOSWND, getOSWnd);
+ VCB(ACCESSIBLE_ONSTATECHANGE, onStateChange);
+ CB(ACCESSIBLE_FLATTENCONTENT, flattenContent);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/wnd/accessible.h b/Src/Wasabi/api/wnd/accessible.h
new file mode 100644
index 00000000..13e544bb
--- /dev/null
+++ b/Src/Wasabi/api/wnd/accessible.h
@@ -0,0 +1,622 @@
+#ifndef __ACCESSIBLE_H
+#define __ACCESSIBLE_H
+
+#include <bfc/common.h>
+
+// Message sent to the OS window in order to retrieve an accessibility interface
+#define WM_GETOBJECT 0x003D
+
+// undef some stuff we're gonna #define ourselves
+#ifdef OBJID_WINDOW
+#undef OBJID_WINDOW
+#endif
+#ifdef OBJID_SYSMENU
+#undef OBJID_SYSMENU
+#endif
+#ifdef OBJID_TITLEBAR
+#undef OBJID_TITLEBAR
+#endif
+#ifdef OBJID_MENU
+#undef OBJID_MENU
+#endif
+#ifdef OBJID_CLIENT
+#undef OBJID_CLIENT
+#endif
+#ifdef OBJID_VSCROLL
+#undef OBJID_VSCROLL
+#endif
+#ifdef OBJID_HSCROLL
+#undef OBJID_HSCROLL
+#endif
+#ifdef OBJID_SIZEGRIP
+#undef OBJID_SIZEGRIP
+#endif
+#ifdef OBJID_CARET
+#undef OBJID_CARET
+#endif
+#ifdef OBJID_CURSOR
+#undef OBJID_CURSOR
+#endif
+#ifdef OBJID_ALERT
+#undef OBJID_ALERT
+#endif
+#ifdef OBJID_SOUND
+#undef OBJID_SOUND
+#endif
+#ifdef STATE_SYSTEM_VALID
+#undef STATE_SYSTEM_VALID
+#endif // STATE_SYSTEM_VALID
+
+// Accessibility system object IDs
+#define OBJID_WINDOW 0x00000000
+#define OBJID_SYSMENU 0xFFFFFFFF
+#define OBJID_TITLEBAR 0xFFFFFFFE
+#define OBJID_MENU 0xFFFFFFFD
+#define OBJID_CLIENT 0xFFFFFFFC
+#define OBJID_VSCROLL 0xFFFFFFFB
+#define OBJID_HSCROLL 0xFFFFFFFA
+#define OBJID_SIZEGRIP 0xFFFFFFF9
+#define OBJID_CARET 0xFFFFFFF8
+#define OBJID_CURSOR 0xFFFFFFF7
+#define OBJID_ALERT 0xFFFFFFF6
+#define OBJID_SOUND 0xFFFFFFF5
+
+#if 0
+#define ROLE_SYSTEM_TITLEBAR 0x00000001
+#define ROLE_SYSTEM_MENUBAR 0x00000002
+#define ROLE_SYSTEM_SCROLLBAR 0x00000003
+#define ROLE_SYSTEM_GRIP 0x00000004
+#define ROLE_SYSTEM_SOUND 0x00000005
+#define ROLE_SYSTEM_CURSOR 0x00000006
+#define ROLE_SYSTEM_CARET 0x00000007
+#define ROLE_SYSTEM_ALERT 0x00000008
+#define ROLE_SYSTEM_WINDOW 0x00000009
+#define ROLE_SYSTEM_CLIENT 0x0000000A
+#define ROLE_SYSTEM_MENUPOPUP 0x0000000B
+#define ROLE_SYSTEM_MENUITEM 0x0000000C
+#define ROLE_SYSTEM_TOOLTIP 0x0000000D
+#define ROLE_SYSTEM_APPLICATION 0x0000000E
+#define ROLE_SYSTEM_DOCUMENT 0x0000000F
+#define ROLE_SYSTEM_PANE 0x00000010
+#define ROLE_SYSTEM_CHART 0x00000011
+#define ROLE_SYSTEM_DIALOG 0x00000012
+#define ROLE_SYSTEM_BORDER 0x00000013
+#define ROLE_SYSTEM_GROUPING 0x00000014
+#define ROLE_SYSTEM_SEPARATOR 0x00000015
+#define ROLE_SYSTEM_TOOLBAR 0x00000016
+#define ROLE_SYSTEM_STATUSBAR 0x00000017
+#define ROLE_SYSTEM_TABLE 0x00000018
+#define ROLE_SYSTEM_COLUMNHEADER 0x00000019
+#define ROLE_SYSTEM_ROWHEADER 0x0000001A
+#define ROLE_SYSTEM_COLUMN 0x0000001B
+#define ROLE_SYSTEM_ROW 0x0000001C
+#define ROLE_SYSTEM_CELL 0x0000001D
+#define ROLE_SYSTEM_LINK 0x0000001E
+#define ROLE_SYSTEM_HELPBALLOON 0x0000001F
+#define ROLE_SYSTEM_CHARACTER 0x00000020
+#define ROLE_SYSTEM_LIST 0x00000021
+#define ROLE_SYSTEM_LISTITEM 0x00000022
+#define ROLE_SYSTEM_OUTLINE 0x00000023
+#define ROLE_SYSTEM_OUTLINEITEM 0x00000024
+#define ROLE_SYSTEM_PAGETAB 0x00000025
+#define ROLE_SYSTEM_PROPERTYPAGE 0x00000026
+#define ROLE_SYSTEM_INDICATOR 0x00000027
+#define ROLE_SYSTEM_GRAPHIC 0x00000028
+#define ROLE_SYSTEM_STATICTEXT 0x00000029
+#define ROLE_SYSTEM_TEXT 0x0000002A // Editable, selectable, etc.
+#define ROLE_SYSTEM_PUSHBUTTON 0x0000002B
+#define ROLE_SYSTEM_CHECKBUTTON 0x0000002C
+#define ROLE_SYSTEM_RADIOBUTTON 0x0000002D
+#define ROLE_SYSTEM_COMBOBOX 0x0000002E
+#define ROLE_SYSTEM_DROPLIST 0x0000002F
+#define ROLE_SYSTEM_PROGRESSBAR 0x00000030
+#define ROLE_SYSTEM_DIAL 0x00000031
+#define ROLE_SYSTEM_HOTKEYFIELD 0x00000032
+#define ROLE_SYSTEM_SLIDER 0x00000033
+#define ROLE_SYSTEM_SPINBUTTON 0x00000034
+#define ROLE_SYSTEM_DIAGRAM 0x00000035
+#define ROLE_SYSTEM_ANIMATION 0x00000036
+#define ROLE_SYSTEM_EQUATION 0x00000037
+#define ROLE_SYSTEM_BUTTONDROPDOWN 0x00000038
+#define ROLE_SYSTEM_BUTTONMENU 0x00000039
+#define ROLE_SYSTEM_BUTTONDROPDOWNGRID 0x0000003A
+#define ROLE_SYSTEM_WHITESPACE 0x0000003B
+#define ROLE_SYSTEM_PAGETABLIST 0x0000003C
+#define ROLE_SYSTEM_CLOCK 0x0000003D
+#endif
+#define STATE_SYSTEM_UNAVAILABLE 0x00000001 // Disabled
+#define STATE_SYSTEM_SELECTED 0x00000002
+#define STATE_SYSTEM_FOCUSED 0x00000004
+#define STATE_SYSTEM_PRESSED 0x00000008
+#define STATE_SYSTEM_CHECKED 0x00000010
+#define STATE_SYSTEM_MIXED 0x00000020 // 3-state checkbox or toolbar button
+#define STATE_SYSTEM_READONLY 0x00000040
+#define STATE_SYSTEM_HOTTRACKED 0x00000080
+#define STATE_SYSTEM_DEFAULT 0x00000100
+#define STATE_SYSTEM_EXPANDED 0x00000200
+#define STATE_SYSTEM_COLLAPSED 0x00000400
+#define STATE_SYSTEM_BUSY 0x00000800
+#define STATE_SYSTEM_FLOATING 0x00001000 // Children "owned" not "contained" by parent
+#define STATE_SYSTEM_MARQUEED 0x00002000
+#define STATE_SYSTEM_ANIMATED 0x00004000
+#define STATE_SYSTEM_INVISIBLE 0x00008000
+#define STATE_SYSTEM_OFFSCREEN 0x00010000
+#define STATE_SYSTEM_SIZEABLE 0x00020000
+#define STATE_SYSTEM_MOVEABLE 0x00040000
+#define STATE_SYSTEM_SELFVOICING 0x00080000
+#define STATE_SYSTEM_FOCUSABLE 0x00100000
+#define STATE_SYSTEM_SELECTABLE 0x00200000
+#define STATE_SYSTEM_LINKED 0x00400000
+#define STATE_SYSTEM_TRAVERSED 0x00800000
+#define STATE_SYSTEM_MULTISELECTABLE 0x01000000 // Supports multiple selection
+#define STATE_SYSTEM_EXTSELECTABLE 0x02000000 // Supports extended selection
+#define STATE_SYSTEM_ALERT_LOW 0x04000000 // This information is of low priority
+#define STATE_SYSTEM_ALERT_MEDIUM 0x08000000 // This information is of medium priority
+#define STATE_SYSTEM_ALERT_HIGH 0x10000000 // This information is of high priority
+
+#define STATE_SYSTEM_VALID 0x1FFFFFFF
+
+/*
+ * Reserved IDs for system objects
+ */
+#define OBJID_WINDOW 0x00000000
+#define OBJID_SYSMENU 0xFFFFFFFF
+#define OBJID_TITLEBAR 0xFFFFFFFE
+#define OBJID_MENU 0xFFFFFFFD
+#define OBJID_CLIENT 0xFFFFFFFC
+#define OBJID_VSCROLL 0xFFFFFFFB
+#define OBJID_HSCROLL 0xFFFFFFFA
+#define OBJID_SIZEGRIP 0xFFFFFFF9
+#define OBJID_CARET 0xFFFFFFF8
+#define OBJID_CURSOR 0xFFFFFFF7
+#define OBJID_ALERT 0xFFFFFFF6
+#define OBJID_SOUND 0xFFFFFFF5
+
+/*
+ * EVENT DEFINITION
+ */
+#define EVENT_MIN 0x00000001
+#define EVENT_MAX 0x7FFFFFFF
+
+
+/*
+ * EVENT_SYSTEM_SOUND
+ * Sent when a sound is played. Currently nothing is generating this, we
+ * this event when a system sound (for menus, etc) is played. Apps
+ * generate this, if accessible, when a private sound is played. For
+ * example, if Mail plays a "New Mail" sound.
+ *
+ * System Sounds:
+ * (Generated by PlaySoundEvent in USER itself)
+ * hwnd is NULL
+ * idObject is OBJID_SOUND
+ * idChild is sound child ID if one
+ * App Sounds:
+ * (PlaySoundEvent won't generate notification; up to app)
+ * hwnd + idObject gets interface pointer to Sound object
+ * idChild identifies the sound in question
+ * are going to be cleaning up the SOUNDSENTRY feature in the control panel
+ * and will use this at that time. Applications implementing WinEvents
+ * are perfectly welcome to use it. Clients of IAccessible* will simply
+ * turn around and get back a non-visual object that describes the sound.
+ */
+#define EVENT_SYSTEM_SOUND 0x0001
+
+/*
+ * EVENT_SYSTEM_ALERT
+ * System Alerts:
+ * (Generated by MessageBox() calls for example)
+ * hwnd is hwndMessageBox
+ * idObject is OBJID_ALERT
+ * App Alerts:
+ * (Generated whenever)
+ * hwnd+idObject gets interface pointer to Alert
+ */
+#define EVENT_SYSTEM_ALERT 0x0002
+
+/*
+ * EVENT_SYSTEM_FOREGROUND
+ * Sent when the foreground (active) window changes, even if it is changing
+ * to another window in the same thread as the previous one.
+ * hwnd is hwndNewForeground
+ * idObject is OBJID_WINDOW
+ * idChild is INDEXID_OBJECT
+ */
+#define EVENT_SYSTEM_FOREGROUND 0x0003
+
+/*
+ * Menu
+ * hwnd is window (top level window or popup menu window)
+ * idObject is ID of control (OBJID_MENU, OBJID_SYSMENU, OBJID_SELF for popup)
+ * idChild is CHILDID_SELF
+ *
+ * EVENT_SYSTEM_MENUSTART
+ * EVENT_SYSTEM_MENUEND
+ * For MENUSTART, hwnd+idObject+idChild refers to the control with the menu bar,
+ * or the control bringing up the context menu.
+ *
+ * Sent when entering into and leaving from menu mode (system, app bar, and
+ * track popups).
+ */
+#define EVENT_SYSTEM_MENUSTART 0x0004
+#define EVENT_SYSTEM_MENUEND 0x0005
+
+/*
+ * EVENT_SYSTEM_MENUPOPUPSTART
+ * EVENT_SYSTEM_MENUPOPUPEND
+ * Sent when a menu popup comes up and just before it is taken down. Note
+ * that for a call to TrackPopupMenu(), a client will see EVENT_SYSTEM_MENUSTART
+ * followed almost immediately by EVENT_SYSTEM_MENUPOPUPSTART for the popup
+ * being shown.
+ *
+ * For MENUPOPUP, hwnd+idObject+idChild refers to the NEW popup coming up, not the
+ * parent item which is hierarchical. You can get the parent menu/popup by
+ * asking for the accParent object.
+ */
+#define EVENT_SYSTEM_MENUPOPUPSTART 0x0006
+#define EVENT_SYSTEM_MENUPOPUPEND 0x0007
+
+
+/*
+ * EVENT_SYSTEM_CAPTURESTART
+ * EVENT_SYSTEM_CAPTUREEND
+ * Sent when a window takes the capture and releases the capture.
+ */
+#define EVENT_SYSTEM_CAPTURESTART 0x0008
+#define EVENT_SYSTEM_CAPTUREEND 0x0009
+
+/*
+ * Move Size
+ * EVENT_SYSTEM_MOVESIZESTART
+ * EVENT_SYSTEM_MOVESIZEEND
+ * Sent when a window enters and leaves move-size dragging mode.
+ */
+#define EVENT_SYSTEM_MOVESIZESTART 0x000A
+#define EVENT_SYSTEM_MOVESIZEEND 0x000B
+
+/*
+ * Context Help
+ * EVENT_SYSTEM_CONTEXTHELPSTART
+ * EVENT_SYSTEM_CONTEXTHELPEND
+ * Sent when a window enters and leaves context sensitive help mode.
+ */
+#define EVENT_SYSTEM_CONTEXTHELPSTART 0x000C
+#define EVENT_SYSTEM_CONTEXTHELPEND 0x000D
+
+/*
+ * Drag & Drop
+ * EVENT_SYSTEM_DRAGDROPSTART
+ * EVENT_SYSTEM_DRAGDROPEND
+ * Send the START notification just before going into drag&drop loop. Send
+ * the END notification just after canceling out.
+ * Note that it is up to apps and OLE to generate this, since the system
+ * doesn't know. Like EVENT_SYSTEM_SOUND, it will be a while before this
+ * is prevalent.
+ */
+#define EVENT_SYSTEM_DRAGDROPSTART 0x000E
+#define EVENT_SYSTEM_DRAGDROPEND 0x000F
+
+/*
+ * Dialog
+ * Send the START notification right after the dialog is completely
+ * initialized and visible. Send the END right before the dialog
+ * is hidden and goes away.
+ * EVENT_SYSTEM_DIALOGSTART
+ * EVENT_SYSTEM_DIALOGEND
+ */
+#define EVENT_SYSTEM_DIALOGSTART 0x0010
+#define EVENT_SYSTEM_DIALOGEND 0x0011
+
+/*
+ * EVENT_SYSTEM_SCROLLING
+ * EVENT_SYSTEM_SCROLLINGSTART
+ * EVENT_SYSTEM_SCROLLINGEND
+ * Sent when beginning and ending the tracking of a scrollbar in a window,
+ * and also for scrollbar controls.
+ */
+#define EVENT_SYSTEM_SCROLLINGSTART 0x0012
+#define EVENT_SYSTEM_SCROLLINGEND 0x0013
+
+/*
+ * Alt-Tab Window
+ * Send the START notification right after the switch window is initialized
+ * and visible. Send the END right before it is hidden and goes away.
+ * EVENT_SYSTEM_SWITCHSTART
+ * EVENT_SYSTEM_SWITCHEND
+ */
+#define EVENT_SYSTEM_SWITCHSTART 0x0014
+#define EVENT_SYSTEM_SWITCHEND 0x0015
+
+/*
+ * EVENT_SYSTEM_MINIMIZESTART
+ * EVENT_SYSTEM_MINIMIZEEND
+ * Sent when a window minimizes and just before it restores.
+ */
+#define EVENT_SYSTEM_MINIMIZESTART 0x0016
+#define EVENT_SYSTEM_MINIMIZEEND 0x0017
+
+
+
+/*
+ * Object events
+ *
+ * The system AND apps generate these. The system generates these for
+ * real windows. Apps generate these for objects within their window which
+ * act like a separate control, e.g. an item in a list view.
+ *
+ * When the system generate them, dwParam2 is always WMOBJID_SELF. When
+ * apps generate them, apps put the has-meaning-to-the-app-only ID value
+ * in dwParam2.
+ * For all events, if you want detailed accessibility information, callers
+ * should
+ * * Call AccessibleObjectFromWindow() with the hwnd, idObject parameters
+ * of the event, and IID_IAccessible as the REFIID, to get back an
+ * IAccessible* to talk to
+ * * Initialize and fill in a VARIANT as VT_I4 with lVal the idChild
+ * parameter of the event.
+ * * If idChild isn't zero, call get_accChild() in the container to see
+ * if the child is an object in its own right. If so, you will get
+ * back an IDispatch* object for the child. You should release the
+ * parent, and call QueryInterface() on the child object to get its
+ * IAccessible*. Then you talk directly to the child. Otherwise,
+ * if get_accChild() returns you nothing, you should continue to
+ * use the child VARIANT. You will ask the container for the properties
+ * of the child identified by the VARIANT. In other words, the
+ * child in this case is accessible but not a full-blown object.
+ * Like a button on a titlebar which is 'small' and has no children.
+ */
+
+/*
+ * For all EVENT_OBJECT events,
+ * hwnd is the dude to Send the WM_GETOBJECT message to (unless NULL,
+ * see above for system things)
+ * idObject is the ID of the object that can resolve any queries a
+ * client might have. It's a way to deal with windowless controls,
+ * controls that are just drawn on the screen in some larger parent
+ * window (like SDM), or standard frame elements of a window.
+ * idChild is the piece inside of the object that is affected. This
+ * allows clients to access things that are too small to have full
+ * blown objects in their own right. Like the thumb of a scrollbar.
+ * The hwnd/idObject pair gets you to the container, the dude you
+ * probably want to talk to most of the time anyway. The idChild
+ * can then be passed into the acc properties to get the name/value
+ * of it as needed.
+ *
+ * Example #1:
+ * System propagating a listbox selection change
+ * EVENT_OBJECT_SELECTION
+ * hwnd == listbox hwnd
+ * idObject == OBJID_WINDOW
+ * idChild == new selected item, or CHILDID_SELF if
+ * nothing now selected within container.
+ * Word '97 propagating a listbox selection change
+ * hwnd == SDM window
+ * idObject == SDM ID to get at listbox 'control'
+ * idChild == new selected item, or CHILDID_SELF if
+ * nothing
+ *
+ * Example #2:
+ * System propagating a menu item selection on the menu bar
+ * EVENT_OBJECT_SELECTION
+ * hwnd == top level window
+ * idObject == OBJID_MENU
+ * idChild == ID of child menu bar item selected
+ *
+ * Example #3:
+ * System propagating a dropdown coming off of said menu bar item
+ * EVENT_OBJECT_CREATE
+ * hwnd == popup item
+ * idObject == OBJID_WINDOW
+ * idChild == CHILDID_SELF
+ *
+ * Example #4:
+ *
+ * For EVENT_OBJECT_REORDER, the object referred to by hwnd/idObject is the
+ * PARENT container in which the zorder is occurring. This is because if
+ * one child is zordering, all of them are changing their relative zorder.
+ */
+#define EVENT_OBJECT_CREATE 0x8000 // hwnd + ID + idChild is created item
+#define EVENT_OBJECT_DESTROY 0x8001 // hwnd + ID + idChild is destroyed item
+#define EVENT_OBJECT_SHOW 0x8002 // hwnd + ID + idChild is shown item
+#define EVENT_OBJECT_HIDE 0x8003 // hwnd + ID + idChild is hidden item
+#define EVENT_OBJECT_REORDER 0x8004 // hwnd + ID + idChild is parent of zordering children
+/*
+ * NOTE:
+ * Minimize the number of notifications!
+ *
+ * When you are hiding a parent object, obviously all child objects are no
+ * longer visible on screen. They still have the same "visible" status,
+ * but are not truly visible. Hence do not send HIDE notifications for the
+ * children also. One implies all. The same goes for SHOW.
+ */
+
+
+#define EVENT_OBJECT_FOCUS 0x8005 // hwnd + ID + idChild is focused item
+#define EVENT_OBJECT_SELECTION 0x8006 // hwnd + ID + idChild is selected item (if only one), or idChild is OBJID_WINDOW if complex
+#define EVENT_OBJECT_SELECTIONADD 0x8007 // hwnd + ID + idChild is item added
+#define EVENT_OBJECT_SELECTIONREMOVE 0x8008 // hwnd + ID + idChild is item removed
+#define EVENT_OBJECT_SELECTIONWITHIN 0x8009 // hwnd + ID + idChild is parent of changed selected items
+
+/*
+ * NOTES:
+ * There is only one "focused" child item in a parent. This is the place
+ * keystrokes are going at a given moment. Hence only send a notification
+ * about where the NEW focus is going. A NEW item getting the focus already
+ * implies that the OLD item is losing it.
+ *
+ * SELECTION however can be multiple. Hence the different SELECTION
+ * notifications. Here's when to use each:
+ *
+ * (1) Send a SELECTION notification in the simple single selection
+ * case (like the focus) when the item with the selection is
+ * merely moving to a different item within a container. hwnd + ID
+ * is the container control, idChildItem is the new child with the
+ * selection.
+ *
+ * (2) Send a SELECTIONADD notification when a new item has simply been added
+ * to the selection within a container. This is appropriate when the
+ * number of newly selected items is very small. hwnd + ID is the
+ * container control, idChildItem is the new child added to the selection.
+ *
+ * (3) Send a SELECTIONREMOVE notification when a new item has simply been
+ * removed from the selection within a container. This is appropriate
+ * when the number of newly selected items is very small, just like
+ * SELECTIONADD. hwnd + ID is the container control, idChildItem is the
+ * new child removed from the selection.
+ *
+ * (4) Send a SELECTIONWITHIN notification when the selected items within a
+ * control have changed substantially. Rather than propagate a large
+ * number of changes to reflect removal for some items, addition of
+ * others, just tell somebody who cares that a lot happened. It will
+ * be faster an easier for somebody watching to just turn around and
+ * query the container control what the new bunch of selected items
+ * are.
+ */
+
+#define EVENT_OBJECT_STATECHANGE 0x800A // hwnd + ID + idChild is item w/ state change
+/*
+ * Examples of when to send an EVENT_OBJECT_STATECHANGE include
+ * * It is being enabled/disabled (USER does for windows)
+ * * It is being pressed/released (USER does for buttons)
+ * * It is being checked/unchecked (USER does for radio/check buttons)
+ */
+#define EVENT_OBJECT_LOCATIONCHANGE 0x800B // hwnd + ID + idChild is moved/sized item
+
+/*
+ * Note:
+ * A LOCATIONCHANGE is not sent for every child object when the parent
+ * changes shape/moves. Send one notification for the topmost object
+ * that is changing. For example, if the user resizes a top level window,
+ * USER will generate a LOCATIONCHANGE for it, but not for the menu bar,
+ * title bar, scrollbars, etc. that are also changing shape/moving.
+ *
+ * In other words, it only generates LOCATIONCHANGE notifications for
+ * real windows that are moving/sizing. It will not generate a LOCATIONCHANGE
+ * for every non-floating child window when the parent moves (the children are
+ * logically moving also on screen, but not relative to the parent).
+ *
+ * Now, if the app itself resizes child windows as a result of being
+ * sized, USER will generate LOCATIONCHANGEs for those dudes also because
+ * it doesn't know better.
+ *
+ * Note also that USER will generate LOCATIONCHANGE notifications for two
+ * non-window sys objects:
+ * (1) System caret
+ * (2) Cursor
+ */
+
+#define EVENT_OBJECT_NAMECHANGE 0x800C // hwnd + ID + idChild is item w/ name change
+#define EVENT_OBJECT_DESCRIPTIONCHANGE 0x800D // hwnd + ID + idChild is item w/ desc change
+#define EVENT_OBJECT_VALUECHANGE 0x800E // hwnd + ID + idChild is item w/ value change
+#define EVENT_OBJECT_PARENTCHANGE 0x800F // hwnd + ID + idChild is item w/ new parent
+#define EVENT_OBJECT_HELPCHANGE 0x8010 // hwnd + ID + idChild is item w/ help change
+#define EVENT_OBJECT_DEFACTIONCHANGE 0x8011 // hwnd + ID + idChild is item w/ def action change
+#define EVENT_OBJECT_ACCELERATORCHANGE 0x8012 // hwnd + ID + idChild is item w/ keybd accel change
+
+#ifdef WIN32
+WINUSERAPI VOID WINAPI
+NotifyWinEvent(
+ DWORD event,
+ HWND hwnd,
+ LONG idObject,
+ LONG idChild);
+#endif
+
+#include <bfc/dispatch.h>
+
+struct IAccessible;
+
+class Accessible : public Dispatchable {
+ public:
+ IAccessible *getIAccessible();
+#ifdef _WIN32
+ HRESULT getOSHandle(int p);
+#endif
+ void release();
+ void addRef();
+ int getNumRefs();
+ void onGetFocus(int idx=-1);
+ void onStateChange(int idx=-1);
+ void onSetName(const wchar_t *newname, int idx=-1);
+ OSWINDOWHANDLE getOSWnd();
+ int flattenContent(OSWINDOWHANDLE *w);
+
+ enum {
+ ACCESSIBLE_GETIACCESSIBLE=10,
+ ACCESSIBLE_GETOSHANDLE=20,
+ ACCESSIBLE_ADDREF=30,
+ ACCESSIBLE_RELEASE=40,
+ ACCESSIBLE_GETNUMREFS=50,
+ ACCESSIBLE_ONGETFOCUS=60,
+ ACCESSIBLE_ONSETNAME=70,
+ ACCESSIBLE_GETOSWND=80,
+ ACCESSIBLE_ONSTATECHANGE=90,
+ ACCESSIBLE_FLATTENCONTENT=100,
+ };
+};
+
+inline IAccessible *Accessible::getIAccessible() {
+ return _call(ACCESSIBLE_GETIACCESSIBLE, (IAccessible *)NULL);
+}
+
+#ifdef _WIN32
+inline HRESULT Accessible::getOSHandle(int p) {
+ return _call(ACCESSIBLE_GETOSHANDLE, (HRESULT)NULL, p);
+}
+#endif
+
+inline void Accessible::addRef() {
+ _voidcall(ACCESSIBLE_ADDREF);
+}
+
+inline void Accessible::release() {
+ _voidcall(ACCESSIBLE_RELEASE);
+}
+
+inline int Accessible::getNumRefs() {
+ return _call(ACCESSIBLE_GETNUMREFS, 0);
+}
+
+inline void Accessible::onGetFocus(int idx/* =-1 */) {
+ _voidcall(ACCESSIBLE_ONGETFOCUS, idx);
+}
+
+inline void Accessible::onSetName(const wchar_t *name, int idx) {
+ _voidcall(ACCESSIBLE_ONSETNAME, name, idx);
+}
+
+inline OSWINDOWHANDLE Accessible::getOSWnd() {
+ return _call(ACCESSIBLE_GETOSWND, (OSWINDOWHANDLE)NULL);
+}
+
+inline void Accessible::onStateChange(int idx/* =-1 */) {
+ _voidcall(ACCESSIBLE_ONSTATECHANGE, idx);
+}
+
+inline int Accessible::flattenContent(OSWINDOWHANDLE *w) {
+ return _call(ACCESSIBLE_FLATTENCONTENT, 0, w);
+}
+
+class AccessibleI : public Accessible {
+ public:
+ AccessibleI() {}
+ virtual ~AccessibleI() {}
+
+ virtual IAccessible *getIAccessible()=0;
+#ifdef _WIN32
+ virtual HRESULT getOSHandle(int p)=0;
+#endif
+ virtual void release()=0;
+ virtual void addRef()=0;
+ virtual int getNumRefs()=0;
+ virtual void onGetFocus(int idx=-1)=0;
+ virtual void onSetName(const wchar_t *name, int idx)=0;
+ virtual OSWINDOWHANDLE getOSWnd()=0;
+ virtual void onStateChange(int idx=-1)=0;
+ virtual int flattenContent(OSWINDOWHANDLE *w)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/api_canvas.cpp b/Src/Wasabi/api/wnd/api_canvas.cpp
new file mode 100644
index 00000000..e170572f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_canvas.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "ifc_canvas.h"
diff --git a/Src/Wasabi/api/wnd/api_canvas.h b/Src/Wasabi/api/wnd/api_canvas.h
new file mode 100644
index 00000000..513d6c47
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_canvas.h
@@ -0,0 +1,163 @@
+#ifndef __WASABI_API_CANVAS_H
+#define __WASABI_API_CANVAS_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/platform.h>
+#include <api/service/svcs/svc_font.h> // for STDFONT_* stuff. should make a std_font thingy later
+#include <bfc/std.h> // for WASABI_DEFAULT_FONTNAMEW
+
+namespace Wasabi
+{
+ // benski> move this to std_font later
+struct FontInfo
+{
+ FontInfo()
+ {
+ // defaults
+ face = WASABI_DEFAULT_FONTNAMEW;
+ pointSize = 12;
+ bold = 0;
+ opaque = false;
+ underline = false;
+ italic = false;
+ alignFlags = STDFONT_LEFT;
+ antialias = 1;
+ bgColor = RGBA(255, 255, 255, 255);
+ color = RGBA(0, 0, 0, 0);
+ }
+
+ const wchar_t *face;
+ unsigned int pointSize;
+ int bold; // bold level
+ bool opaque;
+ bool underline;
+ bool italic;
+ int alignFlags;
+ int antialias; // anti-alias level
+ ARGB32 color;
+ ARGB32 bgColor;
+};
+}
+
+class ifc_window;
+// abstract base class: safe to use in API
+class NOVTABLE ifc_canvas : public Dispatchable
+{
+protected:
+ ifc_canvas()
+ {} // protect constructor
+ ~ifc_canvas()
+ {}
+
+public:
+ DISPATCH_CODES
+ {
+ GETHDC = 100,
+ GETROOTWND = 200,
+ GETBITS = 300,
+ GETOFFSETS = 400,
+ ISFIXEDCOORDS = 500,
+ GETDIM = 600,
+ GETTEXTFONT = 700,
+ GETTEXTSIZE = 710,
+ GETTEXTBOLD = 720,
+ GETTEXTOPAQUE = 730,
+ GETTEXTALIGN = 740,
+ GETTEXTCOLOR = 750,
+ GETTEXTBKCOLOR = 760,
+ GETTEXTAA = 770,
+ GETTEXTUNDERLINE = 780,
+ GETTEXTITALIC = 790,
+ GETCLIPBOX = 800,
+ };
+public:
+ HDC getHDC();
+ ifc_window *getRootWnd();
+ void *getBits();
+ void getOffsets(int *x, int *y);
+ bool isFixedCoords(); //FG> allows onPaint to handle double buffers as well as normal DCs
+ bool getDim(int *w, int *h = NULL, int *p = NULL); // w & h in pixels, pitch in bytes. 0 on success.
+ int getClipBox(RECT *r); // returns 0 if no clipping region
+ const wchar_t *getTextFont();
+ int getTextSize();
+ int getTextBold();
+ int getTextAntialias();
+ int getTextOpaque();
+ int getTextUnderline();
+ int getTextItalic();
+ int getTextAlign();
+ ARGB32 getTextColor();
+ ARGB32 getTextBkColor();
+};
+
+
+inline HDC ifc_canvas::getHDC()
+{
+ return _call(ifc_canvas::GETHDC, (HDC)0);
+}
+inline ifc_window *ifc_canvas::getRootWnd()
+{
+ return _call(ifc_canvas::GETROOTWND, (ifc_window*)0);
+}
+inline void *ifc_canvas::getBits()
+{
+ return _call(ifc_canvas::GETBITS, (void *)0);
+}
+inline void ifc_canvas::getOffsets(int *x, int *y)
+{
+ _voidcall(ifc_canvas::GETOFFSETS, x, y);
+}
+inline bool ifc_canvas::isFixedCoords()
+{ //FG> allows onPaint to handle double buffers as well as normal DCs
+ return _call(ifc_canvas::ISFIXEDCOORDS, false);
+}
+inline bool ifc_canvas::getDim(int *w, int *h, int *p)
+{ // w & h in pixels, pitch in bytes. 0 on success.
+ return _call(ifc_canvas::GETDIM, false, w, h, p);
+}
+inline int ifc_canvas::getClipBox(RECT *r)
+{ // returns 0 if no clipping region
+ return _call(ifc_canvas::GETCLIPBOX, 0, r);
+}
+
+inline const wchar_t *ifc_canvas::getTextFont()
+{
+ return _call(ifc_canvas::GETTEXTFONT, L"");
+}
+inline int ifc_canvas::getTextSize()
+{
+ return _call(ifc_canvas::GETTEXTSIZE, -1);
+}
+inline int ifc_canvas::getTextBold()
+{
+ return _call(ifc_canvas::GETTEXTBOLD, 0);
+}
+inline int ifc_canvas::getTextAntialias()
+{
+ return _call(ifc_canvas::GETTEXTAA, 0);
+}
+inline int ifc_canvas::getTextOpaque()
+{
+ return _call(ifc_canvas::GETTEXTOPAQUE, 0);
+}
+inline int ifc_canvas::getTextUnderline()
+{
+ return _call(ifc_canvas::GETTEXTUNDERLINE, 0);
+}
+inline int ifc_canvas::getTextItalic()
+{
+ return _call(ifc_canvas::GETTEXTITALIC, 0);
+}
+inline int ifc_canvas::getTextAlign()
+{
+ return _call(ifc_canvas::GETTEXTALIGN, -1);
+}
+inline ARGB32 ifc_canvas::getTextColor()
+{
+ return _call(ifc_canvas::GETTEXTCOLOR, RGB(0, 0, 0));
+}
+inline ARGB32 ifc_canvas::getTextBkColor()
+{
+ return _call(ifc_canvas::GETTEXTBKCOLOR, RGB(255, 255, 255));
+}
+#endif
diff --git a/Src/Wasabi/api/wnd/api_region.cpp b/Src/Wasabi/api/wnd/api_region.cpp
new file mode 100644
index 00000000..40063420
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_region.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include "api_region.h" \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/api_region.h b/Src/Wasabi/api/wnd/api_region.h
new file mode 100644
index 00000000..df184246
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_region.h
@@ -0,0 +1,200 @@
+#ifndef __WASABI_API_REGION_H
+#define __WASABI_API_REGION_H
+
+#include <bfc/dispatch.h>
+
+class api_region : public Dispatchable
+{
+protected:
+ api_region() {}
+ virtual ~api_region() {}
+
+public:
+ DISPATCH_CODES
+ {
+ REGION_GETOSHANDLE = 50,
+ REGION_CLONE = 100,
+ REGION_DISPOSECLONE = 110,
+ REGION_PTINREGION = 120,
+ REGION_OFFSET = 130,
+ REGION_GETBOX = 140,
+ REGION_SUBTRACTRGN = 150,
+ REGION_SUBTRACTRECT = 160,
+ REGION_ADDRECT = 170,
+ REGION_ADD = 180,
+ REGION_AND = 190,
+ REGION_SETRECT = 200,
+ REGION_EMPTY = 210,
+ REGION_ISEMPTY = 220,
+ REGION_EQUALS = 230,
+ REGION_ENCLOSED = 240,
+ REGION_INTERSECTRGN = 250,
+ REGION_DOESINTERSECTRGN = 251,
+ REGION_INTERSECTRECT = 260,
+ REGION_ISRECT = 270,
+ REGION_SCALE = 280,
+ REGION_DEBUG = 290,
+ REGION_MAKEWNDREGION = 300,
+ REGION_GETNUMRECTS = 310,
+ REGION_ENUMRECT = 320,
+ };
+public:
+ OSREGIONHANDLE getOSHandle(); // avoid as much as you can, should be used only when you need to call the OS api
+
+ api_region *clone();
+ void disposeClone(api_region *r);
+ bool ptInRegion(const POINT *pt);
+ void offset(int x, int y);
+ void getBox(RECT *r);
+ void subtractRegion(const api_region *r);
+ void subtractRgn(const api_region *r) { subtractRegion(r); } //DEPRECATED
+ void subtractRect(const RECT *r);
+ void addRect(const RECT *r);
+ void addRegion(const api_region *r);
+ void andRegion(const api_region *r);
+ void setRect(const RECT *r);
+ void empty();
+ int isEmpty();
+ int equals(const api_region *r);
+ int enclosed(const api_region *r, api_region *outside = NULL);
+ int intersectRgn(const api_region *r, api_region *intersection);
+ int doesIntersectRgn(const api_region *r);
+ int intersectRect(const RECT *r, api_region *intersection);
+
+ int isRect();
+ void scale(double sx, double sy, bool round = 0);
+ void debug(int async = 0);
+ OSREGIONHANDLE makeWindowRegion(); // gives you a handle to a clone of the OSREGION object so you can insert it into a window's region with SetWindowRgn. ANY other use is prohibited
+
+ // this is how you can enumerate the subrects that compose to make up the
+ // entire region
+ int getNumRects();
+ int enumRect(int n, RECT *r);
+};
+
+inline OSREGIONHANDLE api_region::getOSHandle()
+{
+ return _call(REGION_GETOSHANDLE, (OSREGIONHANDLE)NULL);
+}
+
+inline api_region *api_region::clone()
+{
+ return _call(REGION_CLONE, (api_region *)NULL);
+}
+
+inline void api_region::disposeClone(api_region *r)
+{
+ _voidcall(REGION_DISPOSECLONE, r);
+}
+
+inline bool api_region::ptInRegion(const POINT *pt)
+{
+ return _call(REGION_PTINREGION, false, pt);
+}
+
+inline void api_region::offset(int x, int y)
+{
+ _voidcall(REGION_OFFSET, x, y);
+}
+
+inline void api_region::getBox(RECT *r)
+{
+ _voidcall(REGION_GETBOX, r);
+}
+
+inline void api_region::subtractRegion(const api_region *reg)
+{
+ _voidcall(REGION_SUBTRACTRGN, reg);
+}
+
+inline void api_region::subtractRect(const RECT *r)
+{
+ _voidcall(REGION_SUBTRACTRECT, r);
+}
+
+inline void api_region::addRect(const RECT *r)
+{
+ _voidcall(REGION_ADDRECT, r);
+}
+
+inline void api_region::addRegion(const api_region *r)
+{
+ _voidcall(REGION_ADD, r);
+}
+
+inline void api_region::andRegion(const api_region *r)
+{
+ _voidcall(REGION_AND, r);
+}
+
+inline void api_region::setRect(const RECT *r)
+{
+ _voidcall(REGION_SETRECT, r);
+}
+
+inline void api_region::empty()
+{
+ _voidcall(REGION_EMPTY);
+}
+
+inline int api_region::isEmpty()
+{
+ return _call(REGION_ISEMPTY, 0);
+}
+
+inline int api_region::equals(const api_region *r)
+{
+ return _call(REGION_EQUALS, 0, r);
+}
+
+inline int api_region::enclosed(const api_region *r, api_region *outside)
+{
+ return _call(REGION_ENCLOSED, 0, r, outside);
+}
+
+inline int api_region::intersectRgn(const api_region *r, api_region *intersection)
+{
+ return _call(REGION_INTERSECTRGN, 0, r, intersection);
+}
+
+inline int api_region::doesIntersectRgn(const api_region *r)
+{
+ return _call(REGION_DOESINTERSECTRGN, 0, r);
+}
+
+inline int api_region::intersectRect(const RECT *r, api_region *intersection)
+{
+ return _call(REGION_INTERSECTRECT, 0, r, intersection);
+}
+
+inline int api_region::isRect()
+{
+ return _call(REGION_ISRECT, 0);
+}
+
+inline void api_region::scale(double sx, double sy, bool round)
+{
+ _voidcall(REGION_SCALE, sx, sy, round);
+}
+
+inline void api_region::debug(int async)
+{
+ _voidcall(REGION_DEBUG, async);
+}
+
+inline OSREGIONHANDLE api_region::makeWindowRegion()
+{
+ return _call(REGION_MAKEWNDREGION, (OSREGIONHANDLE)NULL);
+}
+
+inline int api_region::getNumRects()
+{
+ return _call(REGION_GETNUMRECTS, 0);
+}
+
+inline int api_region::enumRect(int n, RECT *r)
+{
+ return _call(REGION_ENUMRECT, 0, n, r);
+}
+
+#endif
diff --git a/Src/Wasabi/api/wnd/api_window.cpp b/Src/Wasabi/api/wnd/api_window.cpp
new file mode 100644
index 00000000..537a3b2c
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_window.cpp
@@ -0,0 +1,3 @@
+#include <precomp.h>
+#include "api_window.h"
+
diff --git a/Src/Wasabi/api/wnd/api_window.h b/Src/Wasabi/api/wnd/api_window.h
new file mode 100644
index 00000000..3d6f1c00
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_window.h
@@ -0,0 +1,1277 @@
+#ifndef __WASABI_API_WINDOW_H
+#define __WASABI_API_WINDOW_H
+
+#include <bfc/dispatch.h>
+#include <api/wnd/drag.h>
+#include <api/wnd/cursor.h>
+#include <api/wnd/accessible.h>
+#include <tataki/canvas/Canvas.h>
+#include <api/dependency/api_dependent.h>
+#include <api/timer/timerclient.h>
+#include <api/script/objects/guiobject.h>
+enum WndPreferences {
+ SUGGESTED_X,
+ SUGGESTED_Y,
+ SUGGESTED_W,
+ SUGGESTED_H,
+ MINIMUM_W,
+ MINIMUM_H,
+ MAXIMUM_W,
+ MAXIMUM_H,
+};
+
+enum GetTab {
+ TAB_GETCURRENT,
+ TAB_GETNEXT,
+ TAB_GETPREVIOUS,
+ TAB_GETFIRST,
+ TAB_GETLAST,
+};
+
+
+#define MAXIMIZE_WIDTH 1
+#define MAXIMIZE_HEIGHT 2
+
+#define RESTORE_X 1
+#define RESTORE_Y 2
+#define RESTORE_HEIGHT 4
+#define RESTORE_WIDTH 8
+
+// popWindowRect flags
+#define PWR_X 1
+#define PWR_Y 2
+#define PWR_WIDTH 4
+#define PWR_HEIGHT 8
+#define PWR_DIMENTIONS (PWR_WIDTH|PWR_HEIGHT)
+#define PWR_POSITION (PWR_X|PWR_Y)
+
+class FindObjectCallback;
+
+class NOVTABLE ifc_window : public Dispatchable
+{
+protected:
+ ifc_window() {} // protect constructor
+public:
+ static const GUID *depend_getClassGuid() {
+ // {11981849-61F7-4158-8283-DA7DD006D732}
+ static const GUID ret =
+ { 0x11981849, 0x61f7, 0x4158, { 0x82, 0x83, 0xda, 0x7d, 0xd0, 0x6, 0xd7, 0x32 } };
+ return &ret;
+ }
+
+ // this passes thru to the windows WndProc, if there is one -- NONPORTABLE
+#if defined (_WIN32) || defined (_WIN64)
+ virtual LRESULT wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)=0;
+#elif defined(__APPLE__)
+ virtual OSStatus eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)=0;
+#endif
+
+ // get the OSWINDOWHANDLE (if there is one)
+ OSWINDOWHANDLE gethWnd() { return getOsWindowHandle(); } // stay back compatibile
+ OSWINDOWHANDLE getOsWindowHandle();
+ OSMODULEHANDLE getOsModuleHandle();
+ void performBatchProcesses(); // this is called after wndProc is called (under win32) to recompute batch operations such as calculating window regions, cascaderepainting, etc. this prevents N children from independently calling repaintTree for the whole gui on overlaping zones of the framebuffer. under OSes other than win32, this should be called after you've executed all your window events for this poll
+ TimerClient *getTimerClient();
+
+ const wchar_t *getRootWndName();
+ const wchar_t *getId();
+
+ int init(ifc_window *parent, int nochild=FALSE);
+ int isInited(); // are we post init() ? USE THIS INSTEAD OF gethWnd()==1
+ int isPostOnInit(); // are we post onInit() ? USE THIS INSTEAD OF ISINITED TO KNOW IF YOU CAN CALL ONRESIZE (if a function can be called by onInit and other parts of the code at the same time)
+
+ int setVirtual(int i);
+
+ int isClickThrough();
+ int onMouseMove(int x, int y);
+ int onLeftButtonUp(int x, int y);
+ int onRightButtonUp(int x, int y);
+ int onLeftButtonDown(int x, int y);
+ int onRightButtonDown(int x, int y);
+ int onLeftButtonDblClk(int x, int y);
+ int onRightButtonDblClk(int x, int y);
+
+ // fetch the DragInterface of the api_window here, can be NULL
+ DragInterface *getDragInterface();
+
+ int getCursorType(int x, int y);
+ OSCURSORHANDLE getCustomCursor(int x, int y);
+
+ // returns deepest child for point or yourself if no child there
+ ifc_window *rootWndFromPoint(POINT *pt);
+
+ void getClientRect(RECT *);
+ void getNonClientRect(RECT *rect);
+ // the onscreen coordinates
+ int getWindowRect(RECT *r);
+
+ void setVisible(int show);
+ void setCloaked(int cloak);
+ void onSetVisible(int show);
+ int isVisible(int within=0);
+
+ void *getInterface(GUID interface_guid);
+
+ // painting stuff
+ void invalidate();
+ void invalidateRect(RECT *r);
+ void invalidateRgn(api_region *r);
+ void invalidateFrom(ifc_window *who);
+ void invalidateRectFrom(RECT *r, ifc_window *who);
+ void invalidateRgnFrom(api_region *r, ifc_window *who);
+ void onChildInvalidate(api_region *r, ifc_window *who);
+ void validate();
+ void validateRect(RECT *r);
+ void validateRgn(api_region *reg);
+ int paintTree(ifc_canvas *canvas, api_region *r);
+ int paint(Canvas *canvas=NULL, api_region *r=NULL);
+ Canvas *getFrameBuffer();
+ ifc_window *getParent();
+ ifc_window *getRootParent();
+ ifc_window *getDesktopParent();
+ void setParent(ifc_window *newparent);
+ int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx);
+ int wantSiblingInvalidations();
+ int wantAutoContextMenu();
+ int wantActivation();
+ void activate();
+ int cascadeRepaintFrom(ifc_window *who, int pack=1);
+ int cascadeRepaintRgnFrom(api_region *reg, ifc_window *who, int pack=1);
+ int cascadeRepaintRectFrom(RECT *r, ifc_window *who, int pack=1);
+ int cascadeRepaint(int pack=1);
+ int cascadeRepaintRgn(api_region *reg, int pack=1);
+ int cascadeRepaintRect(RECT *r, int pack=1);
+ void repaint();
+ ifc_window *getBaseTextureWindow();
+ int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2);
+ int getPreferences(int what);
+ void setPreferences(int what, int v);
+ api_region *getRegion();
+ void invalidateWindowRegion();
+ api_region *getComposedRegion();
+ api_region *getSubtractorRegion();
+ int getRegionOp();
+ void setRegionOp(int op);
+ int isRectRgn();
+ void setRectRgn(int rrgn);
+ void setStartHidden(int sh);
+ void setClickThrough(int ct);
+ void focusNext();
+ void focusPrevious();
+
+ void setWindowTitle(const wchar_t *name);
+
+ double getRenderRatio();
+ void setRenderRatio(double r);
+ void setRatioLinked(int l); // 1 = getRenderRatio asks parent, 0 = returns this ratio, default is 1, 0 should only be used for non virtuals
+ int handleRatio();
+ void resize(int x, int y, int w, int h, int wantcb=1);
+ inline void resizeToRect(RECT *r)
+ {
+ resize(r->left, r->top, r->right - r->left, r->bottom - r->top);
+ }
+ void move(int x, int y);
+ void notifyDeferredMove(int x, int y);
+ void getPosition(POINT *pt);
+ ifc_window *getForwardWnd();
+
+ // children registration/enumeration
+ void registerRootWndChild(ifc_window *child);
+ void unregisterRootWndChild(ifc_window *child);
+ ifc_window *findRootWndChild(int x, int y, int only_virtuals=0);
+ ifc_window *enumRootWndChildren(int _enum);
+ int getNumRootWndChildren();
+
+ // virtual child stuff
+ int isVirtual();
+ void bringVirtualToFront(ifc_window *w);
+ void bringVirtualToBack(ifc_window *w);
+ void bringVirtualAbove(ifc_window *w, ifc_window *b);
+ void bringVirtualBelow(ifc_window *w, ifc_window *b);
+ int checkDoubleClick(int button, int x, int y);
+
+ void onCancelCapture();
+ void cancelCapture();
+ void setVirtualChildCapture(ifc_window *child);
+ ifc_window *getVirtualChildCapture();
+ ifc_window *getCurVirtualChildFocus();
+ ifc_window *getTab(int what=TAB_GETCURRENT);
+
+ bool ptInRegion(int x, int y);
+
+ void clientToScreen(int *x, int *y); // so rootWndFromPoint can map ratio
+ void screenToClient(int *x, int *y); // ..
+
+ int getNotifyId();
+
+ int onActivate();
+ int onDeactivate();
+ int isActive();
+ int handleTransparency();
+ int handleDesktopAlpha();
+ void setEnabled(int e);
+ int onEnable(int e);
+ int isEnabled(int within=0);
+ int getPaintingAlpha();
+ void getAlpha(int *activealpha=NULL, int *inactivealpha=NULL);
+ void setAlpha(int activealpha, int inactivealpha=-1); // -1 means same as activealpha
+ void setTip(const wchar_t *tip);
+
+ int runModal();
+ void endModal(int retcode);
+
+ void bringToFront();
+ void bringToBack();
+ void setFocus();
+ int gotFocus();
+ ifc_window *getNextVirtualFocus(ifc_window *w);
+ void setVirtualChildFocus(ifc_window *w);
+ void setVirtualTabOrder(ifc_window *w, int a);
+ int getVirtualTabOrder(ifc_window *w);
+ int wantFocus();
+ void setTabOrder(int a);
+ int getTabOrder();
+ void setAutoTabOrder();
+ void setVirtualAutoTabOrder(ifc_window *w);
+
+ int onAcceleratorEvent(const wchar_t *name);
+ int onChar(unsigned int c);
+ int onKeyDown(int keycode);
+ int onKeyUp(int keycode);
+ int onSysKeyDown(int keyCode, int keyData);
+ int onSysKeyUp(int keyCode, int keyData);
+ int onKillFocus();
+ int onGetFocus();
+ void onSetRootFocus(ifc_window *w);
+
+ ifc_dependent *getDependencyPtr();
+ void addMinMaxEnforcer(ifc_window *w);
+ void removeMinMaxEnforcer(ifc_window *w);
+ ifc_window *enumMinMaxEnforcer(int n);
+ int getNumMinMaxEnforcers();
+ void signalMinMaxEnforcerChanged();
+
+ int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+ void setRenderBaseTexture(int r);
+ int getRenderBaseTexture();
+ void renderBaseTexture(ifc_canvas *c, const RECT *r, int alpha=255);
+
+ GuiObject *getGuiObject(); // not guaranteed non null
+ int getFlag(int flag);
+
+ // see basewnd.h for codes. this is to force an event
+ int triggerEvent(int event, intptr_t p1=0, intptr_t p2=0);
+
+ int allowDeactivation();
+ void setAllowDeactivation(int allow);
+
+ ifc_window *findWindow(const wchar_t *id);
+ ifc_window *findWindowByInterface(GUID interface_guid);
+ ifc_window *findWindowByCallback(FindObjectCallback *cb);
+ ifc_window *findWindowChain(FindObjectCallback *cb, ifc_window *wcaller);
+
+ ifc_window *enumTab(int i);
+ int getNumTabs();
+
+ int getFocusOnClick();
+ void setFocusOnClick(int i);
+
+ void setNoDoubleClicks(int no);
+ void setNoLeftClicks(int no);
+ void setNoRightClicks(int no);
+ void setNoMouseMoves(int no);
+ void setNoContextMenus(int no);
+
+ int wantDoubleClicks();
+ int wantLeftClicks();
+ int wantRightClicks();
+ int wantMouseMoves();
+ int wantContextMenus();
+
+ void setDefaultCursor(Cursor *c);
+
+ Accessible *getAccessibleObject(int createifnotexist=1);
+
+ int accessibility_getState();
+
+#ifndef WA3COMPATIBILITY
+ void setDropTarget(void *dt);
+ void *getDropTarget();
+#endif
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ void setAlwaysOnTop(int i);
+ int getAlwaysOnTop();
+#endif
+
+ void maximize(int axis=MAXIMIZE_WIDTH|MAXIMIZE_HEIGHT);
+ void restore(int what=RESTORE_X|RESTORE_Y|RESTORE_WIDTH|RESTORE_HEIGHT);
+ int getRestoredRect(RECT *r);
+ int isMinimized();
+
+ enum {
+ Event_SETVISIBLE=100, // param 2 is 1 or 0
+ Event_ONPAINT=200, // param 2 is PaintCallback::BEFOREPAINT or PaintCallback::AFTERPAINT
+ Event_ONINVALIDATE=300,
+ };
+
+ enum {
+ BATCHPROCESSES = 50,
+ GETOSWINDOWHANDLE = 100,
+ GETOSMODULEHANDLE = 105,
+ GETROOTWNDNAME = 110,
+ GETID = 120,
+ GETDRAGINTERFACE = 200,
+ FROMPOINT = 300,
+ GETWINDOWRECT = 400,
+ ISVISIBLE = 501,
+ ONMETRICCHANGE = 700,
+ PAINTTREE = 900,
+ PAINT = 910,
+ GETFRAMEBUFFER = 920,
+ GETPARENT = 1000,
+ GETROOTPARENT = 1001,
+ SETPARENT = 1002,
+ GETDESKTOPPARENT = 1003,
+ CHILDNOTIFY = 1200,
+ GETPREFERENCES = 1300,
+ SETPREFERENCES = 1310,
+ CLICKTHROUGH = 1500,
+ GETFORWARDWND = 1501,
+ SETCLICKTHROUGH = 1502,
+ CLIENTSCREEN = 1600,
+ SCREENCLIENT = 1601,
+ INIT = 1700,
+ ISINITED = 1701,
+ ISPOSTONINIT = 1702,
+ SETVIRTUAL = 1704,
+ GETCURSORTYPE = 1800,
+ GETCUSTOMCURSOR = 1801,
+ GETINTERFACE = 1850,
+ GETCLIENTRECT = 1900,
+ GETNONCLIENTRECT = 1901,
+ SETVISIBLE = 2000,
+ ONSETVISIBLE = 2001,
+ SETCLOAKED = 2002,
+ INVALIDATE = 2100,
+ INVALIDATERECT = 2101,
+ INVALIDATERGN = 2102,
+ INVALIDATEFROM = 2103,
+ INVALIDATERECTFROM = 2104,
+ INVALIDATERGNFROM = 2105,
+ VALIDATE = 2200,
+ VALIDATERECT = 2201,
+ VALIDATERGN = 2202,
+ ONSIBINVALIDATE = 2300,
+ WANTSIBINVALIDATE = 2301,
+ ONCHILDINVALIDATE = 2302,
+ CASCADEREPAINTFROM = 2400,
+ CASCADEREPAINTRECTFROM = 2401,
+ CASCADEREPAINTRGNFROM = 2402,
+ CASCADEREPAINT = 2403,
+ CASCADEREPAINTRECT = 2405,
+ CASCADEREPAINTRGN = 2406,
+ REPAINT = 2500,
+ GETTEXTUREWND = 2600,
+ ONACTIVATE = 2700,
+ ACTIVATE = 2710,
+ ONDEACTIVATE = 2800,
+ ISACTIVATED = 2801,
+ GETPOSITION = 2900,
+ GETREGION = 3000,
+ GETREGIONOP = 3001,
+ INVALWNDRGN = 3002,
+ GETCOMPOSEDRGN = 3003,
+ GETSUBTRACTORRGN = 3010,
+ SETREGIONOP = 3004,
+ SETRECTRGN = 3005,
+ ISRECTRGN = 3006,
+ //SETPARAM = 3200, // deprecated, use the xmlobject interface
+ HANDLETRANSPARENCY = 3300,
+ HANDLEDESKTOPALPHA = 3400,
+ SETSTARTHIDDEN = 3500,
+ GETRENDERRATIO = 3600,
+ SETRENDERRATIO = 3610,
+ SETRATIOLINKED = 3615,
+ HANDLERATIO = 3620,
+ //_RESIZE = 3700, // deprecated, cut
+ _RESIZE = 3701,
+ _MOVE = 3710,
+ NOTIFYDEFERREDMOVE = 3720,
+ CHECKDBLCLK = 3800,
+ REGISTERROOTWNDCHILD = 3960,
+ UNREGISTERROOTWNDCHILD = 3965,
+ FINDROOTWNDCHILD= 3970,
+ ENUMROOTWNDCHILDREN = 3975,
+ GETNUMROOTWNDCHILDREN = 3980,
+ ISVIRTUAL = 3950,
+ BRINGVTOFRONT = 4000,
+ BRINGVTOBACK = 4010,
+ BRINGVABOVE = 4020,
+ BRINGVBELOW = 4030,
+ SETVCAPTURE = 4100,
+ GETVCAPTURE = 4110,
+ SETVTIMER = 4200,
+ KILLVTIMER = 4210,
+ PTINREGION = 4400,
+ ONLBDBLCLK = 4500,
+ ONRBDBLCLK = 4510,
+ ONLBUP = 4520,
+ ONRBUP = 4530,
+ ONLBDOWN = 4540,
+ ONRBDOWN = 4550,
+ ONMOUSEMOVE = 4560,
+ CLIENTTOSCREEN = 4600,
+ SCREENTOCLIENT = 4610,
+ GETNOTIFYID = 4700,
+ SETENABLED = 4800,
+ ISENABLED = 4810,
+ ONENABLE = 4811,
+ SETALPHA = 4900,
+ GETALPHA = 4910,
+ GETPAINTALPHA = 4911,
+ SETTOOLTIP = 4920,
+ RUNMODAL = 5000,
+ ENDMODAL = 5010,
+ WANTAUTOCONTEXTMENU = 5100,
+ ONCANCELCAPTURE = 5200,
+ CANCELCAPTURE = 5210,
+ BRINGTOFRONT = 5300,
+ BRINGTOBACK = 5310,
+ SETFOCUS = 5401,
+ GOTFOCUS = 5410,
+ GETNEXTVFOCUS = 5420,
+ SETVFOCUS = 5430,
+ ONKILLFOCUS = 5440,
+ ONGETFOCUS = 5450,
+ WANTFOCUS = 5460,
+ ONKEYDOWN = 5500,
+ ONKEYUP = 5510,
+ ONCHAR = 5520,
+ ONACCELERATOREVENT = 5530,
+ GETTIMERCLIENT = 5600,
+ GETDEPENDENCYPTR = 6000,
+ ADDMINMAXENFORCER = 6400,
+ REMOVEMINMAXENFORCER = 6410,
+ GETNUMMINMAXENFORCERS = 6420,
+ ENUMMINMAXENFORCER = 6430,
+ SIGNALMINMAXCHANGED = 6440,
+ ROOTWNDONACTION = 6300,
+ SETRENDERBASETEXTURE = 6600,
+ GETRENDERBASETEXTURE = 6610,
+ RENDERBASETEXTURE=6611,
+ GETGUIOBJECT = 6620,
+ ONSYSKEYDOWN = 6630,
+ ONSYSKEYUP = 6640,
+ GETFLAG = 6650,
+ TRIGGEREVENT = 6660,
+
+ SETALLOWDEACTIVATE = 6700,
+ ALLOWDEACTIVATE=6710,
+ FINDWND_BYID=6800,
+ FINDWND_BYGUID=6810,
+ FINDWND_BYCB=6820,
+ FINDWNDCHAIN=6830,
+ SETTABORDER=6900,
+ GETTABORDER=6910,
+ SETAUTOTABORDER=6920,
+ GETTAB=6940,
+ SETVIRTUALTABORDER=7000,
+ GETVIRTUALTABORDER=7010,
+ SETVIRTUALAUTOTABORDER=7020,
+ GETCURVIRTUALCHILDFOCUS=7030,
+ FOCUSNEXT=7100,
+ FOCUSPREVIOUS=7110,
+ SETWINDOWTITLE=7120,
+ GETNUMTABS = 7200,
+ ENUMTAB = 7210,
+ ONSETROOTFOCUS = 7300,
+ GETFOCUSONCLICK = 7400,
+ SETFOCUSONCLICK = 7410,
+ SETNODOUBLECLICKS = 7500,
+ SETNOLEFTCLICKS = 7510,
+ SETNORIGHTCLICKS = 7520,
+ SETNOMOUSEMOVES = 7530,
+ SETNOCONTEXTMENUS = 7540,
+ WANTDOUBLECLICKS = 7600,
+ WANTLEFTCLICKS = 7610,
+ WANTRIGHTCLICKS = 7620,
+ WANTMOUSEMOVES = 7630,
+ WANTCONTEXTMENUS = 7640,
+ WANTACTIVATION = 7700,
+ SETDEFAULTCURSOR = 7800,
+
+ GETACCESSIBLEOBJECT = 8000,
+ ACCGETSTATE = 8104,
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ SETALWAYSONTOP = 8500,
+ GETALWAYSONTOP = 8501,
+#endif
+
+#ifndef WA3COMPATIBILITY
+ GETDROPTARGET = 8800,
+ SETDROPTARGET = 8810,
+#endif
+ ISMINIMIZED = 8900,
+ MAXIMIZE = 9200,
+ RESTORE = 9210,
+ GETRESTOREDRECT = 9220,
+ };
+};
+
+
+// helper functions definitions
+inline OSWINDOWHANDLE ifc_window::getOsWindowHandle() {
+ return _call(GETOSWINDOWHANDLE, (OSWINDOWHANDLE)NULL);
+}
+
+inline OSMODULEHANDLE ifc_window::getOsModuleHandle() {
+ return _call(GETOSMODULEHANDLE, (OSMODULEHANDLE)NULL);
+}
+
+inline void ifc_window::performBatchProcesses() {
+ _voidcall(BATCHPROCESSES);
+}
+
+inline const wchar_t *ifc_window::getRootWndName()
+{
+ return _call(GETROOTWNDNAME, (const wchar_t *)NULL);
+}
+
+inline const wchar_t *ifc_window::getId() {
+ return _call(GETID, (const wchar_t *)NULL);
+}
+
+inline DragInterface *ifc_window::getDragInterface() {
+ return _call(GETDRAGINTERFACE, (DragInterface*)0);
+}
+
+inline ifc_window *ifc_window::rootWndFromPoint(POINT *pt) {
+ return _call(FROMPOINT, (ifc_window*)0, pt);
+}
+
+inline int ifc_window::getWindowRect(RECT *r) {
+ return _voidcall(GETWINDOWRECT, r);
+}
+
+inline int ifc_window::isVisible(int within) {
+ return _call(ISVISIBLE, 0, within);
+}
+
+inline int ifc_window::paintTree(ifc_canvas *canvas, api_region *r) {
+ return _call(PAINTTREE, 0, canvas, r);
+}
+
+inline Canvas *ifc_window::getFrameBuffer() {
+ return _call(GETFRAMEBUFFER, (Canvas *)NULL);
+}
+
+inline int ifc_window::paint(Canvas *canvas, api_region *r) {
+ return _call(PAINT, 0, canvas, r);
+}
+
+inline ifc_window *ifc_window::getParent() {
+ return _call(GETPARENT, (ifc_window *)0);
+}
+
+inline ifc_window *ifc_window::getRootParent() {
+ return _call(GETROOTPARENT, (ifc_window *)0);
+}
+
+inline ifc_window *ifc_window::getDesktopParent() {
+ return _call(GETDESKTOPPARENT, (ifc_window *)0);
+}
+
+inline void ifc_window::setParent(ifc_window *parent) {
+ _voidcall(SETPARENT, parent);
+}
+
+inline int ifc_window::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) {
+ return _call(CHILDNOTIFY, 0, child, msg, p1, p2);
+}
+
+inline int ifc_window::getPreferences(int what) {
+ return _call(GETPREFERENCES, 0, what);
+}
+
+inline void ifc_window::setPreferences(int what, int v) {
+ _voidcall(SETPREFERENCES, what, v);
+}
+
+inline void ifc_window::cancelCapture() {
+ _voidcall(CANCELCAPTURE, 0);
+}
+
+inline void ifc_window::onCancelCapture() {
+ _voidcall(ONCANCELCAPTURE, 0);
+}
+
+inline int ifc_window::isClickThrough() {
+ return _call(CLICKTHROUGH, 0);
+}
+
+inline void ifc_window::setClickThrough(int ct) {
+ _voidcall(SETCLICKTHROUGH, ct);
+}
+
+inline ifc_window *ifc_window::getForwardWnd() {
+ return _call(GETFORWARDWND, this);
+}
+
+inline void ifc_window::clientToScreen(int *x, int *y) {
+ _voidcall(CLIENTSCREEN, x, y);
+}
+
+inline void ifc_window::screenToClient(int *x, int *y) {
+ _voidcall(SCREENCLIENT, x, y);
+}
+
+inline int ifc_window::init(ifc_window *parent, int nochild) {
+ return _call(INIT, 0, parent, nochild);
+}
+
+inline int ifc_window::isInited() {
+ return _call(ISINITED, 0);
+}
+
+inline int ifc_window::isPostOnInit() {
+ return _call(ISPOSTONINIT, 0);
+}
+
+inline int ifc_window::setVirtual(int i) {
+ return _call(SETVIRTUAL, 0, i);
+}
+
+inline int ifc_window::getCursorType(int x, int y) {
+ return _call(GETCURSORTYPE, 0, x, y);
+}
+
+inline OSCURSORHANDLE ifc_window::getCustomCursor(int x, int y) {
+ return _call(GETCUSTOMCURSOR, (OSCURSORHANDLE)NULL, x, y);
+}
+
+inline void ifc_window::getClientRect(RECT *r) {
+ _voidcall(GETCLIENTRECT, r);
+}
+
+inline void ifc_window::getNonClientRect(RECT *rect) {
+ _voidcall(GETNONCLIENTRECT, rect);
+}
+
+inline void ifc_window::getPosition(POINT *pt) {
+ _voidcall(GETPOSITION, pt);
+}
+
+inline void ifc_window::setVisible(int show) {
+ _voidcall(SETVISIBLE, show);
+}
+
+inline void ifc_window::setCloaked(int cloak) {
+ _voidcall(SETCLOAKED, cloak);
+}
+
+inline void ifc_window::onSetVisible(int show) {
+ _voidcall(ONSETVISIBLE, show);
+}
+
+inline void ifc_window::invalidate() {
+ _voidcall(INVALIDATE);
+}
+
+inline void ifc_window::invalidateRect(RECT *r) {
+ _voidcall(INVALIDATERECT, r);
+}
+
+inline void ifc_window::invalidateRgn(api_region *r) {
+ _voidcall(INVALIDATERGN, r);
+}
+
+inline void ifc_window::onChildInvalidate(api_region *r, ifc_window *who) {
+ _voidcall(ONCHILDINVALIDATE, r, who);
+}
+
+inline void ifc_window::invalidateFrom(ifc_window *who) {
+ _voidcall(INVALIDATEFROM, who);
+}
+
+inline void ifc_window::invalidateRectFrom(RECT *r, ifc_window *who) {
+ _voidcall(INVALIDATERECTFROM, r, who);
+}
+
+inline void ifc_window::invalidateRgnFrom(api_region *r, ifc_window *who) {
+ _voidcall(INVALIDATERGNFROM, r, who);
+}
+
+inline void ifc_window::validate() {
+ _voidcall(VALIDATE);
+}
+
+inline void ifc_window::validateRect(RECT *r) {
+ _voidcall(VALIDATERECT, r);
+}
+
+inline void ifc_window::validateRgn(api_region *reg) {
+ _voidcall(VALIDATERGN, reg);
+}
+
+inline int ifc_window::onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx) {
+ return _call(ONSIBINVALIDATE, 0, r, who, who_idx, my_idx);
+}
+
+inline int ifc_window::wantSiblingInvalidations() {
+ return _call(WANTSIBINVALIDATE, 0);
+}
+
+inline int ifc_window::cascadeRepaintFrom(ifc_window *who, int pack) {
+ return _call(CASCADEREPAINTFROM, 0, who, pack);
+}
+
+inline int ifc_window::cascadeRepaintRgnFrom(api_region *reg, ifc_window *who, int pack) {
+ return _call(CASCADEREPAINTRGNFROM, 0, reg, who, pack);
+}
+
+inline int ifc_window::cascadeRepaintRectFrom(RECT *r, ifc_window *who, int pack) {
+ return _call(CASCADEREPAINTRECTFROM, 0, r, who, pack);
+}
+
+inline int ifc_window::cascadeRepaint(int pack) {
+ return _call(CASCADEREPAINT, 0, pack);
+}
+
+inline int ifc_window::cascadeRepaintRgn(api_region *reg, int pack) {
+ return _call(CASCADEREPAINTRGN, 0, reg, pack);
+}
+
+inline int ifc_window::cascadeRepaintRect(RECT *r, int pack) {
+ return _call(CASCADEREPAINTRECT, 0, r, pack);
+}
+
+inline void ifc_window::repaint() {
+ _voidcall(REPAINT);
+}
+
+inline ifc_window *ifc_window::getBaseTextureWindow() {
+ return _call(GETTEXTUREWND, (ifc_window *)0);
+}
+
+inline int ifc_window::onActivate() {
+ return _call(ONACTIVATE, 0);
+}
+
+inline void ifc_window::activate() {
+ _voidcall(ACTIVATE);
+}
+
+inline int ifc_window::onDeactivate() {
+ return _call(ONDEACTIVATE, 0);
+}
+
+inline int ifc_window::isActive() {
+ return _call(ISACTIVATED, 0);
+}
+
+inline api_region *ifc_window::getRegion() {
+ return _call(GETREGION, (api_region *)NULL);
+}
+
+inline int ifc_window::handleTransparency() {
+ return _call(HANDLETRANSPARENCY, 0);
+}
+
+inline int ifc_window::handleDesktopAlpha() {
+ return _call(HANDLEDESKTOPALPHA, 0);
+}
+
+inline void ifc_window::setStartHidden(int sh) {
+ _voidcall(SETSTARTHIDDEN, sh);
+}
+
+inline double ifc_window::getRenderRatio() {
+ return _call(GETRENDERRATIO, 1.0);
+}
+
+inline void ifc_window::setRenderRatio(double r) {
+ _voidcall(SETRENDERRATIO, r);
+}
+
+inline void ifc_window::setRatioLinked(int l) {
+ _voidcall(SETRATIOLINKED, l);
+}
+
+inline int ifc_window::handleRatio() {
+ return _call(HANDLERATIO, 0);
+}
+
+inline void ifc_window::resize(int x, int y, int w, int h, int wantcb) {
+ _voidcall(_RESIZE, x, y, w, h, wantcb);
+}
+
+inline void ifc_window::move(int x, int y) {
+ _voidcall(_MOVE, x, y);
+}
+
+inline void ifc_window::notifyDeferredMove(int x, int y) {
+ _voidcall(NOTIFYDEFERREDMOVE, x, y);
+}
+
+inline int ifc_window::checkDoubleClick(int button, int x, int y) {
+ return _call(CHECKDBLCLK, 0, button, x, y);
+}
+
+inline void ifc_window::registerRootWndChild(ifc_window *child) {
+ _voidcall(REGISTERROOTWNDCHILD, child);
+}
+
+inline void ifc_window::unregisterRootWndChild(ifc_window *child) {
+ _voidcall(UNREGISTERROOTWNDCHILD, child);
+}
+
+inline ifc_window *ifc_window::findRootWndChild(int x, int y, int only_virtuals) {
+ return _call(FINDROOTWNDCHILD, (ifc_window *)NULL, x, y, only_virtuals);
+}
+
+inline ifc_window *ifc_window::enumRootWndChildren(int _enum) {
+ return _call(ENUMROOTWNDCHILDREN, (ifc_window *)NULL, _enum);
+}
+
+inline int ifc_window::getNumRootWndChildren() {
+ return _call(GETNUMROOTWNDCHILDREN, 0);
+}
+
+inline int ifc_window::isVirtual() {
+ return _call(ISVIRTUAL, 0);
+}
+
+inline void ifc_window::bringVirtualToFront(ifc_window *w) {
+ _voidcall(BRINGVTOFRONT, w);
+}
+
+inline void ifc_window::bringVirtualToBack(ifc_window *w) {
+ _voidcall(BRINGVTOBACK, w);
+}
+
+inline void ifc_window::bringVirtualAbove(ifc_window *w, ifc_window *b) {
+ _voidcall(BRINGVABOVE, w, b);
+}
+
+inline void ifc_window::bringVirtualBelow(ifc_window *w, ifc_window *b) {
+ _voidcall(BRINGVBELOW, w, b);
+}
+
+inline void ifc_window::setVirtualChildCapture(ifc_window *child) {
+ _voidcall(SETVCAPTURE, child);
+}
+
+inline ifc_window *ifc_window::getVirtualChildCapture() {
+ return _call(GETVCAPTURE, (ifc_window *)NULL);
+}
+
+inline bool ifc_window::ptInRegion(int x, int y) {
+ return _call(PTINREGION, (bool)false, x, y);
+}
+
+inline int ifc_window::onLeftButtonDblClk(int x, int y) {
+ return _call(ONLBDBLCLK, 0, x, y);
+}
+
+inline int ifc_window::onRightButtonDblClk(int x, int y) {
+ return _call(ONRBDBLCLK, 0, x, y);
+}
+
+inline int ifc_window::onLeftButtonUp(int x, int y) {
+ return _call(ONLBUP, 0, x, y);
+}
+
+inline int ifc_window::onRightButtonUp(int x, int y) {
+ return _call(ONRBUP, 0, x, y);
+}
+
+inline int ifc_window::onLeftButtonDown(int x, int y) {
+ return _call(ONLBDOWN, 0, x, y);
+}
+
+inline int ifc_window::onRightButtonDown(int x, int y) {
+ return _call(ONRBDOWN, 0, x, y);
+}
+
+inline int ifc_window::onMouseMove(int x, int y) {
+ return _call(ONMOUSEMOVE, 0, x, y);
+}
+
+inline int ifc_window::getNotifyId() {
+ return _call(GETNOTIFYID, 0);
+}
+
+inline void *ifc_window::getInterface(GUID interface_guid) {
+ return _call(GETINTERFACE, (void *)NULL, interface_guid);
+}
+
+inline void ifc_window::setEnabled(int e) {
+ _voidcall(SETENABLED, e);
+}
+
+inline int ifc_window::isEnabled(int within) {
+ return _call(ISENABLED, 0, within);
+}
+
+inline int ifc_window::onEnable(int e) {
+ return _voidcall(ONENABLE, e);
+}
+
+inline void ifc_window::setAlpha(int activealpha, int inactivealpha) {
+ _voidcall(SETALPHA, activealpha, inactivealpha);
+}
+
+inline void ifc_window::getAlpha(int *active, int *inactive) {
+ _voidcall(GETALPHA, active, inactive);
+}
+
+inline int ifc_window::getPaintingAlpha() {
+ return _call(GETPAINTALPHA, 255);
+}
+
+inline void ifc_window::setTip(const wchar_t *tip) {
+ _voidcall(SETTOOLTIP, tip);
+}
+
+inline int ifc_window::runModal() {
+ return _call(RUNMODAL, 0);
+}
+
+inline void ifc_window::endModal(int retcode) {
+ _voidcall(ENDMODAL, retcode);
+}
+
+inline int ifc_window::wantAutoContextMenu() {
+ return _call(WANTAUTOCONTEXTMENU, 0);
+}
+
+inline int ifc_window::wantActivation() {
+ return _call(WANTACTIVATION, 1);
+}
+
+inline void ifc_window::bringToFront() {
+ _voidcall(BRINGTOFRONT);
+}
+
+inline void ifc_window::bringToBack() {
+ _voidcall(BRINGTOBACK);
+}
+
+inline void ifc_window::setFocus() {
+ _voidcall(SETFOCUS);
+}
+
+inline int ifc_window::gotFocus() {
+ return _call(GOTFOCUS, 0);
+}
+
+inline int ifc_window::onGetFocus() {
+ return _call(ONGETFOCUS, 0);
+}
+
+inline int ifc_window::onKillFocus() {
+ return _call(ONKILLFOCUS, 0);
+}
+
+inline ifc_window *ifc_window::getNextVirtualFocus(ifc_window *cur) {
+ return _call(GETNEXTVFOCUS, (ifc_window *)NULL, cur);
+}
+
+inline int ifc_window::wantFocus() {
+ return _call(WANTFOCUS, 0);
+}
+
+inline int ifc_window::onAcceleratorEvent(const wchar_t *name) {
+ return _call(ONACCELERATOREVENT, 0, name);
+}
+
+inline int ifc_window::onChar(unsigned int c) {
+ return _call(ONCHAR, 0, c);
+}
+
+inline int ifc_window::onKeyDown(int keycode) {
+ return _call(ONKEYDOWN, 0, keycode);
+}
+
+inline int ifc_window::onKeyUp(int keycode) {
+ return _call(ONKEYUP, 0, keycode);
+}
+
+inline int ifc_window::onSysKeyDown(int keycode, int keydata) {
+ return _call(ONSYSKEYDOWN, 0, keycode, keydata);
+}
+
+inline int ifc_window::onSysKeyUp(int keycode, int keydata) {
+ return _call(ONSYSKEYUP, 0, keycode, keydata);
+}
+
+inline void ifc_window::setVirtualChildFocus(ifc_window *w) {
+ _voidcall(SETVFOCUS, w);
+}
+
+inline int ifc_window::getRegionOp() {
+ return _call(GETREGIONOP, 0);
+}
+
+inline void ifc_window::invalidateWindowRegion() {
+ _voidcall(INVALWNDRGN);
+}
+
+inline api_region *ifc_window::getComposedRegion() {
+ return _call(GETCOMPOSEDRGN, (api_region *)NULL);
+}
+
+inline api_region *ifc_window::getSubtractorRegion() {
+ return _call(GETSUBTRACTORRGN, (api_region *)NULL);
+}
+
+inline void ifc_window::setRegionOp(int op) {
+ _voidcall(SETREGIONOP, op);
+}
+
+inline void ifc_window::setRectRgn(int rrgn) {
+ _voidcall(SETRECTRGN, rrgn);
+}
+
+inline int ifc_window::isRectRgn() {
+ return _call(ISRECTRGN, 0);
+}
+
+inline TimerClient *ifc_window::getTimerClient() {
+ return _call(GETTIMERCLIENT, (TimerClient *)NULL);
+}
+
+inline ifc_dependent *ifc_window::getDependencyPtr() {
+ return _call(GETDEPENDENCYPTR, (ifc_dependent *)NULL);
+}
+
+inline void ifc_window::addMinMaxEnforcer(ifc_window *w) {
+ _voidcall(ADDMINMAXENFORCER, w);
+}
+
+inline void ifc_window::removeMinMaxEnforcer(ifc_window *w) {
+ _voidcall(REMOVEMINMAXENFORCER, w);
+}
+
+inline ifc_window *ifc_window::enumMinMaxEnforcer(int n) {
+ return _call(ENUMMINMAXENFORCER, (ifc_window *)NULL, n);
+}
+
+inline int ifc_window::getNumMinMaxEnforcers() {
+ return _call(GETNUMMINMAXENFORCERS, 0);
+}
+
+inline void ifc_window::signalMinMaxEnforcerChanged() {
+ _voidcall(SIGNALMINMAXCHANGED, 0);
+}
+
+inline int ifc_window::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ return _call(ROOTWNDONACTION, 0, action, param, x, y, p1, p2, data, datalen, source);
+}
+
+inline void ifc_window::setRenderBaseTexture(int i) {
+ _voidcall(SETRENDERBASETEXTURE, i);
+}
+
+inline int ifc_window::getRenderBaseTexture() {
+ return _call(GETRENDERBASETEXTURE, 0);
+}
+
+inline void ifc_window::renderBaseTexture(ifc_canvas *c, const RECT *r, int alpha)
+{
+ _voidcall(RENDERBASETEXTURE, c, r, alpha);
+}
+
+inline GuiObject *ifc_window::getGuiObject() {
+ return _call(GETGUIOBJECT, (GuiObject *) NULL);
+}
+
+inline int ifc_window::triggerEvent(int event, intptr_t p1, intptr_t p2) {
+ return _call(TRIGGEREVENT, 0, event, p1, p2);
+}
+
+inline int ifc_window::getFlag(int flag) {
+ return _call(GETFLAG, 0, flag);
+}
+
+inline int ifc_window::allowDeactivation() {
+ return _call(ALLOWDEACTIVATE, 1);
+}
+
+inline void ifc_window::setAllowDeactivation(int allow) {
+ _voidcall(SETALLOWDEACTIVATE, allow);
+}
+
+inline ifc_window *ifc_window::findWindow(const wchar_t *id) {
+ return _call(FINDWND_BYID, (ifc_window *)NULL, id);
+}
+
+inline ifc_window *ifc_window::findWindowByInterface(GUID interface_guid) {
+ return _call(FINDWND_BYGUID, (ifc_window *)NULL, interface_guid);
+}
+
+inline ifc_window *ifc_window::findWindowByCallback(FindObjectCallback *cb) {
+ return _call(FINDWND_BYCB, (ifc_window *)NULL, cb);
+}
+
+inline ifc_window *ifc_window::findWindowChain(FindObjectCallback *cb, ifc_window *wcaller) {
+ return _call(FINDWNDCHAIN, (ifc_window *)NULL, cb, wcaller);
+}
+
+inline void ifc_window::setTabOrder(int a) {
+ _voidcall(SETTABORDER, a);
+}
+
+inline int ifc_window::getTabOrder() {
+ return _call(GETTABORDER, -1);
+}
+
+inline void ifc_window::setAutoTabOrder() {
+ _voidcall(SETAUTOTABORDER, 0);
+}
+
+inline void ifc_window::setVirtualTabOrder(ifc_window *w, int a) {
+ _voidcall(SETVIRTUALTABORDER, w, a);
+}
+
+inline int ifc_window::getVirtualTabOrder(ifc_window *w) {
+ return _call(GETVIRTUALTABORDER, 0, w);
+}
+
+inline void ifc_window::setVirtualAutoTabOrder(ifc_window *w) {
+ _voidcall(SETVIRTUALAUTOTABORDER, w);
+}
+
+inline ifc_window *ifc_window::getCurVirtualChildFocus() {
+ return _call(GETCURVIRTUALCHILDFOCUS, (ifc_window *)NULL);
+}
+
+inline ifc_window *ifc_window::getTab(int what) {
+ return _call(GETTAB, (ifc_window *)NULL, what);
+}
+
+inline void ifc_window::focusNext() {
+ _voidcall(FOCUSNEXT);
+}
+
+inline void ifc_window::focusPrevious() {
+ _voidcall(FOCUSPREVIOUS);
+}
+
+inline void ifc_window::setWindowTitle(const wchar_t *title){
+ _voidcall(SETWINDOWTITLE, title);
+}
+inline int ifc_window::getNumTabs() {
+ return _call(GETNUMTABS, 0);
+}
+
+inline ifc_window *ifc_window::enumTab(int i) {
+ return _call(ENUMTAB, (ifc_window *)NULL, i);
+}
+
+inline void ifc_window::onSetRootFocus(ifc_window *w) {
+ _voidcall(ONSETROOTFOCUS, w);
+}
+
+inline int ifc_window::getFocusOnClick() {
+ return _call(GETFOCUSONCLICK, 0);
+}
+
+inline void ifc_window::setFocusOnClick(int i) {
+ _voidcall(SETFOCUSONCLICK, i);
+}
+
+inline void ifc_window::setNoDoubleClicks(int no) {
+ _voidcall(SETNODOUBLECLICKS, no);
+}
+
+inline void ifc_window::setNoLeftClicks(int no) {
+ _voidcall(SETNOLEFTCLICKS, no);
+}
+
+inline void ifc_window::setNoRightClicks(int no) {
+ _voidcall(SETNORIGHTCLICKS, no);
+}
+
+inline void ifc_window::setNoMouseMoves(int no) {
+ _voidcall(SETNOMOUSEMOVES, no);
+}
+
+inline void ifc_window::setNoContextMenus(int no) {
+ _voidcall(SETNOCONTEXTMENUS, no);
+}
+
+inline int ifc_window::wantDoubleClicks() {
+ return _call(WANTDOUBLECLICKS, 1);
+}
+
+inline int ifc_window::wantRightClicks() {
+ return _call(WANTLEFTCLICKS, 1);
+}
+
+inline int ifc_window::wantLeftClicks() {
+ return _call(WANTRIGHTCLICKS, 1);
+}
+
+inline int ifc_window::wantMouseMoves() {
+ return _call(WANTMOUSEMOVES, 1);
+}
+
+inline int ifc_window::wantContextMenus() {
+ return _call(WANTCONTEXTMENUS, 1);
+}
+
+inline void ifc_window::setDefaultCursor(Cursor *c) {
+ _voidcall(SETDEFAULTCURSOR, c);
+}
+
+inline Accessible *ifc_window::getAccessibleObject(int createifnotexist) {
+ return _call(GETACCESSIBLEOBJECT, (Accessible*)NULL, createifnotexist);
+}
+
+
+inline int ifc_window::accessibility_getState() {
+ return _call(ACCGETSTATE, 0);
+}
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+inline void ifc_window::setAlwaysOnTop(int i) {
+ _voidcall(SETALWAYSONTOP, i);
+}
+
+inline int ifc_window::getAlwaysOnTop() {
+ return _call(GETALWAYSONTOP, 0);
+}
+#endif
+
+#ifndef WA3COMPATIBILITY
+inline void ifc_window::setDropTarget(void *dt) {
+ _voidcall(SETDROPTARGET, dt);
+}
+
+inline void *ifc_window::getDropTarget() {
+ return _call(GETDROPTARGET, (void *)NULL);
+}
+#endif
+
+inline int ifc_window::isMinimized() {
+ return _call(ISMINIMIZED, 0);
+}
+
+inline void ifc_window::maximize(int axis) {
+ _voidcall(MAXIMIZE, axis);
+}
+
+inline void ifc_window::restore(int what) {
+ _voidcall(RESTORE, what);
+}
+
+inline int ifc_window::getRestoredRect(RECT *r)
+{
+ return _call(GETRESTOREDRECT, 0, r);
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/api_wnd.cpp b/Src/Wasabi/api/wnd/api_wnd.cpp
new file mode 100644
index 00000000..50d2f455
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_wnd.cpp
@@ -0,0 +1,57 @@
+#include "precomp.h"
+#include "api_wnd.h"
+
+#define CBCLASS wnd_apiI
+START_DISPATCH;
+VCB(API_WND_SETROOTWND, main_setRootWnd);
+CB(API_WND_GETROOTWND, main_getRootWnd);
+CB(API_WND_GETMODALWND, getModalWnd);
+VCB(API_WND_PUSHMODALWND, popModalWnd);
+VCB(API_WND_POPMODALWND, popModalWnd);
+CB(API_WND_ROOTWNDFROMPOINT, rootWndFromPoint);
+VCB(API_WND_REGISTERROOTWND, registerRootWnd);
+VCB(API_WND_UNREGISTERROOTWND, unregisterRootWnd);
+CB(API_WND_ROOTWNDISVALID, rootwndIsValid);
+CB(API_WND_INTERCEPTONCHAR, interceptOnChar);
+CB(API_WND_INTERCEPTONKEYDOWN, interceptOnKeyDown);
+CB(API_WND_INTERCEPTONKEYUP, interceptOnKeyUp);
+CB(API_WND_INTERCEPTONSYSKEYDOWN, interceptOnSysKeyDown);
+CB(API_WND_INTERCEPTONSYSKEYUP, interceptOnSysKeyUp);
+VCB(API_WND_HOOKKEYBOARD, hookKeyboard);
+VCB(API_WND_UNHOOKKEYBOARD, unhookKeyboard);
+VCB(API_WND_KBDRESET, kbdReset);
+CB(API_WND_FORWARDONCHAR, forwardOnChar);
+CB(API_WND_FORWARDONKEYDOWN, forwardOnKeyDown);
+CB(API_WND_FORWARDONKEYUP, forwardOnKeyUp);
+CB(API_WND_FORWARDONSYSKEYDOWN, forwardOnSysKeyDown);
+CB(API_WND_FORWARDONSYSKEYUP, forwardOnSysKeyUp);
+CB(API_WND_FORWARDONKILLFOCUS, forwardOnKillFocus);
+CB(API_WND_POPUPEXIT_CHECK, popupexit_check);
+VCB(API_WND_POPUPEXIT_SIGNAL, popupexit_signal);
+VCB(API_WND_POPUPEXIT_REGISTER, popupexit_register);
+VCB(API_WND_POPUPEXIT_DEREGISTER, popupexit_deregister);
+VCB(API_WND_RENDERBASETEXTURE, skin_renderBaseTexture);
+VCB(API_WND_REGISTERBASETEXTUREWINDOW, skin_registerBaseTextureWindow);
+VCB(API_WND_UNREGISTERBASETEXTUREWINDOW, skin_unregisterBaseTextureWindow);
+VCB(API_WND_APPDEACTIVATION_PUSH_DISALLOW, appdeactivation_push_disallow);
+VCB(API_WND_APPDEACTIVATION_POP_DISALLOW, appdeactivation_pop_disallow);
+CB(API_WND_APPDEACTIVATION_ISALLOWED, appdeactivation_isallowed);
+VCB(API_WND_APPDEACTIVATION_SETBYPASS, appdeactivation_setbypass);
+CB(API_WND_FORWARDONMOUSEWHEEL, forwardOnMouseWheel);
+#ifdef WASABI_COMPILE_PAINTSETS
+CB(API_WND_PAINTSET_PRESENT, paintset_present );
+#ifdef WASABI_COMPILE_IMGLDR
+VCB(API_WND_PAINTSET_RENDER, paintset_render);
+#ifdef WASABI_COMPILE_FONTS
+VCB(API_WND_PAINTSET_RENDERTITLE, paintset_renderTitle);
+#endif // fonts
+#endif // imgldr
+#endif // paintsets
+// fg> this may need to go away eventually but i need it _right now_
+VCB(API_WND_SETDEFAULTDROPTARGET, setDefaultDropTarget);
+CB(API_WND_GETDEFAULTDROPTARGET, getDefaultDropTarget);
+CB(API_WND_PUSHKBDLOCK, pushKeyboardLock);
+CB(API_WND_POPKBDLOCK, popKeyboardLock);
+CB(API_WND_ISKBDLOCKED, isKeyboardLocked);
+CB(API_WND_ROOTWNDFROMOSHANDLE, rootWndFromOSHandle);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/wnd/api_wnd.h b/Src/Wasabi/api/wnd/api_wnd.h
new file mode 100644
index 00000000..ce72cd8c
--- /dev/null
+++ b/Src/Wasabi/api/wnd/api_wnd.h
@@ -0,0 +1,390 @@
+#ifndef __API_WND_H
+#define __API_WND_H
+
+#include <wasabicfg.h>
+#include <bfc/dispatch.h>
+#include <bfc/platform/platform.h>
+class ifc_window;
+class PopupExitCallback; // see ../bfc/popexitcb.h
+class ifc_canvas; // see ../common/canvas.h
+class CfgItem;
+
+#ifndef MODALWND_DEF
+#define MODALWND_DEF
+ifc_window *const MODALWND_NOWND = reinterpret_cast<ifc_window*>(-1);
+#endif
+
+class wnd_api : public Dispatchable
+{
+ public:
+
+ // the master window
+ /**
+ Get the main root window.
+
+ @ret Main root window.
+ */
+ ifc_window *main_getRootWnd();
+ void main_setRootWnd(ifc_window *w);
+ /**
+ Get the modal window on top of the
+ modal window stack.
+
+ @ret Window that's currently modal.
+ */
+ ifc_window *getModalWnd();
+ /**
+ Push a window onto the modal stack. If
+ the window is on top of the stack, it's
+ currently modal.
+
+ @param w Window to push onto the modal stack.
+ */
+ void pushModalWnd(ifc_window *w=MODALWND_NOWND);
+
+ /**
+ Pop a window from the modal stack. If
+ the window is on top of the stack, it
+ will no longer be modal after this call.
+
+ @param w Window to pop from the modal stack.
+ */
+ void popModalWnd(ifc_window *w=MODALWND_NOWND);
+ ifc_window *rootWndFromPoint(POINT *pt);
+ ifc_window *rootWndFromOSHandle(OSWINDOWHANDLE wnd);
+ void registerRootWnd(ifc_window *wnd);
+ void unregisterRootWnd(ifc_window *wnd);
+ int rootwndIsValid(ifc_window *wnd);
+ void hookKeyboard(ifc_window *hooker);
+ void unhookKeyboard(ifc_window *hooker);
+ void kbdReset();
+ int interceptOnChar(unsigned int c);
+ int interceptOnKeyDown(int k);
+ int interceptOnKeyUp(int k);
+ int interceptOnSysKeyDown(int k, int kd);
+ int interceptOnSysKeyUp(int k, int kd);
+ int forwardOnChar(ifc_window *from, unsigned int c, int kd);
+ int forwardOnKeyDown(ifc_window *from, int k, int kd);
+ int forwardOnKeyUp(ifc_window *from, int k, int kd);
+ int forwardOnSysKeyDown(ifc_window *from, int k, int kd);
+ int forwardOnSysKeyUp(ifc_window *from, int k, int kd);
+ int forwardOnKillFocus();
+ int pushKeyboardLock();
+ int popKeyboardLock();
+ int isKeyboardLocked();
+ void popupexit_deregister(PopupExitCallback *cb);
+ void popupexit_register(PopupExitCallback *cb, ifc_window *watched);
+ int popupexit_check(ifc_window *w);
+ void popupexit_signal();
+#define RenderBaseTexture renderBaseTexture //CUT
+ void skin_renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *destWnd, int alpha=255);
+ void skin_registerBaseTextureWindow(ifc_window *window, const wchar_t *bmp=NULL);
+ void skin_unregisterBaseTextureWindow(ifc_window *window);
+ void appdeactivation_push_disallow(ifc_window *w);
+ void appdeactivation_pop_disallow(ifc_window *w);
+ int appdeactivation_isallowed(ifc_window *w);
+ void appdeactivation_setbypass(int i);
+ int paintset_present(int set);
+ void paintset_render(int set, ifc_canvas *c, const RECT *r, int alpha=255);
+ void paintset_renderTitle(const wchar_t *t, ifc_canvas *c, const RECT *r, int alpha=255);
+ int forwardOnMouseWheel(int l, int a);
+ void setDefaultDropTarget(void *dt);
+ void *getDefaultDropTarget();
+
+ enum {
+ API_WND_GETROOTWND = 10,
+ API_WND_SETROOTWND = 20,
+ API_WND_GETMODALWND = 30,
+ API_WND_PUSHMODALWND = 40,
+ API_WND_POPMODALWND = 50,
+ API_WND_ROOTWNDFROMPOINT = 60,
+ API_WND_ROOTWNDFROMOSHANDLE = 65,
+ API_WND_REGISTERROOTWND = 70,
+ API_WND_UNREGISTERROOTWND = 80,
+ API_WND_ROOTWNDISVALID = 90,
+ API_WND_INTERCEPTONCHAR = 100,
+ API_WND_INTERCEPTONKEYDOWN = 110,
+ API_WND_INTERCEPTONKEYUP = 120,
+ API_WND_INTERCEPTONSYSKEYDOWN = 130,
+ API_WND_INTERCEPTONSYSKEYUP = 140,
+ API_WND_HOOKKEYBOARD = 150,
+ API_WND_UNHOOKKEYBOARD = 160,
+ API_WND_KBDRESET = 165,
+ API_WND_FORWARDONCHAR = 170,
+ API_WND_FORWARDONKEYDOWN = 180,
+ API_WND_FORWARDONKEYUP = 190,
+ API_WND_FORWARDONSYSKEYDOWN = 200,
+ API_WND_FORWARDONSYSKEYUP = 210,
+ API_WND_FORWARDONKILLFOCUS = 220,
+ API_WND_POPUPEXIT_CHECK = 230,
+ API_WND_POPUPEXIT_SIGNAL = 240,
+ API_WND_POPUPEXIT_REGISTER = 250,
+ API_WND_POPUPEXIT_DEREGISTER = 260,
+ API_WND_RENDERBASETEXTURE = 270,
+ API_WND_REGISTERBASETEXTUREWINDOW = 280,
+ API_WND_UNREGISTERBASETEXTUREWINDOW = 290,
+ API_WND_APPDEACTIVATION_PUSH_DISALLOW = 300,
+ API_WND_APPDEACTIVATION_POP_DISALLOW = 310,
+ API_WND_APPDEACTIVATION_ISALLOWED = 320,
+ API_WND_APPDEACTIVATION_SETBYPASS = 330,
+ API_WND_PAINTSET_PRESENT = 335,
+ API_WND_PAINTSET_RENDER = 340,
+ API_WND_PAINTSET_RENDERTITLE = 350,
+ API_WND_FORWARDONMOUSEWHEEL = 360,
+ // fg> this may need to go away eventually but i need it _right now_
+ API_WND_SETDEFAULTDROPTARGET = 370,
+ API_WND_GETDEFAULTDROPTARGET = 380,
+ API_WND_PUSHKBDLOCK = 390,
+ API_WND_POPKBDLOCK = 400,
+ API_WND_ISKBDLOCKED = 410,
+ };
+};
+
+
+inline ifc_window *wnd_api::main_getRootWnd() {
+ return _call(API_WND_GETROOTWND, (ifc_window *)0 );
+}
+
+inline void wnd_api::main_setRootWnd(ifc_window *w) {
+ _voidcall(API_WND_SETROOTWND, w );
+}
+
+inline ifc_window *wnd_api::getModalWnd() {
+ return _call(API_WND_GETMODALWND, (ifc_window *)0 );
+}
+
+inline void wnd_api::pushModalWnd(ifc_window *w) {
+ _voidcall(API_WND_PUSHMODALWND, w);
+}
+
+inline void wnd_api::popModalWnd(ifc_window *w) {
+ _voidcall(API_WND_POPMODALWND, w);
+}
+
+inline ifc_window *wnd_api::rootWndFromPoint(POINT *pt) {
+ return _call(API_WND_ROOTWNDFROMPOINT, (ifc_window *)0, pt );
+}
+
+inline ifc_window *wnd_api::rootWndFromOSHandle(OSWINDOWHANDLE wnd) {
+ return _call(API_WND_ROOTWNDFROMOSHANDLE, (ifc_window *)0, wnd);
+}
+
+inline void wnd_api::registerRootWnd(ifc_window *wnd) {
+ _voidcall(API_WND_REGISTERROOTWND, wnd );
+}
+
+inline void wnd_api::unregisterRootWnd(ifc_window *wnd) {
+ _voidcall(API_WND_UNREGISTERROOTWND, wnd );
+}
+
+inline int wnd_api::rootwndIsValid(ifc_window *wnd) {
+ return _call(API_WND_ROOTWNDISVALID, (int)0, wnd );
+}
+
+inline int wnd_api::interceptOnChar(unsigned int c) {
+ return _call(API_WND_INTERCEPTONCHAR, (int)0, c );
+}
+
+inline int wnd_api::interceptOnKeyDown(int k) {
+ return _call(API_WND_INTERCEPTONKEYDOWN, (int)0, k );
+}
+
+inline int wnd_api::interceptOnKeyUp(int k) {
+ return _call(API_WND_INTERCEPTONKEYUP, (int)0, k );
+}
+
+inline int wnd_api::interceptOnSysKeyDown(int k, int kd) {
+ return _call(API_WND_INTERCEPTONSYSKEYDOWN, (int)0, k , kd );
+}
+
+inline int wnd_api::interceptOnSysKeyUp(int k, int kd) {
+ return _call(API_WND_INTERCEPTONSYSKEYUP, (int)0, k , kd );
+}
+
+inline void wnd_api::hookKeyboard(ifc_window *hooker) {
+ _voidcall(API_WND_HOOKKEYBOARD, hooker);
+}
+
+inline void wnd_api::unhookKeyboard(ifc_window *hooker) {
+ _voidcall(API_WND_UNHOOKKEYBOARD, hooker);
+}
+
+inline void wnd_api::kbdReset() {
+ _voidcall(API_WND_KBDRESET);
+}
+
+inline int wnd_api::forwardOnChar(ifc_window *from, unsigned int c, int kd) {
+ return _call(API_WND_FORWARDONCHAR, (int)0, from, c, kd );
+}
+
+inline int wnd_api::forwardOnKeyDown(ifc_window *from, int k, int kd) {
+ return _call(API_WND_FORWARDONKEYDOWN, (int)0, from, k, kd);
+}
+
+inline int wnd_api::forwardOnKeyUp(ifc_window *from, int k, int kd) {
+ return _call(API_WND_FORWARDONKEYUP, (int)0, from, k, kd );
+}
+
+inline int wnd_api::forwardOnSysKeyDown(ifc_window *from, int k, int kd) {
+ return _call(API_WND_FORWARDONSYSKEYDOWN, (int)0, from, k , kd );
+}
+
+inline int wnd_api::forwardOnSysKeyUp(ifc_window *from, int k, int kd) {
+ return _call(API_WND_FORWARDONSYSKEYUP, (int)0, from, k , kd );
+}
+
+inline int wnd_api::forwardOnKillFocus() {
+ return _call(API_WND_FORWARDONKILLFOCUS, (int)0 );
+}
+
+inline int wnd_api::popupexit_check(ifc_window *w) {
+ return _call(API_WND_POPUPEXIT_CHECK, 0, w);
+}
+
+inline void wnd_api::popupexit_signal() {
+ _voidcall(API_WND_POPUPEXIT_SIGNAL);
+}
+
+inline void wnd_api::popupexit_register(PopupExitCallback *cb, ifc_window *watched) {
+ _voidcall(API_WND_POPUPEXIT_REGISTER, cb, watched);
+}
+
+inline void wnd_api::popupexit_deregister(PopupExitCallback *cb) {
+ _voidcall(API_WND_POPUPEXIT_DEREGISTER, cb);
+}
+
+#define RenderBaseTexture renderBaseTexture //CUT
+
+inline void wnd_api::skin_renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *destWnd, int alpha) {
+ _voidcall(API_WND_RENDERBASETEXTURE, base, c, &r, destWnd, alpha );
+}
+
+inline void wnd_api::skin_registerBaseTextureWindow(ifc_window *window, const wchar_t *bmp) {
+ _voidcall(API_WND_REGISTERBASETEXTUREWINDOW, window, bmp);
+}
+
+inline void wnd_api::skin_unregisterBaseTextureWindow(ifc_window *window) {
+ _voidcall(API_WND_UNREGISTERBASETEXTUREWINDOW, window );
+}
+
+inline void wnd_api::appdeactivation_push_disallow(ifc_window *w) {
+ _voidcall(API_WND_APPDEACTIVATION_PUSH_DISALLOW, w);
+}
+
+inline void wnd_api::appdeactivation_pop_disallow(ifc_window *w) {
+ _voidcall(API_WND_APPDEACTIVATION_POP_DISALLOW, w);
+}
+
+inline int wnd_api::appdeactivation_isallowed(ifc_window *w) {
+ return _call(API_WND_APPDEACTIVATION_ISALLOWED, 0, w);
+}
+
+inline void wnd_api::appdeactivation_setbypass(int i) {
+ _voidcall(API_WND_APPDEACTIVATION_SETBYPASS, i);
+}
+
+inline int wnd_api::paintset_present(int set)
+{
+ return _call(API_WND_PAINTSET_PRESENT, 0, set);
+}
+
+inline void wnd_api::paintset_render(int set, ifc_canvas *c, const RECT *r, int alpha)
+{
+ _voidcall(API_WND_PAINTSET_RENDER, set, c, r, alpha);
+}
+
+inline void wnd_api::paintset_renderTitle(const wchar_t *t, ifc_canvas *c, const RECT *r, int alpha)
+{
+ _voidcall(API_WND_PAINTSET_RENDERTITLE, t, c, r, alpha);
+}
+
+inline int wnd_api::forwardOnMouseWheel(int l, int a) {
+ return _call(API_WND_FORWARDONMOUSEWHEEL, 0, l, a);
+}
+
+// fg> this may need to go away eventually but i need it _right now_
+
+inline void wnd_api::setDefaultDropTarget(void *dt) {
+ _voidcall(API_WND_SETDEFAULTDROPTARGET, dt);
+}
+
+inline void *wnd_api::getDefaultDropTarget() {
+ return _call(API_WND_GETDEFAULTDROPTARGET, (void*)NULL);
+}
+
+inline int wnd_api::pushKeyboardLock() {
+ return _call(API_WND_PUSHKBDLOCK, 0);
+}
+
+inline int wnd_api::popKeyboardLock() {
+ return _call(API_WND_POPKBDLOCK, 0);
+}
+
+inline int wnd_api::isKeyboardLocked() {
+ return _call(API_WND_ISKBDLOCKED, 0);
+}
+
+class wnd_apiI : public wnd_api {
+ public:
+ virtual void main_setRootWnd(ifc_window *w)=0;
+ virtual ifc_window *main_getRootWnd()=0;
+ virtual ifc_window *getModalWnd()=0;
+ virtual void pushModalWnd(ifc_window *w=MODALWND_NOWND)=0;
+ virtual void popModalWnd(ifc_window *w=MODALWND_NOWND)=0;
+ virtual ifc_window *rootWndFromPoint(POINT *pt)=0;
+ virtual ifc_window *rootWndFromOSHandle(OSWINDOWHANDLE wnd)=0;
+ virtual void registerRootWnd(ifc_window *wnd)=0;
+ virtual void unregisterRootWnd(ifc_window *wnd)=0;
+ virtual int rootwndIsValid(ifc_window *wnd)=0;
+ virtual void hookKeyboard(ifc_window *hooker)=0;
+ virtual void unhookKeyboard(ifc_window *hooker)=0;
+ virtual void kbdReset()=0;
+ virtual int interceptOnChar(unsigned int c)=0;
+ virtual int interceptOnKeyDown(int k)=0;
+ virtual int interceptOnKeyUp(int k)=0;
+ virtual int interceptOnSysKeyDown(int k, int kd)=0;
+ virtual int interceptOnSysKeyUp(int k, int kd)=0;
+ virtual int forwardOnChar(ifc_window *from, unsigned int c, int kd)=0;
+ virtual int forwardOnKeyDown(ifc_window *from, int k, int kd)=0;
+ virtual int forwardOnKeyUp(ifc_window *from, int k, int kd)=0;
+ virtual int forwardOnSysKeyDown(ifc_window *from, int k, int kd)=0;
+ virtual int forwardOnSysKeyUp(ifc_window *from, int k, int kd)=0;
+ virtual int forwardOnKillFocus()=0;
+ virtual void popupexit_deregister(PopupExitCallback *cb)=0;
+ virtual void popupexit_register(PopupExitCallback *cb, ifc_window *watched)=0;
+ virtual int popupexit_check(ifc_window *w)=0;
+ virtual void popupexit_signal()=0;
+ virtual void skin_renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT *r, ifc_window *destWnd, int alpha=255)=0;
+ virtual void skin_registerBaseTextureWindow(ifc_window *window, const wchar_t *bmp=NULL)=0;
+ virtual void skin_unregisterBaseTextureWindow(ifc_window *window)=0;
+ virtual void appdeactivation_push_disallow(ifc_window *w)=0;
+ virtual void appdeactivation_pop_disallow(ifc_window *w)=0;
+ virtual int appdeactivation_isallowed(ifc_window *w)=0;
+ virtual void appdeactivation_setbypass(int i)=0;
+#ifdef WASABI_COMPILE_PAINTSETS
+ virtual int paintset_present(int set)=0;
+#ifdef WASABI_COMPILE_IMGLDR
+ virtual void paintset_render(int set, ifc_canvas *c, const RECT *r, int alpha=255)=0;
+#ifdef WASABI_COMPILE_FONTS
+ virtual void paintset_renderTitle(const wchar_t *t, ifc_canvas *c, const RECT *r, int alpha=255)=0;
+#endif // fonts
+#endif // imgldr
+#endif // paintsets
+ virtual int forwardOnMouseWheel(int l, int a)=0;
+ // fg> this may need to go away eventually but i need it _right now_
+ virtual void setDefaultDropTarget(void *dt)=0;
+ virtual void *getDefaultDropTarget()=0;
+ virtual int pushKeyboardLock()=0;
+ virtual int popKeyboardLock()=0;
+ virtual int isKeyboardLocked()=0;
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {ABB8FBC7-6255-4d41-ACAB-D3D61DDD74EE}
+static const GUID wndApiServiceGuid =
+{ 0xabb8fbc7, 0x6255, 0x4d41, { 0xac, 0xab, 0xd3, 0xd6, 0x1d, 0xdd, 0x74, 0xee } };
+
+extern wnd_api *wndApi;
+
+#endif
diff --git a/Src/Wasabi/api/wnd/basewnd.cpp b/Src/Wasabi/api/wnd/basewnd.cpp
new file mode 100644
index 00000000..f24e4d6f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/basewnd.cpp
@@ -0,0 +1,5743 @@
+#include <precomp.h>
+
+#include <bfc/wasabi_std.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <api/wnd/wndevent.h>
+
+#include <bfc/bfc_assert.h>
+#include <api/wnd/wndclass/tooltip.h>
+#include <api/wnd/cursor.h>
+#include <api/wnd/accessible.h>
+#include <api/service/svcs/svc_accessibility.h>
+#include <api/wnd/paintsets.h>
+#include <api/wnd/PaintCanvas.h>
+
+#ifdef _WIN32
+#include <shellapi.h> // for HDROP
+#endif
+#include <tataki/canvas/bltcanvas.h>
+
+#define DESKTOPALPHA
+#define REFRESH_RATE 25
+#define DRAWTIMERID 125
+
+#include <api/wnd/basewnd.h>
+#include <api/wnd/usermsg.h>
+
+#include <api/wnd/paintcb.h>
+#include <tataki/canvas/canvas.h>
+#include <bfc/file/filename.h>
+#include <tataki/region/region.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptguid.h>
+#include <api/wnd/notifmsg.h>
+#include <api/metrics/metricscb.h>
+
+#include <api/wndmgr/gc.h>
+#include <api/wndmgr/layout.h>
+
+namespace Agave
+{
+ #include "../Agave/Config/api_config.h"
+}
+
+
+
+//#define TIP_TIMER_ID 1601
+#define TIP_DESTROYTIMER_ID 1602
+#define TIP_AWAY_ID 1603
+#define TIP_AWAY_DELAY 100
+
+#define TIP_TIMER_THRESHOLD 350
+#define TIP_LENGTH 3000
+
+#define VCHILD_TIMER_ID_MIN 2000
+#define VCHILD_TIMER_ID_MAX 2100
+
+#define BUFFEREDMSG_TIMER_ID 1604
+
+#define DEFERREDCB_INVALIDATE 0x201 // move to .h
+#define DEFERREDCB_FOCUSFIRST 0x202 // move to .h
+#define DC_KILLGHOST 0x204
+
+#ifdef _WIN32
+#define WM_DEFER_CALLBACK (WM_USER+0x333)
+#endif
+class DragSet : public PtrList<void>, public NamedW {};
+
+//CUT? static void register_wndClass(HINSTANCE);
+
+//CUT? #define ROOTSTRING "RootWnd"
+
+//CUT? #define BASEWNDCLASSNAME "BaseWindow_" ROOTSTRING
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x20A
+#endif
+
+static ifc_window *stickyWnd;
+static RECT sticky;
+
+static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
+
+/*api_window *api_window::rootwndFromPoint(POINT &point, int level) {
+ api_window *wnd;
+ wnd = WASABI_API_WND->rootWndFromPoint(&point);
+ return api_window::rootwndFromRootWnd(wnd, level, &point);
+}
+
+api_window *api_window::rootwndFromRootWnd(api_window *wnd, int level, POINT *point) {
+
+ for (;;) {
+ if (wnd == NULL || level < 0) return NULL;
+ if (point) {
+ RECT r;
+ wnd->getWindowRect(&r);
+ if (!PtInRect(&r, *point)) return NULL; // PORT ME
+ }
+ if (level == 0) return wnd;
+ wnd = wnd->getRootWndParent();
+ level--;
+ }
+ // should never get here
+}*/
+
+static BOOL DisabledWindow_OnMouseClick(HWND hwnd)
+{
+ DWORD windowStyle = (DWORD)GetWindowLongPtrW(hwnd, GWL_STYLE);
+ if (WS_DISABLED != ((WS_CHILD | WS_DISABLED) & windowStyle))
+ return FALSE;
+
+ HWND hActive = GetActiveWindow();
+ HWND hPopup = GetWindow(hwnd, GW_ENABLEDPOPUP);
+
+ BOOL beepOk = (hPopup == hActive || hwnd == GetWindow(hActive, GW_OWNER));
+ if (!beepOk && NULL == hPopup)
+ {
+ for (HWND hWalker = hwnd; ;)
+ {
+ hWalker = GetWindow(hWalker, GW_OWNER);
+ if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE))))
+ break;
+ if (hActive == GetWindow(hWalker, GW_ENABLEDPOPUP))
+ {
+ beepOk = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (beepOk)
+ {
+ static const GUID accessibilityConfigGroupGUID =
+ { 0xe2e7f4a, 0x7c51, 0x478f, { 0x87, 0x74, 0xab, 0xbc, 0xf6, 0xd5, 0xa8, 0x57 } };
+
+ #define GetBoolConfig(__group, __itemName, __default)\
+ ((NULL != (__group)) && NULL != (item = group->GetItem(__itemName)) ? item->GetBool() : (__default))
+
+ waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(Agave::AgaveConfigGUID);
+ Agave::api_config *config = (NULL != serviceFactory) ? (Agave::api_config *)serviceFactory->getInterface() : NULL;
+ Agave::ifc_configgroup *group = (NULL != config) ? config->GetGroup(accessibilityConfigGroupGUID) : NULL;
+ Agave::ifc_configitem *item;
+
+ if (GetBoolConfig(group, L"modalflash", true))
+ {
+ FLASHWINFO flashInfo;
+ flashInfo.cbSize = sizeof(FLASHWINFO);
+ flashInfo.hwnd = hActive;
+ flashInfo.dwFlags = FLASHW_CAPTION;
+ flashInfo.uCount = 2;
+ flashInfo.dwTimeout = 100;
+ FlashWindowEx(&flashInfo);
+ }
+
+ if (GetBoolConfig(group, L"modalbeep", false))
+ MessageBeep(MB_OK);
+
+ if (NULL != config)
+ serviceFactory->releaseInterface(config);
+ }
+ else
+ {
+ for (HWND hWalker = hwnd; NULL == hPopup;)
+ {
+ hWalker = GetWindow(hWalker, GW_OWNER);
+ if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE))))
+ break;
+ hPopup = GetWindow(hWalker, GW_ENABLEDPOPUP);
+ }
+
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
+ if (NULL != hPopup && hPopup != hwnd)
+ {
+ BringWindowToTop(hPopup);
+ SetActiveWindow(hPopup);
+ }
+ }
+
+ return TRUE;
+}
+int WndWatcher::viewer_onItemDeleted(ifc_dependent *item)
+{
+ if (item == dep)
+ {
+ dep = NULL;
+ watcher->wndwatcher_onDeleteWindow(watched);
+ watched = NULL;
+ }
+ return 1;
+}
+
+BaseWnd::BaseWnd()
+{
+ uiwaslocked = 0;
+ m_takenOver = 0;
+ rootfocus = NULL;
+ rootfocuswatcher.setWatcher(this);
+ alwaysontop = 0;
+ customdefaultcursor = NULL;
+ preventcancelcapture = 0;
+ ratiolinked = 1;
+ deleting = 0;
+ hinstance = NULL;
+ hwnd = NULL;
+ parentWnd = NULL;
+ dragging = 0;
+ prevtarg = NULL;
+ inputCaptured = 0;
+ btexture = NULL;
+ postoninit = 0;
+ inited = 0;
+ skipnextfocus = 0;
+ ncb = FALSE;
+ accessible = NULL;
+
+ tooltip = NULL;
+ tip_done = FALSE;
+ tipshowtimer = FALSE;
+ tipawaytimer = FALSE;
+ tipdestroytimer = FALSE;
+ start_hidden = 0;
+ notifyWindow = NULL;
+ lastClick[0] = 0;
+ lastClick[1] = 0;
+ lastClickP[0].x = 0;
+ lastClickP[0].y = 0;
+ lastClickP[1].x = 0;
+ lastClickP[1].y = 0;
+ destroying = FALSE;
+
+ curVirtualChildCaptured = NULL;
+ curVirtualChildFocus = NULL;
+
+ virtualCanvas = NULL; virtualCanvasH = virtualCanvasW = 0;
+ deferedInvalidRgn = NULL;
+
+ hasfocus = 0;
+ focus_on_click = 1;
+ lastnullregion = 0;
+ ratio = 1;
+ lastratio = 1;
+ rwidth = rheight = 0;
+ skin_id = -1;
+ wndalpha = 255;
+ activealpha = 255;
+ inactivealpha = 255;
+ w2k_alpha = 0; //FUCKO
+ scalecanvas = NULL;
+ clickthrough = 0;
+
+ mustquit = 0;
+ returnvalue = 0;
+ notifyid = 0;
+ cloaked = 0;
+ disable_tooltip_til_recapture = 0;
+
+ subtractorrgn = NULL;
+ composedrgn = NULL;
+ wndregioninvalid = 1;
+ regionop = REGIONOP_NONE;
+ rectrgn = 1;
+ need_flush_cascaderepaint = 0;
+ deferedCascadeRepaintRgn = NULL;
+ this_visible = 0;
+ this_enabled = 1;
+ renderbasetexture = 0;
+ oldCapture = NULL;
+ my_guiobject = NULL;
+ want_autoresize_after_init = 0;
+ resizecount = 0;
+ suggested_w = 320;
+ suggested_h = 200;
+ maximum_w = maximum_h = AUTOWH;
+ minimum_w = minimum_h = AUTOWH;
+ rx = 0;
+ ry = 0;
+ rwidth = 0;
+ rheight = 0;
+ allow_deactivate = 1;
+ minimized = 0;
+ inonresize = 0;
+#ifndef WA3COMPATIBILITY
+ m_target = NULL;
+#endif
+
+ nodoubleclick = noleftclick = norightclick = nomousemove = nocontextmnu = 0;
+ focusEventsEnabled = 1;
+ maximized = 0;
+ MEMSET(&restore_rect, 0, sizeof(RECT));
+ ghostbust = 0;
+
+ lastActiveWnd = NULL;
+}
+
+BaseWnd::~BaseWnd()
+{
+ //ASSERT(virtualChildren.getNumItems() == 0);
+ childtabs.deleteAll();
+ if (WASABI_API_WND && WASABI_API_WND->getModalWnd() == this) WASABI_API_WND->popModalWnd(this);
+ destroying = TRUE;
+ curVirtualChildFocus = NULL;
+#ifdef _WIN32
+ if (inputCaptured && GetCapture() == getOsWindowHandle()) ReleaseCapture();
+#else
+#warning port me
+#endif
+
+ for (int i = 0;i < ghosthwnd.getNumItems();i++)
+ Wasabi::Std::Wnd::destroyWnd(ghosthwnd.enumItem(i));
+
+ if (hwnd != NULL && !m_takenOver)
+ {
+#ifdef URLDROPS
+ if (acceptExternalDrops()) Wasabi::Std::Wnd::revokeDragNDrop(hwnd /*, &m_target*/);
+#else
+#ifndef WA3COMPATIBILITY
+ if (m_target != NULL)
+ {
+ Wasabi::Std::Wnd::revokeDragNDrop(hwnd);
+ }
+#endif
+#endif
+ int popact = !wantActivation();
+ if (popact) WASABI_API_WND->appdeactivation_push_disallow(this);
+
+ Wasabi::Std::Wnd::destroyWnd(hwnd);
+
+ if (popact) WASABI_API_WND->appdeactivation_pop_disallow(this);
+ }
+
+ deleteFrameBuffer(virtualCanvas);
+ virtualCanvas = NULL;
+ delete scalecanvas;
+ scalecanvas = NULL;
+
+ resetDragSet();
+
+ notifyParent(ChildNotify::DELETED);
+ if (tipdestroytimer)
+ killTimer(TIP_DESTROYTIMER_ID);
+ if (tipshowtimer)
+ {
+ // TODO: on the mac, use CreateMouseTrackingRegion
+ TRACKMOUSEEVENT tracker;
+ tracker.cbSize=sizeof(tracker);
+ tracker.dwFlags = TME_HOVER|TME_CANCEL;
+ tracker.hwndTrack = this->getOsWindowHandle();
+ tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
+
+ TrackMouseEvent(&tracker);
+
+ }
+ if (tipawaytimer)
+ killTimer(TIP_AWAY_ID);
+
+ destroyTip();
+
+ delete tooltip;
+
+ if (uiwaslocked)
+ killTimer(BUFFEREDMSG_TIMER_ID);
+
+ if (deferedInvalidRgn)
+ delete deferedInvalidRgn;
+
+ delete composedrgn;
+ delete subtractorrgn;
+ delete deferedCascadeRepaintRgn;
+
+ if (parentWnd != NULL)
+ parentWnd->unregisterRootWndChild(this);
+
+ if (!m_takenOver && WASABI_API_WND) WASABI_API_WND->unregisterRootWnd(this);
+ hwnd = NULL;
+}
+
+int BaseWnd::init(ifc_window *parWnd, int nochild)
+{
+ if (parWnd == NULL)
+ return 0;
+
+ OSWINDOWHANDLE phwnd = parWnd->getOsWindowHandle();
+ ASSERT(phwnd != NULL);
+
+ parentWnd = parWnd; // set default parent wnd
+ int ret = init(parWnd->getOsModuleHandle(), phwnd, nochild);
+
+ if (!ret)
+ parentWnd = NULL; // abort
+
+ return ret;
+}
+
+int BaseWnd::init(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild)
+{
+ RECT r;
+ int w, h;
+
+ ASSERTPR(getOsWindowHandle() == NULL, "don't you double init you gaybag");
+
+ hinstance = moduleHandle;
+
+#ifdef _WIN32
+ ASSERT(hinstance != NULL);
+#endif
+
+ //CUT register_wndClass(hinstance);
+
+ if (parent != NULL)
+ {
+ Wasabi::Std::Wnd::getClientRect(parent, &r);
+ }
+ else
+ {
+ Wasabi::Std::setRect(&r, 0, 0, getPreferences(SUGGESTED_W), getPreferences(SUGGESTED_H));
+ }
+
+ w = (r.right - r.left);
+ h = (r.bottom - r.top);
+
+ rwidth = w;
+ rheight = h;
+ rx = r.left;
+ ry = r.top;
+
+ int popact = !wantActivation();
+ if (popact) WASABI_API_WND->appdeactivation_push_disallow(this);
+
+ //CUThwnd = createWindow(r.left, r.top, w, h, nochild, parent, hinstance);
+ hwnd = Wasabi::Std::Wnd::createWnd(&r, nochild, acceptExternalDrops(), parent, hinstance, static_cast<ifc_window*>(this));
+#ifdef __APPLE__
+#warning remove me
+ Wasabi::Std::Wnd::showWnd(hwnd);
+#endif
+
+ if (popact) WASABI_API_WND->appdeactivation_pop_disallow(this);
+
+ //ASSERT(hwnd != NULL); // lets fail nicely, this could happen for some win32 reason, we don't want to fail the whole app for it, so lets just fail the wnd
+ if (hwnd == NULL) return 0;
+
+ if (wantActivation()) bringToFront();
+
+ //CUT nreal++;
+
+ //FUCKO
+#ifdef _WIN32 // PORT ME
+#ifdef URLDROPS
+ if (acceptExternalDrops()) RegisterDragDrop(hwnd, &m_target);
+#else
+#ifndef WA3COMPATIBILITY
+ if (!m_target && WASABI_API_WND != NULL)
+ m_target = WASABI_API_WND->getDefaultDropTarget();
+ if (m_target != NULL)
+ {
+ RegisterDragDrop(hwnd, (IDropTarget *)m_target);
+ }
+#endif
+#endif
+#endif
+
+ this_visible = 0;
+
+ onInit();
+
+ this_visible = !start_hidden;
+
+ onPostOnInit();
+
+ return 1;
+}
+
+#ifndef WA3COMPATIBILITY
+void BaseWnd::setDropTarget(void *dt)
+{
+#ifdef _WIN32
+ if (isVirtual()) return ;
+ if (isInited() && m_target != NULL)
+ {
+ Wasabi::Std::Wnd::revokeDragNDrop(getOsWindowHandle());
+ m_target = NULL;
+ }
+ m_target = dt;
+ if (m_target != NULL && isInited())
+ {
+ RegisterDragDrop(gethWnd(), (IDropTarget *)m_target);
+ }
+#else
+#warning port me
+#endif
+}
+
+void *BaseWnd::getDropTarget()
+{
+ return m_target;
+}
+#endif
+
+int BaseWnd::onInit()
+{
+
+ const wchar_t *s = getName();
+ if (s != NULL)
+ setOSWndName(s);
+
+ inited = 1;
+
+ if (getParent())
+ getParent()->registerRootWndChild(this);
+
+ if (WASABI_API_WND != NULL)
+ WASABI_API_WND->registerRootWnd(this);
+
+#ifdef _WIN32
+ if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable())
+ w2k_alpha = 0; //FUCKO
+
+ if (w2k_alpha)
+ {
+ setLayeredWindow(1);
+ }
+
+ if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
+ WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
+
+#endif
+
+ return 0;
+}
+
+int BaseWnd::onPostOnInit()
+{
+ postoninit = 1; // from now on, isInited() returns 1;
+ if (want_autoresize_after_init) onResize();
+ else invalidateWindowRegion();
+ if (isVisible()) onSetVisible(1);
+ if (getTabOrder() == -1) setAutoTabOrder();
+ ifc_window *dp = getDesktopParent();
+ if ((dp == NULL || dp == this) && WASABI_API_TIMER != NULL)
+ postDeferredCallback(DEFERREDCB_FOCUSFIRST, 0, 500);
+ return 0;
+}
+
+void BaseWnd::setLayeredWindow(int i)
+{
+ if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ;
+ if (!isInited()) return ;
+ Wasabi::Std::Wnd::setLayeredWnd(getOsWindowHandle(), i);
+#if 0//CUT
+ if (i)
+ {
+ SetWindowLong(getOsWindowHandle(), GWL_EXSTYLE, GetWindowLong(getOsWindowHandle(), GWL_EXSTYLE) & ~WS_EX_LAYERED);
+ SetWindowLong(getOsWindowHandle(), GWL_EXSTYLE, GetWindowLong(getOsWindowHandle(), GWL_EXSTYLE) | WS_EX_LAYERED);
+ }
+ else
+ {
+ SetWindowLong(getOsWindowHandle(), GWL_EXSTYLE, GetWindowLong(getOsWindowHandle(), GWL_EXSTYLE) & ~WS_EX_LAYERED);
+ }
+#endif
+ setTransparency(-1);
+}
+
+int BaseWnd::getCursorType(int x, int y)
+{
+ if (!customdefaultcursor)
+ return BASEWND_CURSOR_POINTER;
+ return BASEWND_CURSOR_USERSET;
+}
+
+void BaseWnd::onSetName()
+{
+ if (isInited() && !isVirtual())
+ Wasabi::Std::Wnd::setWndName(getOsWindowHandle(), getNameSafe());
+ notifyParent(ChildNotify::NAMECHANGED);
+ if (accessible)
+ accessible->onSetName(getName());
+}
+
+OSWINDOWHANDLE BaseWnd::getOsWindowHandle()
+{
+ OSWINDOWHANDLE handle;
+
+ if ( isVirtual() )
+ handle = getParent()->getOsWindowHandle();
+ else
+ handle = hwnd;
+
+
+ return handle;
+}
+
+OSMODULEHANDLE BaseWnd::getOsModuleHandle()
+{
+ return hinstance;
+}
+
+void BaseWnd::onTip()
+{
+ tipshowtimer = FALSE;
+ tip_done = TRUE;
+
+ POINT p;
+ Wasabi::Std::getMousePos(&p);
+ if (WASABI_API_WND->rootWndFromPoint(&p) == (ifc_window *)this)
+ {
+ createTip();
+ setTimer(TIP_DESTROYTIMER_ID, TIP_LENGTH);
+ tipdestroytimer = TRUE;
+ }
+ setTimer(TIP_AWAY_ID, TIP_AWAY_DELAY);
+ tipawaytimer = TRUE;
+}
+
+void BaseWnd::timerCallback(int id)
+{
+ switch (id)
+ {
+ case BUFFEREDMSG_TIMER_ID:
+ checkLockedUI();
+ break;
+// case TIP_TIMER_ID:
+ //onTip();
+ //break;
+ case TIP_DESTROYTIMER_ID:
+ killTimer(TIP_DESTROYTIMER_ID);
+ killTimer(TIP_AWAY_ID);
+ tipawaytimer = FALSE;
+ tipdestroytimer = FALSE;
+ destroyTip();
+ break;
+ case TIP_AWAY_ID:
+ onTipMouseMove();
+ break;
+ }
+}
+
+int BaseWnd::isInited()
+{
+ return inited;
+}
+
+int BaseWnd::isDestroying()
+{
+ return destroying;
+}
+
+int BaseWnd::wantSiblingInvalidations()
+{
+ return FALSE;
+}
+
+void BaseWnd::setRSize(int x, int y, int w, int h)
+{
+ rwidth = w;
+ rheight = h;
+ rx = x;
+ ry = y;
+}
+
+void BaseWnd::resize(int x, int y, int w, int h, int wantcb)
+{
+ inonresize = 1;
+
+ if (x == AUTOWH) x = NOCHANGE;
+ if (y == AUTOWH) y = NOCHANGE;
+ if (w == AUTOWH) w = NOCHANGE;
+ if (h == AUTOWH) h = NOCHANGE;
+
+ if (getNumMinMaxEnforcers() > 0)
+ {
+ int min_w = getPreferences(MINIMUM_W);
+ int min_h = getPreferences(MINIMUM_H);
+ int max_w = getPreferences(MAXIMUM_W);
+ int max_h = getPreferences(MAXIMUM_H);
+ if (min_w != AUTOWH && w != NOCHANGE && w < min_w) w = min_w;
+ if (max_w != AUTOWH && w != NOCHANGE && w > max_w) w = max_w;
+ if (min_h != AUTOWH && h != NOCHANGE && h < min_h) h = min_h;
+ if (max_h != AUTOWH && h != NOCHANGE && h > max_h) h = max_h;
+ }
+
+ int noresize = (w == NOCHANGE && h == NOCHANGE);
+ int nomove = (x == NOCHANGE && y == NOCHANGE)/* || (x == rx && y == ry)*/;
+ if (x == NOCHANGE) x = rx;
+ if (y == NOCHANGE) y = ry;
+ if (w == NOCHANGE) w = rwidth;
+ if (h == NOCHANGE) h = rheight;
+
+#ifdef _DEBUG
+ ASSERT(x < 0xFFF0);
+ ASSERT(y < 0xFFF0);
+ ASSERT(w < 0xFFF0);
+ ASSERT(h < 0xFFF0);
+#endif
+
+ double thisratio = getRenderRatio();
+ int different_ratio = (lastratio != thisratio);
+ lastratio = thisratio;
+
+ int noevent = (resizecount > 1 && w == rwidth && h == rheight);
+ //ifc_window *dp = getDesktopParent();
+ if (different_ratio == 1 && noevent == 1)
+ {
+ if (Wasabi::Std::Wnd::getTopmostChild(getOsWindowHandle()) != INVALIDOSWINDOWHANDLE)
+ noevent = 0;
+ invalidateWindowRegion();
+ }
+
+ RECT oldsize, newsize = Wasabi::Std::makeRect(x, y, w, h);
+ if (hwnd != NULL)
+ BaseWnd::getNonClientRect(&oldsize);
+ else
+ oldsize = newsize;
+
+ setRSize(x, y, w, h);
+
+ if (handleRatio() && renderRatioActive())
+ {
+ multRatio(&w, &h);
+ if (getParent() != NULL)
+ {
+ multRatio(&x, &y);
+ }
+ }
+
+ if (!noevent)
+ {
+ if (wantcb && isPostOnInit())
+ {
+ resizecount = MIN(5, ++resizecount);
+ if (!isVirtual())
+ invalidateWindowRegion();
+ onResize();
+ if (ensureWindowRegionValid())
+ updateWindowRegion();
+ }
+ }
+
+ if (getOsWindowHandle() != NULL)
+ {
+
+ RECT oldsizescaled;
+ getWindowRect(&oldsizescaled);
+ RECT newsizescaled = {x, y, x + w, y + h};
+ if (MEMCMP(&newsizescaled, &oldsizescaled, sizeof(RECT)))
+ {
+ //CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, w, h,
+ //CUT SWP_NOZORDER |
+ //CUT SWP_NOACTIVATE |
+ //CUT (!wantRedrawOnResize() ? SWP_NOCOPYBITS: 0) |
+ //CUT (ncb ? SWP_NOCOPYBITS : 0) |
+ //CUT ( nomove ? SWP_NOMOVE : 0) |
+ //CUT ( noresize ? SWP_NOSIZE : 0) |
+ //CUT 0);
+ Wasabi::Std::Wnd::setWndPos( getOsWindowHandle(), NULL, x, y, w, h, TRUE, TRUE, !wantRedrawOnResize() || ncb, nomove, noresize );
+ }
+ //else
+ //{
+ // DebugStringW(L"BaseWnd::resize optimized\n");
+ //}
+
+ onAfterResize();
+
+ if (ncb)
+ invalidate();
+ else
+ {
+ RECT r;
+ if (hwnd != NULL)
+ {
+ if (newsize.left == oldsize.left && newsize.top == oldsize.top)
+ {
+ if (newsize.right > oldsize.right)
+ {
+ // growing in width
+ r.left = oldsize.right;
+ r.right = newsize.right;
+ r.top = newsize.top;
+ r.bottom = newsize.bottom;
+ invalidateRect(&r);
+ if (newsize.bottom > oldsize.bottom)
+ {
+ // growing in width & height
+ r.left = oldsize.left;
+ r.right = newsize.right;
+ r.top = oldsize.bottom;
+ r.bottom = newsize.bottom;
+ invalidateRect(&r);
+ }
+ }
+ else if (newsize.bottom > oldsize.bottom)
+ {
+ if (newsize.bottom > oldsize.bottom)
+ {
+ // growing in height
+ r.left = oldsize.left;
+ r.right = newsize.right;
+ r.top = oldsize.bottom;
+ r.bottom = newsize.bottom;
+ invalidateRect(&r);
+ }
+ }
+ }
+ }
+ }
+ }
+ inonresize = 0;
+}
+
+void BaseWnd::forcedOnResizeChain(ifc_window *w)
+{
+ w->triggerEvent(TRIGGER_ONRESIZE);
+ int n = w->getNumRootWndChildren();
+ for (int i = 0;i < n;i++)
+ {
+ forcedOnResizeChain(w->enumRootWndChildren(i));
+ }
+}
+
+int BaseWnd::forcedOnResize()
+{
+ forcedOnResizeChain(this);
+ return 1;
+}
+
+int BaseWnd::onResize()
+{
+ if (!isVirtual() || (getRegionOp() != REGIONOP_NONE))
+ invalidateWindowRegion();
+ // you are not supposed to call onResize until after onInit has returned. If what you wanted was to generate
+ // an onResize event to do some custom client coordinates recalculations (ie: to apply on your children)
+ // then you don't need to do anything since onResize is going to be called after onInit() is done. If you still want to
+ // trigger it because your code might be called by onInit and after onInit, use isPostOnInit() as a test.
+ // if what you wanted was to signal a object that you just resized it, then you don't need to do anything beside
+ // resize(...), it will generate the event on its own if the window is inited, and will defer to until after onInit
+ // if it is not.
+ // shortly put: do not call onResize before or inside onInit()
+ // if you have any valid reason for doing that, i'd like to know about it so i can make it possible. -FG
+#ifdef _DEBUG
+ if (!isPostOnInit())
+ {
+ //__asm int 3;
+ ASSERTPR(isPostOnInit(), "do not call onResize before or inside onInit()");
+ }
+#endif
+ return FALSE;
+}
+
+void BaseWnd::resizeToClient(BaseWnd *wnd)
+{
+ if (wnd != NULL)
+ wnd->resize(&clientRect());
+}
+
+int BaseWnd::onPostedMove()
+{
+ /*
+ if (w2k_alpha && Wasabi::Std::Wnd::isDesktopAlphaAvailable() && !cloaked)
+ {
+ RECT r;
+ getWindowRect(&r);
+ Wasabi::Std::Wnd::moveLayeredWnd(hwnd, r.left, r.top);
+ }*/
+ return FALSE;
+}
+
+void BaseWnd::resize(RECT *r, int wantcb)
+{
+ resize(r->left, r->top, r->right - r->left, r->bottom - r->top, wantcb);
+}
+
+void BaseWnd::move(int x, int y)
+{
+ //DebugStringW( L"BaseWnd::move( x = %d, y = %d )\n", x, y );
+
+ setRSize(x, y, rwidth, rheight);
+ Wasabi::Std::Wnd::setWndPos( getOsWindowHandle(), NULL, x, y, 0, 0, TRUE, TRUE, ncb, FALSE, TRUE );
+ //CUT if (!ncb)
+ //CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DEFERERASE);
+ //CUT else
+ //CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_DEFERERASE);
+}
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+BOOL CALLBACK EnumOwnedTopMostWindows(HWND hwnd, LPARAM lParam)
+{
+ enumownedstruct *st = (enumownedstruct *)lParam;
+ if (hwnd != st->hthis && GetWindow(hwnd, GW_OWNER) == st->owner)
+ {
+ ifc_window *w = (ifc_window*)GetWindowLong(hwnd, GWL_USERDATA);
+ if (w != NULL && w->getAlwaysOnTop())
+ st->hlist->addItem(w);
+ }
+ return TRUE;
+}
+
+void BaseWnd::saveTopMosts()
+{
+ HWND owner = GetWindow(getOsWindowHandle(), GW_OWNER);
+ enumownedstruct st;
+ ontoplist.removeAll();
+ if (owner != NULL)
+ {
+ st.owner = owner;
+ st.hlist = &ontoplist;
+ st.hthis = getOsWindowHandle();
+ EnumWindows(EnumOwnedTopMostWindows, (long)&st);
+ }
+}
+
+void BaseWnd::restoreTopMosts()
+{
+ HWND owner = GetWindow(getOsWindowHandle(), GW_OWNER);
+ if (owner != NULL)
+ {
+ for (int i = 0;i < ontoplist.getNumItems();i++)
+ {
+ ontoplist.enumItem(i)->setAlwaysOnTop(1);
+ }
+ }
+}
+#endif
+
+void BaseWnd::bringToFront()
+{
+ // when we set a window to the top of the zorder (not topmost), win32 finds the owner and removes any topmost flag its children may
+ // have because it assumes we want this window over these, which we definitly don't. so we need to first go thru all the owner's children,
+ // make a list of the ones with a topmost flag, set this window on top, and set the topmost flags back. yay
+ ASSERT(!isVirtual());
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ saveTopMosts();
+#endif
+ //CUT SetWindowPos(getOsWindowHandle(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE|SWP_DEFERERASE|SWP_NOOWNERZORDER);
+ Wasabi::Std::Wnd::bringToFront(getOsWindowHandle());
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ restoreTopMosts();
+#endif
+}
+
+void BaseWnd::bringToBack()
+{
+ ASSERT(!isVirtual());
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ saveTopMosts();
+#endif
+ //CUT SetWindowPos(getOsWindowHandle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE|SWP_DEFERERASE|SWP_NOOWNERZORDER);
+ Wasabi::Std::Wnd::sendToBack(getOsWindowHandle());
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ restoreTopMosts();
+#endif
+}
+
+void BaseWnd::setVisible(int show)
+{
+ int visible = isVisible(1);
+ if (!!visible == !!show) return ;
+ invalidate();
+ this_visible = !!show;
+ /*if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() && IsWindow(getOsWindowHandle())) {
+ if (!show) {
+ setLayeredWindow(0);
+ if (setLayeredWindowAttributes)
+ setLayeredWindowAttributes(hwnd, RGB(0,0,0), 255, LWA_ALPHA);
+ } else {
+ setLayeredWindow(w2k_alpha);
+ }
+ }*/
+ if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() || getParent()->isVisible())
+ {
+ onSetVisible(show);
+ }
+}
+
+void BaseWnd::setCloaked(int cloak)
+{
+ if (cloaked == cloak) return ;
+ cloaked = cloak;
+ if (isVirtual()) return ;
+ if (cloaked)
+ {
+ //CUTif (IsWindowVisible(getOsWindowHandle()))
+ //CUT ShowWindow(getOsWindowHandle(), SW_HIDE);
+ if (Wasabi::Std::Wnd::isWndVisible(getOsWindowHandle()))
+ Wasabi::Std::Wnd::hideWnd(getOsWindowHandle());
+ }
+ else
+ {
+ if (isVisible(1))
+ //CUTShowWindow(getOsWindowHandle(), SW_NORMAL);
+ Wasabi::Std::Wnd::showWnd(getOsWindowHandle());
+ }
+}
+
+
+void BaseWnd::onSetVisible(int show)
+{
+ /* for debug purposes - don't delete please
+ #include "../../../studio/container.h"
+ #include "../../../studio/layout.h"
+ if (!show && getGuiObject() && STRCASEEQLSAFE(getGuiObject()->guiobject_getId(), "normal")) {
+ Layout *l = (Layout *)getInterface(layoutGuid);
+ if (l) {
+ if (l->getParentContainer() && STRCASEEQLSAFE(l->getParentContainer()->getId(), "main")) {
+ DebugString("Hiding main player\n");
+ }
+ }
+ }*/
+ if (!isVirtual())
+ if (hwnd != NULL)
+ if (!cloaked)
+ {
+ //CUT // SetWindowPos(getOsWindowHandle(),NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW);
+ //CUT ShowWindow(getOsWindowHandle(), show ? SW_SHOWNA : SW_HIDE);
+ if (show)
+ Wasabi::Std::Wnd::showWnd(getOsWindowHandle(), TRUE);
+ else
+ Wasabi::Std::Wnd::hideWnd(getOsWindowHandle());
+ }
+ /* if (!show)
+ postDeferredCallback(0x7849);
+ else {*/
+ foreach(rootwndchildren)
+ ifc_window *w = rootwndchildren.getfor();
+ if (w && w->isVisible(1)) // check internal flag only
+ w->onSetVisible(show);
+ endfor;
+ dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_SETVISIBLE, show);
+ //}
+ /* if (getDesktopParent() == this) {
+ cascadeRepaint(0);
+ }*/
+
+ /*#ifdef WIN32 // os-specific non virtual child wnd support
+ if (!isVirtual()) {
+ HWND w = GetWindow(getOsWindowHandle(), GW_CHILD);
+ while (w != NULL) {
+ api_window *rootwnd = (api_window*)GetWindowLong(w, GWL_USERDATA);
+ if (rootwnd && rootwnd != this)
+ if (rootwnd->isInited())
+ rootwnd->onSetVisible(show);
+ w = GetWindow(w, GW_HWNDNEXT);
+ }
+ }
+ #endif*/
+ if (!isVirtual())
+ {
+ if (!show)
+ {
+ deferedInvalidate();
+ delete virtualCanvas;
+ virtualCanvas = NULL;
+ }
+ }
+ invalidateWindowRegion();
+}
+
+void BaseWnd::setEnabled(int en)
+{
+ int enabled = isEnabled(1);
+ if (!!enabled == !!en) return ;
+ invalidate();
+ this_enabled = !!en;
+ if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() || getParent()->isEnabled())
+ {
+ onEnable(en);
+ }
+}
+
+int BaseWnd::isEnabled(int within)
+{
+ if (!isVirtual() && !getOsWindowHandle()) return 0;
+ if (!this_enabled) return 0;
+
+ if (within) return this_enabled; // whatever, local
+
+ if (isVirtual()) // virtual, global
+ if (getParent())
+ return getParent()->isEnabled();
+ else
+ return 0;
+
+ // non virtual, global
+ //CUT if (GetWindowLong(getOsWindowHandle(), GWL_STYLE) & WS_POPUP) return this_enabled;
+ if (Wasabi::Std::Wnd::isPopup(getOsWindowHandle())) return this_enabled;
+ //CUT if (!Wasabi::Std::Wnd::isValidWnd(GetParent(gethWnd()))) return this_enabled;
+ if (!Wasabi::Std::Wnd::isValidWnd(Wasabi::Std::Wnd::getParent(getOsWindowHandle()))) return this_enabled;
+ if (getParent()) return getParent()->isEnabled(); // not a popup, check its parent or fail
+ return this_enabled;
+}
+
+int BaseWnd::onEnable(int en)
+{
+ if (!isVirtual())
+ {
+ if (hwnd != NULL)
+ //CUT EnableWindow(getOsWindowHandle(), en);
+ Wasabi::Std::Wnd::setEnabled(getOsWindowHandle(), en);
+ foreach(rootwndchildren)
+ ifc_window *w = rootwndchildren.getfor();
+ if (w->isEnabled(1)) // check internal flag only
+ w->onEnable(en);
+ endfor;
+ }
+ return 1;
+}
+
+void BaseWnd::setFocus()
+{
+ if (curVirtualChildFocus != NULL)
+ {
+ curVirtualChildFocus->onKillFocus();
+ curVirtualChildFocus = NULL;
+ }
+ onSetRootFocus(this);
+ //CUT SetFocus(getOsWindowHandle());
+ Wasabi::Std::Wnd::setFocus(getOsWindowHandle());
+}
+
+void BaseWnd::setFocusOnClick(int f)
+{
+ focus_on_click = f;
+}
+
+api_region *BaseWnd::getDeferedInvalidRgn()
+{
+ return deferedInvalidRgn;
+}
+
+void BaseWnd::deferedInvalidate()
+{
+ if (!hasVirtualChildren() || !isVisible(1)) return ;
+ RECT r = Wasabi::Std::makeRect(0, 0, 0, 0);
+ getNonClientRect(&r);
+ deferedInvalidateRect(&r);
+}
+
+void BaseWnd::deferedInvalidateRect(RECT *r)
+{
+ if (!hasVirtualChildren()) return ;
+ RegionI h(r);
+ deferedInvalidateRgn(&h);
+}
+
+void BaseWnd::deferedInvalidateRgn(api_region *h)
+{
+ if (!hasVirtualChildren()) return ;
+ if (!deferedInvalidRgn)
+ {
+ deferedInvalidRgn = new RegionI();
+ }
+
+ deferedInvalidRgn->addRegion(h);
+}
+
+void BaseWnd::deferedValidate()
+{
+ if (!hasVirtualChildren() || !isVisible(1)) return ;
+ RECT r = Wasabi::Std::makeRect(0,0,0,0);
+ getNonClientRect(&r);
+ deferedValidateRect(&r);
+}
+
+void BaseWnd::deferedValidateRect(RECT *r)
+{
+ if (!hasVirtualChildren()) return ;
+ RegionI h(r);
+ deferedValidateRgn(&h);
+}
+
+void BaseWnd::deferedValidateRgn(api_region *h)
+{
+ if (!hasVirtualChildren()) return ;
+ if (!deferedInvalidRgn) return ;
+
+ deferedInvalidRgn->subtractRgn(h);
+}
+
+int BaseWnd::hasVirtualChildren()
+{
+ return 1; //virtualChildren.getNumItems() > 0;
+}
+
+void BaseWnd::invalidate()
+{
+ invalidateFrom(this);
+}
+
+void BaseWnd::invalidateFrom(ifc_window *who)
+{
+ if (hasVirtualChildren()) deferedInvalidate();
+ //CUT if (hwnd != NULL && isVisible(1)) InvalidateRect(getOsWindowHandle(), NULL, FALSE);
+ if (hwnd != NULL && isVisible(1))
+ Wasabi::Std::Wnd::invalidateRect(getOsWindowHandle());
+}
+
+void BaseWnd::invalidateRectFrom(RECT *r, ifc_window *who)
+{
+ if (hasVirtualChildren()) deferedInvalidateRect(r);
+ RegionI rg(r);
+ invalidateRgnFrom(&rg, who);
+}
+
+void BaseWnd::invalidateRgn(api_region *r)
+{
+ invalidateRgnFrom(r, this);
+}
+
+void BaseWnd::invalidateRect(RECT *r)
+{
+ invalidateRectFrom(r, this);
+}
+
+void BaseWnd::invalidateRgnFrom(api_region *r, ifc_window *who)
+{
+ if (parentWnd) parentWnd->onChildInvalidate(r, who);
+ PaintCallbackInfoI pc(NULL, r);
+ dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_ONINVALIDATE, 0, &pc);
+ if (hwnd != NULL && isVisible(1))
+ {
+ if (hasVirtualChildren())
+ {
+ api_region *_r = r->clone();
+ int j = virtualChildren.searchItem(who);
+ for (int i = 0;i < virtualChildren.getNumItems();i++)
+ {
+ ifc_window *w = virtualChildren[i];
+ if (w != who && w->wantSiblingInvalidations())
+ w->onSiblingInvalidateRgn(_r, who, j, i);
+ }
+
+ deferedInvalidateRgn(_r);
+ physicalInvalidateRgn(_r);
+ r->disposeClone(_r);
+ }
+ else
+ {
+ deferedInvalidateRgn(r);
+ physicalInvalidateRgn(r);
+ }
+ }
+}
+
+void BaseWnd::physicalInvalidateRgn(api_region *r)
+{
+ if (hwnd != NULL && isVisible(1))
+ {
+ if (renderRatioActive())
+ {
+ api_region *clone = r->clone();
+ clone->scale(getRenderRatio(), getRenderRatio(), TRUE);
+ //CUT InvalidateRgn(getOsWindowHandle(), clone->getOSHandle(), FALSE);
+ Wasabi::Std::Wnd::invalidateRegion(getOsWindowHandle(), clone->getOSHandle());
+ r->disposeClone(clone);
+ }
+ else
+ //CUT InvalidateRgn(getOsWindowHandle(), r->getOSHandle(), FALSE);
+ Wasabi::Std::Wnd::invalidateRegion(getOsWindowHandle(), r->getOSHandle());
+ }
+}
+
+void BaseWnd::validate()
+{
+ //CUT if (hwnd != NULL) ValidateRect(getOsWindowHandle(), NULL);
+ if (hwnd != NULL)
+ Wasabi::Std::Wnd::validateRect(getOsWindowHandle());
+}
+
+void BaseWnd::validateRect(RECT *r)
+{
+ if (hwnd != NULL)
+ {
+ if (renderRatioActive())
+ {
+ RECT r2 = *r;
+ Wasabi::Std::scaleRect(&r2, getRenderRatio());
+ //CUT ValidateRect(getOsWindowHandle(), &r2);
+ Wasabi::Std::Wnd::validateRect(getOsWindowHandle(), &r2);
+ }
+ else
+ //CUT ValidateRect(getOsWindowHandle(), r);
+ Wasabi::Std::Wnd::validateRect(getOsWindowHandle(), r);
+ }
+}
+
+void BaseWnd::validateRgn(api_region *reg)
+{
+ if (hwnd != NULL)
+ {
+ if (renderRatioActive())
+ {
+ api_region *clone = reg->clone();
+ clone->scale(getRenderRatio(), getRenderRatio(), TRUE);
+ //CUT ValidateRgn(getOsWindowHandle(), clone->getOSHandle());
+ Wasabi::Std::Wnd::validateRegion(getOsWindowHandle(), clone->getOSHandle());
+ reg->disposeClone(clone);
+ }
+ else
+ //CUT ValidateRgn(getOsWindowHandle(), reg->getOSHandle());
+ Wasabi::Std::Wnd::validateRegion(getOsWindowHandle(), reg->getOSHandle());
+ }
+}
+
+void BaseWnd::repaint()
+{
+ /* if (hasVirtualChildren()) {
+ api_region *h = new api_region();
+ int s = GetUpdateRgn(getOsWindowHandle(), h->getHRGN(), FALSE);
+ if (s != NULLREGION && s != ERROR) {
+ virtualDrawRgn(h);
+ }
+ delete h;
+ }*/
+ //CUTif (hwnd != NULL) UpdateWindow(getOsWindowHandle());
+ if (hwnd != NULL)
+ Wasabi::Std::Wnd::update(getOsWindowHandle());
+}
+
+void BaseWnd::getClientRect(RECT *rect)
+{
+ /* rect->left = rx;
+ rect->right = rx + rwidth;
+ rect->top = ry;
+ rect->bottom = ry + rheight;*/
+ //ASSERT(hwnd != NULL);
+ if (!Wasabi::Std::Wnd::isValidWnd(hwnd))
+ {
+ MEMSET(rect, 0, sizeof(RECT));
+ return ;
+ }
+
+ GetClientRect(getOsWindowHandle(), rect);
+ ////Wasabi::Std::Wnd::getClientRect(getOsWindowHandle(), rect);
+ rect->right = rect->left + rwidth;
+ rect->bottom = rect->top + rheight;
+}
+
+RECT BaseWnd::clientRect()
+{
+ RECT ret;
+ getClientRect(&ret);
+ return ret;
+}
+
+void BaseWnd::getNonClientRect(RECT *rect)
+{
+ // ASSERT(hwnd != NULL);
+ if (!hwnd)
+ getClientRect(rect);
+ else
+ {
+ Wasabi::Std::Wnd::getClientRect(getOsWindowHandle(), rect);
+ if (getRenderRatio() != 1.0)
+ {
+ rect->right = rect->left + rwidth;
+ rect->bottom = rect->left + rheight;
+ }
+ }
+ /* rect->left = rx;
+ rect->right = rx + rwidth;
+ rect->top = ry;
+ rect->bottom = ry + rheight;*/
+}
+
+RECT BaseWnd::nonClientRect()
+{
+ RECT ret;
+ getNonClientRect(&ret);
+ return ret;
+}
+
+void BaseWnd::getWindowRect(RECT *rect)
+{
+ //CUT#ifdef WIN32
+ //CUT ASSERT(hwnd != NULL);
+ //CUT GetWindowRect(getOsWindowHandle(), rect);
+ //CUT#else
+ //CUT#error port me
+ //CUT#endif
+ Wasabi::Std::Wnd::getWindowRect(getOsWindowHandle(), rect);
+}
+
+// get position relative to parent (same coordinate system for basewnd & virtualwnd)
+void BaseWnd::getPosition(POINT *pt)
+{
+ pt->x = rx;
+ pt->y = ry;
+}
+
+void *BaseWnd::dependent_getInterface(const GUID *classguid)
+{
+ HANDLEGETINTERFACE(ifc_window);
+ //CUT HANDLEGETINTERFACE(api_window);
+ return NULL;
+}
+
+RECT BaseWnd::windowRect()
+{
+ RECT ret;
+ getWindowRect(&ret);
+ return ret;
+}
+
+
+void BaseWnd::clientToScreen(int *x, int *y)
+{
+ int _x = x ? *x : 0;
+ int _y = y ? *y : 0;
+ if (renderRatioActive())
+ {
+ _x = (int)((double)_x * getRenderRatio());
+ _y = (int)((double)_y * getRenderRatio());
+ }
+ Wasabi::Std::Wnd::clientToScreen(getOsWindowHandle(), &_x, &_y);
+ if (x) *x = _x;
+ if (y) *y = _y;
+}
+
+void BaseWnd::clientToScreen(RECT *r)
+{
+ clientToScreen((int*)&r->left, (int*)&r->top);
+ clientToScreen((int*)&r->right, (int*)&r->bottom);
+}
+
+void BaseWnd::clientToScreen(POINT *p)
+{
+ clientToScreen((int *)&p->x, (int *)&p->y);
+}
+
+void BaseWnd::screenToClient(int *x, int *y)
+{
+ //CUT POINT p;
+ int _x = x ? *x : 0;
+ int _y = y ? *y : 0;
+ //CUT ScreenToClient(getOsWindowHandle(), &p);
+ Wasabi::Std::Wnd::screenToClient(getOsWindowHandle(), &_x, &_y);
+ if (renderRatioActive())
+ {
+ _x = (int)((double)_x / getRenderRatio());
+ _y = (int)((double)_y / getRenderRatio());
+ }
+ if (x) *x = _x;
+ if (y) *y = _y;
+}
+
+void BaseWnd::screenToClient(RECT *r)
+{
+ screenToClient((int*)&r->left, (int*)&r->top);
+ screenToClient((int*)&r->right, (int*)&r->bottom);
+}
+
+void BaseWnd::screenToClient(POINT *p)
+{
+ screenToClient((int *)&p->x, (int *)&p->y);
+}
+
+void BaseWnd::setParent(ifc_window *newparent)
+{
+ ASSERTPR(newparent != NULL, "quit being a weeny");
+ ASSERTPR(parentWnd == NULL || newparent == parentWnd, "can't reset parent");
+ parentWnd = newparent;
+ if (isInited())
+ {
+ OSWINDOWHANDLE w1 = getOsWindowHandle();
+ OSWINDOWHANDLE w2 = newparent->getOsWindowHandle();
+ if (w1 != w2)
+ //CUT SetParent(w1, w2);
+ Wasabi::Std::Wnd::setParent(w1, w2);
+ }
+}
+
+//FUCKO
+int BaseWnd::reparent(ifc_window *newparent)
+{
+#ifdef _WIN32
+ if (!isVirtual())
+ {
+ if (isInited())
+ {
+ ifc_window *old = getParent();
+ if (!old && newparent)
+ {
+ ::SetParent(getOsWindowHandle(), newparent->getOsWindowHandle());
+ SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) & ~WS_POPUP);
+ SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) | WS_CHILD);
+ }
+ else if (old && !newparent)
+ {
+ SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) & ~WS_CHILD);
+ SetWindowLong(getOsWindowHandle() , GWL_STYLE, GetWindowLong(getOsWindowHandle(), GWL_STYLE) | WS_POPUP);
+ ::SetParent(getOsWindowHandle(), NULL);
+ }
+ else
+ {
+ ::SetParent(getOsWindowHandle(), newparent ? newparent->getOsWindowHandle() : NULL);
+ }
+ }
+ }
+
+ parentWnd = newparent;
+ onSetParent(newparent);
+
+#ifdef WASABI_ON_REPARENT
+ WASABI_ON_REPARENT(getOsWindowHandle());
+#endif
+#else
+#warning port me
+#endif
+ return 1;
+}
+
+ifc_window *BaseWnd::getParent()
+{
+ return parentWnd;
+}
+
+ifc_window *BaseWnd::getRootParent()
+{
+ return this;
+}
+
+//PORTME
+ifc_window *BaseWnd::getDesktopParent()
+{
+#ifdef _WIN32
+ // NONPORTABLE
+ HWND w = getOsWindowHandle();
+ HWND last = w;
+ if (!w) return NULL;
+ HWND p = w;
+ wchar_t cn[256] = {0};
+ while (p && !(GetWindowLong(p, GWL_STYLE) & WS_POPUP))
+ {
+ GetClassNameW(p, cn, 255); cn[255] = 0;
+ if (!wcscmp(cn, BASEWNDCLASSNAME))
+ last = p;
+ p = GetParent(p);
+ }
+ if (p)
+ {
+ GetClassNameW(p, cn, 255); cn[255] = 0;
+ if (!wcscmp(cn, BASEWNDCLASSNAME))
+ return (ifc_window*)GetWindowLongPtrW(p, GWLP_USERDATA);
+ else if (last != NULL)
+ return (ifc_window*)GetWindowLongPtrW(last, GWLP_USERDATA);
+ }
+#else
+#warning port me
+#endif
+ return NULL;
+}
+
+int BaseWnd::notifyParent(int msg, int param1, int param2)
+{
+ ifc_window *notifywnd = getNotifyWindow();
+ if (getParent() == NULL && notifywnd == NULL) return 0;
+ if (notifywnd == NULL) notifywnd = getParent();
+ ASSERT(notifywnd != NULL);
+ return notifywnd->childNotify(this, msg, param1, param2);
+}
+
+int BaseWnd::passNotifyUp(ifc_window *child, int msg, int param1, int param2)
+{
+ // Same code as above to decide for whom we should notify.
+ ifc_window *notifywnd = getNotifyWindow();
+ if (getParent() == NULL && notifywnd == NULL) return 0;
+ if (notifywnd == NULL) notifywnd = getParent();
+ ASSERT(notifywnd != NULL);
+ // And here we just change the api_window pointer.
+ return notifywnd->childNotify(child, msg, param1, param2);
+}
+
+void BaseWnd::setNotifyId(int id)
+{
+ notifyid = id;
+}
+
+int BaseWnd::getNotifyId()
+{
+ return notifyid;
+}
+
+DragInterface *BaseWnd::getDragInterface()
+{
+ return this;
+}
+
+ifc_window *BaseWnd::rootWndFromPoint(POINT *pt)
+{
+ // pt is in client coordinates
+ int x = (int)((double)pt->x / getRenderRatio());
+ int y = (int)((double)pt->y / getRenderRatio());
+
+ ifc_window *ret = findRootWndChild(x, y);
+ if (ret == NULL) ret = this;
+ return ret;
+}
+
+int BaseWnd::rootwnd_paintTree(ifc_canvas *canvas, api_region *r)
+{
+ BaseCloneCanvas c(canvas);
+ return paintTree(&c, r);
+}
+
+const wchar_t *BaseWnd::getRootWndName()
+{
+ return getName();
+}
+
+const wchar_t *BaseWnd::getId()
+{
+ return NULL;
+}
+
+void BaseWnd::setSkinId(int id)
+{
+ skin_id = id;
+}
+
+void BaseWnd::setPreferences(int what, int v)
+{
+ switch (what)
+ {
+ case MAXIMUM_W: maximum_w = v; break;
+ case MAXIMUM_H: maximum_h = v; break;
+ case MINIMUM_W: minimum_w = v; break;
+ case MINIMUM_H: minimum_h = v; break;
+ case SUGGESTED_W: suggested_w = v; break;
+ case SUGGESTED_H: suggested_h = v; break;
+ }
+}
+
+int BaseWnd::getPreferences(int what)
+{
+ if (getNumMinMaxEnforcers() > 0)
+ {
+
+ int min_x = minimum_w, min_y = minimum_h, max_x = maximum_w, max_y = maximum_h, sug_x = suggested_w, sug_y = suggested_h;
+
+ for (int i = 0;i < getNumMinMaxEnforcers();i++)
+ {
+
+ int tmin_x = MINIMUM_W, tmin_y = MINIMUM_H, tmax_x = MAXIMUM_W, tmax_y = MAXIMUM_H, tsug_x = SUGGESTED_W, tsug_y = SUGGESTED_H;
+
+ ifc_window *w = enumMinMaxEnforcer(i);
+
+ if (w)
+ {
+
+ tmin_x = w->getPreferences(MINIMUM_W);
+ tmin_y = w->getPreferences(MINIMUM_H);
+ tmax_x = w->getPreferences(MAXIMUM_W);
+ tmax_y = w->getPreferences(MAXIMUM_H);
+ tsug_x = w->getPreferences(SUGGESTED_W);
+ tsug_y = w->getPreferences(SUGGESTED_H);
+
+ if (tmin_x == -1) tmin_x = AUTOWH;
+ if (tmin_y == -1) tmin_y = AUTOWH;
+ if (tmax_x == -1) tmax_x = AUTOWH;
+ if (tmax_y == -1) tmax_y = AUTOWH;
+ if (tsug_x == -1) tsug_x = AUTOWH;
+ if (tsug_y == -1) tsug_y = AUTOWH;
+
+#ifndef DISABLE_SYSFONTSCALE
+ TextInfoCanvas textInfoCanvas(this);
+ double fontScale = textInfoCanvas.getSystemFontScale();
+ GuiObject *o = static_cast<GuiObject *>(getInterface(guiObjectGuid));
+ if (o != NULL)
+ {
+ if (o->guiobject_getAutoSysMetricsW())
+ {
+ if (tmin_x != AUTOWH) tmin_x = (int)((float)tmin_x * fontScale);
+ if (tmax_x != AUTOWH) tmax_x = (int)((float)tmax_x * fontScale);
+ if (tsug_x != AUTOWH) tsug_x = (int)((float)tsug_x * fontScale);
+ }
+ if (o->guiobject_getAutoSysMetricsH())
+ {
+ if (tmin_y != AUTOWH) tmin_y = (int)((float)tmin_y * fontScale);
+ if (tmax_y != AUTOWH) tmax_y = (int)((float)tmax_y * fontScale);
+ if (tsug_y != AUTOWH) tsug_y = (int)((float)tsug_y * fontScale);
+ }
+ }
+#endif
+
+ RECT cor;
+ w->getNonClientRect(&cor);
+ RECT wr;
+ getNonClientRect(&wr);
+
+ int xdif = (wr.right - wr.left) - (cor.right - cor.left);
+ int ydif = (wr.bottom - wr.top) - (cor.bottom - cor.top);
+ if (tmin_x != AUTOWH) tmin_x += xdif;
+ if (tmin_y != AUTOWH) tmin_y += ydif;
+ if (tmax_x != AUTOWH) tmax_x += xdif;
+ if (tmax_y != AUTOWH) tmax_y += ydif;
+ if (tsug_x != AUTOWH) tsug_x += xdif;
+ if (tsug_y != AUTOWH) tsug_y += ydif;
+ }
+
+ if (min_x != AUTOWH) min_x = (tmin_x != AUTOWH) ? MAX(min_x, tmin_x) : min_x; else min_x = tmin_x;
+ if (max_x != AUTOWH) max_x = (tmax_x != AUTOWH) ? MAX(max_x, tmax_x) : max_x; else max_x = tmax_x;
+ if (min_y != AUTOWH) min_y = (tmin_y != AUTOWH) ? MAX(min_y, tmin_y) : min_y; else min_y = tmin_y;
+ if (max_y != AUTOWH) max_y = (tmax_y != AUTOWH) ? MAX(max_y, tmax_y) : max_y; else max_y = tmax_y;
+ if (sug_x != AUTOWH) sug_x = (tsug_x != AUTOWH) ? MAX(sug_x, tsug_x) : sug_x; else sug_x = tsug_x;
+ if (sug_y != AUTOWH) sug_y = (tsug_y != AUTOWH) ? MAX(sug_y, tsug_y) : sug_y; else sug_y = tsug_y;
+ }
+
+ if (min_x != AUTOWH && min_x == max_x) sug_x = min_x;
+ if (min_y != AUTOWH && min_y == max_y) sug_y = min_y;
+
+ switch (what)
+ {
+ case MINIMUM_W: return min_x;
+ case MINIMUM_H: return min_y;
+ case MAXIMUM_W: return max_x;
+ case MAXIMUM_H: return max_y;
+ case SUGGESTED_W: return sug_x;
+ case SUGGESTED_H: return sug_y;
+ }
+ }
+
+ switch (what)
+ {
+ case SUGGESTED_W: return suggested_w;
+ case SUGGESTED_H: return suggested_h;
+ case MAXIMUM_W: return maximum_w;
+ case MAXIMUM_H: return maximum_h;
+ case MINIMUM_W: return minimum_w;
+ case MINIMUM_H: return minimum_h;
+ }
+
+ return AUTOWH;
+}
+
+void BaseWnd::setStartHidden(int wtf)
+{
+ start_hidden = wtf;
+}
+
+//PORTME
+#ifdef _WIN32
+
+
+
+#define EQUAL_CLSNAME(__name1, __name2)\
+(CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),\
+NORM_IGNORECASE, (__name1), -1, (__name2), -1))
+
+static BOOL BaseWnd_IsFrameWindow(HWND hwnd)
+{
+ WCHAR szClass[64] = {0};
+ if (NULL == hwnd || !GetClassNameW(hwnd, szClass, ARRAYSIZE(szClass)))
+ return FALSE;
+
+ return EQUAL_CLSNAME(szClass, L"Winamp v1.x") ||
+ EQUAL_CLSNAME(szClass, L"BaseWindow_RootWnd");
+}
+
+
+LRESULT BaseWnd::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (!isDestroying()) switch (uMsg)
+ {
+ case WM_DEFER_CALLBACK:
+ timerclient_onDeferredCallback(wParam, lParam);
+ break;
+ case WM_SYSCOMMAND:
+ {
+ if ((wParam & 0xfff0) == SC_SCREENSAVE || (wParam & 0xfff0) == SC_MONITORPOWER)
+ {
+ ifc_window *main = WASABI_API_WND->main_getRootWnd();
+ if (main && main != this)
+ return SendMessageW(main->gethWnd(), uMsg, wParam, lParam);
+ }
+ break;
+ }
+ //CUT case WM_CREATE:
+ //CUT hwnd = hWnd;
+ //CUT break;
+
+ //CUT case WM_CLOSE:
+ //CUT return 0;
+
+ case WM_PAINT:
+ {
+ if (inonresize && !wantRedrawOnResize()) return 1;
+ ASSERT(hwnd != NULL);
+ if (!isVisible(1) || IsIconic(hWnd)) break;
+ RECT r;
+ if (GetUpdateRect(hWnd, &r, FALSE))
+ {
+ if (virtualOnPaint())
+ {
+ return 0;
+ }
+ }
+ }
+ break;
+
+ case WM_PRINTCLIENT:
+ {
+ bool old_cloaked = (!!cloaked);
+ cloaked = true;
+ DCCanvas dc((HDC)wParam, this);
+ paint(&dc, 0);
+ cloaked = old_cloaked;
+
+ if (lParam & PRF_CHILDREN)
+ {
+ RECT wnd_size;
+ GetWindowRect(hwnd, &wnd_size);
+
+ HWND child = GetWindow(hwnd, GW_CHILD);
+ while (child != NULL)
+ {
+ if (GetWindowLongPtrW(child, GWL_STYLE) & WS_VISIBLE)
+ {
+ RECT child_size;
+ GetWindowRect(child, &child_size);
+ if (child_size.right && child_size.bottom)
+ {
+ BltCanvas bitmap(child_size.right, child_size.bottom, child);;
+ SendMessageW(child, WM_PRINT, (WPARAM)bitmap.getHDC(), PRF_CHILDREN | PRF_CLIENT | PRF_NONCLIENT/*| PRF_OWNED*/);
+ //bitmap->makeAlpha(255);
+
+ //set alpha to 255
+ int w, h;
+ bitmap.getDim(&w, &h, NULL);
+ ARGB32 *m_pBits = (ARGB32 *)bitmap.getBits();
+ int nwords = w*h;
+ for (; nwords > 0; nwords--, m_pBits++)
+ {
+ unsigned char *pixel = (unsigned char *)m_pBits;
+ pixel[3] = 255; // alpha
+ }
+
+ POINT offset;
+ offset.x = child_size.left - wnd_size.left;
+ offset.y = child_size.top - wnd_size.top;
+
+ //BLENDFUNCTION blendFn;
+ //blendFn.BlendOp = AC_SRC_OVER;
+ //blendFn.BlendFlags = 0;
+ //blendFn.SourceConstantAlpha = 255;
+ //blendFn.AlphaFormat = 0;
+ //AlphaBlend((HDC)wParam, offset.x, offset.y, child_size.right-child_size.left, child_size.bottom-child_size.top,
+ // bitmap->getHDC(), 0, 0, child_size.right-child_size.left, child_size.bottom-child_size.top, blendFn);
+ StretchBlt((HDC)wParam, offset.x, offset.y, child_size.right-child_size.left, child_size.bottom-child_size.top,
+ bitmap.getHDC(), 0, 0, child_size.right-child_size.left, child_size.bottom-child_size.top, SRCCOPY);
+ }
+ }
+ child = GetWindow(child, GW_HWNDNEXT);
+ }
+
+ }
+ }
+ return 0;
+ //CUT case WM_NCPAINT: return 0;
+ //CUT case WM_SYNCPAINT: return 0;
+
+ case WM_SETCURSOR:
+ if (checkModal()) return TRUE;
+ if (hWnd == (HWND)wParam)
+ {
+ DWORD windowStyle = (DWORD)GetWindowLongPtrW(hWnd, GWL_STYLE);
+ switch(HIWORD(lParam))
+ {
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case 0x020B/*WM_XBUTTONDOWN*/:
+ DisabledWindow_OnMouseClick(hWnd);
+ break;
+ }
+ int ct = BASEWND_CURSOR_POINTER;
+ int _x, _y;
+ Wasabi::Std::getMousePos(&_x, &_y);
+ screenToClient(&_x, &_y);
+ OSCURSORHANDLE c = NULL;
+
+ if (0 == (WS_DISABLED & windowStyle))
+ {
+ if (!handleVirtualChildMsg(WM_SETCURSOR, _x, _y, &ct, &c))
+ {
+ ct = getCursorType(_x, _y);
+ }
+ }
+ wchar_t *wincursor = NULL;
+ switch (ct)
+ {
+ case BASEWND_CURSOR_USERSET:
+
+ if (c == NULL)
+ c = getCustomCursor(_x, _y);
+ if (c != NULL)
+ {
+ SetCursor(c);
+ return TRUE;
+ }
+ else wincursor = IDC_ARROW; // Ensure to have at least a cursor
+ break;
+ case BASEWND_CURSOR_POINTER:
+ wincursor = IDC_ARROW;
+ break;
+ case BASEWND_CURSOR_NORTHSOUTH:
+ wincursor = IDC_SIZENS;
+ break;
+ case BASEWND_CURSOR_EASTWEST:
+ wincursor = IDC_SIZEWE;
+ break;
+ case BASEWND_CURSOR_NORTHWEST_SOUTHEAST:
+ wincursor = IDC_SIZENWSE;
+ break;
+ case BASEWND_CURSOR_NORTHEAST_SOUTHWEST:
+ wincursor = IDC_SIZENESW;
+ break;
+ case BASEWND_CURSOR_4WAY:
+ wincursor = IDC_SIZEALL;
+ break;
+ case BASEWND_CURSOR_EDIT:
+ wincursor = IDC_IBEAM;
+ break;
+ default:
+ wincursor = IDC_ARROW;
+ break;
+ }
+ if (wincursor != NULL)
+ {
+ SetCursor(LoadCursor(NULL, wincursor));
+ return TRUE;
+ }
+ }
+ return FALSE;
+
+ case WM_TIMER:
+ timerCallback((int)wParam);
+ return 0;
+
+ case WM_GETOBJECT:
+ if (lParam == OBJID_CLIENT)
+ {
+ Accessible *acc = getAccessibleObject();
+ if (acc != NULL)
+ {
+ LRESULT lAcc = acc->getOSHandle((int)wParam);
+ return lAcc;
+ }
+ }
+ break; // Fall through to DefWindowProc
+
+
+ case WM_SETFOCUS:
+ if (!focusEventsEnabled) break;
+ if (isInited())
+ {
+ if (rootfocus != NULL && rootfocus != this)
+ {
+ if (rootfocus != curVirtualChildFocus)
+ rootfocus->setFocus();
+ break;
+ }
+ else
+ {
+ if (wantFocus())
+ {
+ onGetFocus();
+ break;
+ }
+ else
+ {
+ ifc_window *w = getTab(TAB_GETFIRST);
+ if (w != NULL)
+ {
+ w->setFocus();
+ }
+ }
+ }
+ }
+ break;
+
+ case WM_KILLFOCUS:
+ {
+ ifc_window *rp = getRootParent();
+ if (!WASABI_API_WND->rootwndIsValid(rp) || !Wasabi::Std::Wnd::isValidWnd(rp->getOsWindowHandle())) break;
+ if (!focusEventsEnabled) break;
+#ifdef WASABI_COMPILE_WND
+ if (WASABI_API_WND) WASABI_API_WND->forwardOnKillFocus(); // resets the keyboard active keys buffer
+#endif
+ if (!WASABI_API_WND->rootwndIsValid(curVirtualChildFocus)) curVirtualChildFocus = NULL;
+ if (curVirtualChildFocus)
+ {
+ curVirtualChildFocus->onKillFocus();
+ curVirtualChildFocus = NULL;
+ }
+ else
+ if (hasfocus) onKillFocus();
+ break;
+ }
+
+ // dragging and dropping
+
+ case WM_LBUTTONDOWN:
+ {
+ if (lParam == 0xdeadc0de)
+ return 1;
+
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam))
+ return 0;
+
+ WASABI_API_WND->popupexit_check(this);
+
+ if (checkModal())
+ return 0;
+
+ abortTip();
+
+ int xPos = (signed short)LOWORD(lParam);
+ int yPos = (signed short)HIWORD(lParam);
+
+ xPos = (int)((float)xPos / getRenderRatio());
+ yPos = (int)((float)yPos / getRenderRatio());
+
+ if (!getCapture() && hasVirtualChildren() && handleVirtualChildMsg(WM_LBUTTONDOWN, xPos, yPos))
+ return 0;
+
+ if (isEnabled() && !dragging)
+ {
+ autoFocus(this);
+
+ int r = 0;
+
+ if (wantLeftClicks())
+ r = onLeftButtonDown(xPos, yPos);
+
+ if (checkDoubleClick(uMsg, xPos, yPos) && wantDoubleClicks() && onLeftButtonDblClk(xPos, yPos))
+ return 0;
+
+ return r;
+ }
+ }
+ break;
+
+ case WM_RBUTTONDOWN:
+ {
+ if (lParam == 0xdeadc0de) return 1;
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ WASABI_API_WND->popupexit_check(this);
+ if (checkModal()) return 0;
+ abortTip();
+ int xPos = (signed short)LOWORD(lParam);
+ int yPos = (signed short)HIWORD(lParam);
+ xPos = (int)((float)xPos / getRenderRatio());
+ yPos = (int)((float)yPos / getRenderRatio());
+ if (!getCapture() && hasVirtualChildren())
+ if (handleVirtualChildMsg(WM_RBUTTONDOWN, xPos, yPos))
+ return 0;
+ if (isEnabled() && !dragging)
+ {
+ autoFocus(this);
+ int r = 0;
+ if (wantRightClicks())
+ r = onRightButtonDown(xPos, yPos);
+ if (checkDoubleClick(uMsg, xPos, yPos) && wantDoubleClicks()) if (onRightButtonDblClk(xPos, yPos)) return 0;
+ return r;
+ }
+ }
+ break;
+ case WM_MOUSEHOVER:
+ if (checkModal()) return 0;
+ if (!getCapture() && hasVirtualChildren())
+ if (handleVirtualChildMsg(WM_MOUSEHOVER, 0, 0))
+ return 0;
+ break;
+ case WM_MOUSEMOVE:
+ {
+ /* static int mm=0;
+ DebugString("mousemove %d\n", mm++);*/
+ if (checkModal()) return 0;
+ int xPos = (signed short)LOWORD(lParam);
+ int yPos = (signed short)HIWORD(lParam);
+ xPos = (int)((float)xPos / getRenderRatio());
+ yPos = (int)((float)yPos / getRenderRatio());
+ if (dragging)
+ {
+ POINT pt = {xPos, yPos};
+ clientToScreen(&pt);
+ ifc_window *targ;
+ int candrop = 0;
+ // find the window the mouse is over
+
+ targ = NULL;
+ if (stickyWnd)
+ {
+ RECT wr;
+ GetWindowRect(stickyWnd->getOsWindowHandle(), &wr);
+ if (pt.x >= wr.left - sticky.left &&
+ pt.x <= wr.right + sticky.right &&
+ pt.y >= wr.top - sticky.top &&
+ pt.y <= wr.bottom + sticky.bottom) targ = stickyWnd;
+ else stickyWnd = NULL;
+ }
+
+ if (targ == NULL && WASABI_API_WND) targ = WASABI_API_WND->rootWndFromPoint(&pt); // FG> not to self, check
+
+ DI prevtargdi(prevtarg);
+ DI targdi(targ);
+
+ if (prevtarg != targ)
+ {
+ // window switch
+ if (prevtarg != NULL) prevtargdi.dragLeave(this);
+ if (targ != NULL) targdi.dragEnter(this);
+ }
+ if (targ != NULL)
+ candrop = targdi.dragOver(pt.x, pt.y, this);
+ if (targ == NULL || !candrop)
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)));
+ else
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
+ prevtarg = targ;
+ }
+ else if (isEnabled())
+ {
+ tipbeenchecked = FALSE;
+ if (!getCapture() && hasVirtualChildren())
+ {
+ if (handleVirtualChildMsg(WM_MOUSEMOVE, xPos, yPos))
+ return 0;
+ }
+ if (getCapture())
+ {
+ if (wantMouseMoves())
+ if (onMouseMove(xPos, yPos))
+ return 0;
+ }
+ if (!tipbeenchecked) onTipMouseMove();
+ return 0;
+ }
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ {
+ if (lParam == 0xdeadc0de) return 1;
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (checkModal()) return 0;
+ int xPos = (signed short)LOWORD(lParam);
+ int yPos = (signed short)HIWORD(lParam);
+ xPos = (int)((float)xPos / getRenderRatio());
+ yPos = (int)((float)yPos / getRenderRatio());
+ abortTip();
+ if (!dragging && !getCapture() && hasVirtualChildren())
+ {
+ if (handleVirtualChildMsg(WM_LBUTTONUP, xPos, yPos))
+ return 0;
+ }
+ if (dragging)
+ {
+ clientToScreen(&xPos, &yPos);
+ int res = 0;
+ if (prevtarg != NULL)
+ {
+ res = DI(prevtarg).dragDrop(this, xPos, yPos);
+ }
+
+ // inform source what happened
+ dragComplete(res);
+
+ resetDragSet();
+ prevtarg = NULL;
+ stickyWnd = NULL;
+ suggestedTitle = NULL;
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
+ Wasabi::Std::Wnd::releaseCapture();
+ dragging = 0;
+ }
+ else if (isEnabled())
+ {
+ if (wantLeftClicks())
+ if (onLeftButtonUp(xPos, yPos)) return 0;
+ }
+ }
+ break;
+
+ case WM_RBUTTONUP:
+ {
+ if (lParam == 0xdeadc0de) return 1;
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (checkModal()) return 0;
+ abortTip();
+ int xPos = (signed short)LOWORD(lParam);
+ int yPos = (signed short)HIWORD(lParam);
+ xPos = (int)((float)xPos / getRenderRatio());
+ yPos = (int)((float)yPos / getRenderRatio());
+ if (!getCapture() && hasVirtualChildren())
+ {
+ if (handleVirtualChildMsg(WM_RBUTTONUP, xPos, yPos))
+ return 0;
+ }
+ if (isEnabled() && !dragging)
+ {
+ if (wantRightClicks())
+ if (onRightButtonUp(xPos, yPos)) return 0;
+ }
+ }
+ break;
+
+ case WM_CONTEXTMENU:
+ {
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (checkModal()) return 0;
+ ASSERT(hWnd != NULL);
+ int xPos = (signed short)LOWORD(lParam);
+ int yPos = (signed short)HIWORD(lParam);
+ if (hWnd == getOsWindowHandle())
+ {
+ if (wantContextMenus())
+ if (onContextMenu(xPos, yPos)) return 0;
+ }
+ else if (GetParent(hWnd) == getOsWindowHandle())
+ {
+ if (wantContextMenus())
+ if (onChildContextMenu(xPos, yPos)) return 0;
+ }
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ return (onEraseBkgnd((HDC)wParam));
+
+ case WM_MOUSEWHEEL:
+ {
+ abortTip();
+
+ int l, a;
+ l = (short)HIWORD(wParam) / 120;
+ a = (short)HIWORD(wParam);
+ if (!l)
+ if (a > 0) l = 1;
+ else if (a < 0)l = 0;
+ a = l >= 0 ? l : -l;
+ if (GetAsyncKeyState(VK_MBUTTON)&0x8000)
+ {
+ if (l >= 0) l = 0; // Fast Forward 5s
+ else l = 1; // Rewind 5s
+ }
+ else
+ {
+ if (l >= 0) l = 2; // Volume up
+ else l = 3; // Volume down
+ }
+
+ int r = 0;
+
+ if (l & 1)
+ r = onMouseWheelDown(!(BOOL)(l & 2), a);
+ else
+ r = onMouseWheelUp(!(BOOL)(l & 2), a);
+ if (r == 0)
+ {
+ r = WASABI_API_WND->forwardOnMouseWheel(l, a);
+ }
+ // if it wasn't handled by this wnd, nor by the api, send it to the main wnd, unless we're it
+ if (r == 0)
+ {
+ if (WASABI_API_WND->main_getRootWnd() != this)
+ r = (int)SendMessageW(WASABI_API_WND->main_getRootWnd()->gethWnd(), uMsg, wParam, lParam);
+ }
+
+ return r;
+ }
+
+ case WM_WA_RELOAD:
+ {
+ if (wParam == 0)
+ freeResources();
+ else
+ reloadResources();
+ return 0;
+ }
+
+ case WM_WA_GETFBSIZE:
+ {
+ SIZE *s = (SIZE *)wParam;
+ s->cx = rwidth;
+ s->cy = rheight;
+ return 0;
+ }
+
+ case WM_USER + 8976: // wheel in tip, delete tip
+ abortTip();
+ return 0;
+
+ case WM_CHAR:
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (WASABI_API_WND->interceptOnChar((TCHAR) wParam)) return 0;
+ if (curVirtualChildFocus == NULL)
+ {
+ if (onChar(((TCHAR) wParam))) return 0;
+ }
+ else
+ {
+ if (curVirtualChildFocus->onChar(((TCHAR) wParam))) return 0;
+ }
+ if (WASABI_API_WND && WASABI_API_WND->forwardOnChar(this, (TCHAR) wParam, (int)lParam)) return 0;
+ break;
+
+ case WM_KEYDOWN:
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (WASABI_API_WND->interceptOnKeyDown((int) wParam)) return 0;
+ if (curVirtualChildFocus == NULL)
+ {
+ if (onKeyDown((int) wParam)) return 0;
+ }
+ else
+ {
+ if (curVirtualChildFocus->onKeyDown((int)wParam)) return 0;
+ }
+ if (WASABI_API_WND && WASABI_API_WND->forwardOnKeyDown(this, (int) wParam, (int)lParam)) return 0;
+ break;
+
+ case WM_KEYUP:
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (WASABI_API_WND->interceptOnKeyUp((int) wParam)) return 0;
+ if (curVirtualChildFocus == NULL)
+ {
+ if (onKeyUp((int) wParam)) return 0;
+ }
+ else
+ {
+ if (curVirtualChildFocus->onKeyUp((int)wParam)) return 0;
+ }
+ if (WASABI_API_WND && WASABI_API_WND->forwardOnKeyUp(this, (int) wParam, (int)lParam)) return 0;
+ break;
+
+ case WM_SYSKEYDOWN:
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (WASABI_API_WND->interceptOnSysKeyDown((int) wParam, (int)lParam)) return 0;
+ if (curVirtualChildFocus == NULL)
+ {
+ if (onSysKeyDown((int) wParam, (int)lParam)) return 0;
+ }
+ else
+ {
+ if (curVirtualChildFocus->onSysKeyDown((int)wParam, (int)lParam)) return 0;
+ }
+ if (WASABI_API_WND && WASABI_API_WND->forwardOnSysKeyDown(this, (int) wParam, (int)lParam)) return 0;
+ break;
+
+ case WM_SYSKEYUP:
+ if (bufferizeLockedUIMsg(uMsg, (int)wParam, (int)lParam)) return 0;
+ if (WASABI_API_WND->interceptOnSysKeyUp((int) wParam, (int)lParam)) return 0;
+ if (curVirtualChildFocus == NULL)
+ {
+ if (onSysKeyUp((int) wParam, (int)lParam)) return 0;
+ }
+ else
+ {
+ if (curVirtualChildFocus->onSysKeyUp((int)wParam, (int)lParam)) return 0;
+ }
+ if (WASABI_API_WND && WASABI_API_WND->forwardOnSysKeyUp(this, (int) wParam, (int)lParam)) return 0;
+ break;
+
+ case WM_MOUSEACTIVATE:
+ {
+ if (checkModal() || !wantActivation())
+ return MA_NOACTIVATE;
+ //SetFocus(getOsWindowHandle());
+ return MA_ACTIVATE;
+ }
+
+ case WM_ACTIVATEAPP:
+
+ if (wParam == FALSE)
+ {
+
+ if (WASABI_API_WND != NULL)
+ {
+ WASABI_API_WND->popupexit_signal();
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::GC, GarbageCollectCallback::GARBAGECOLLECT);
+ WASABI_API_WND->kbdReset();
+ if (ghosthwnd.getNumItems() > 0 && ghostbust)
+ {
+ ghostbust = 0; postDeferredCallback(DC_KILLGHOST);
+ }
+ return 0;
+ }
+ }
+
+ break;
+
+ case WM_ACTIVATE:
+ switch(LOWORD(wParam))
+ {
+ case WA_ACTIVE:
+ case WA_CLICKACTIVE:
+ if (WASABI_API_WND != NULL)
+ WASABI_API_WND->popupexit_check(this);
+
+ onActivate();
+
+ if (WA_CLICKACTIVE == LOWORD(wParam))
+ {
+ POINT pt;
+ DWORD pts = GetMessagePos();
+ POINTSTOPOINT(pt, pts);
+ MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1);
+ HWND hTarget = ChildWindowFromPointEx(hwnd, pt, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED | CWP_SKIPTRANSPARENT);
+ if (hTarget && hTarget != hwnd) lastActiveWnd = hTarget;
+ }
+
+ if (lastActiveWnd != hwnd && NULL != lastActiveWnd && IsWindow(lastActiveWnd))
+ {
+ SendMessageW(lastActiveWnd, uMsg, wParam, lParam);
+ return 0;
+ }
+ break;
+ default:
+
+ onDeactivate();
+
+ lastActiveWnd = GetFocus();
+
+ if (NULL != lastActiveWnd && !IsChild(hwnd, lastActiveWnd))
+ lastActiveWnd = NULL;
+
+ {
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
+#endif
+ if (NULL != lastActiveWnd && !BaseWnd_IsFrameWindow(lastActiveWnd))
+ {
+ while (lastActiveWnd)
+ {
+ if (BaseWnd_IsFrameWindow(GetWindow(lastActiveWnd, GW_OWNER)))
+ break;
+ lastActiveWnd = GetAncestor(lastActiveWnd, GA_PARENT);
+ }
+ }
+ }
+
+ if (lastActiveWnd != hwnd && NULL != lastActiveWnd)
+ {
+ SendMessageW(lastActiveWnd, uMsg, wParam, lParam);
+ return 0;
+ }
+
+ break;
+ }
+ break;
+
+ case WM_NCACTIVATE:
+ if (allowDeactivation())
+ return TRUE;
+ return FALSE;
+
+ case WM_WINDOWPOSCHANGING:
+ {
+ if (!isVirtual() && Wasabi::Std::Wnd::isPopup(hwnd))
+ {
+ WINDOWPOS *wp = (WINDOWPOS *)lParam;
+ if (wp->x != rx || wp->y != ry) wp->flags |= SWP_NOMOVE;
+ }
+ }
+ break;
+
+ case WM_WINDOWPOSCHANGED:
+ {
+
+ WINDOWPOS *lpwp = (WINDOWPOS *)lParam; // points to size and position data
+ if (lpwp->flags & SWP_HIDEWINDOW)
+ {
+ minimized = 1;
+ onMinimize();
+ }
+ else if (lpwp->flags & SWP_SHOWWINDOW)
+ {
+ minimized = 0;
+ onRestore();
+ }
+
+ if (!inonresize)
+ {
+ int w = rwidth;
+ int h = rheight;
+ multRatio(&w, &h);
+ if (lpwp->cx != w || lpwp->cy != h)
+ {
+ DebugStringW(L"external onResize\n");
+ w = lpwp->cx;
+ h = lpwp->cy;
+ divRatio(&w, &h);
+ setRSize(rx, ry, w, h);
+ if (isPostOnInit())
+ onResize();
+ }
+ }
+
+ onPostedMove();
+ return 0;
+ }
+
+ case WM_DROPFILES:
+ {
+ if (checkModal()) break;
+ WASABI_API_WND->pushModalWnd();
+ onExternalDropBegin();
+ HDROP h = (HDROP)wParam;
+ POINT dp = {0};
+ DragQueryPoint(h, &dp);
+ clientToScreen(&dp);
+ // build a file list
+ wchar_t buf[WA_MAX_PATH] = {0};
+ PtrList<FilenamePS> keep;
+
+ SetCursor(LoadCursor(NULL, IDC_WAIT));
+
+ //CUT #if UTF8
+ //CUT // doesn't really need UTF8, the "buf" is never written to.
+ //CUT // made to be NULL to enforce this concept.
+ int nfiles = DragQueryFile(h, 0xffffffff, NULL, 0);
+ //CUT #else
+ //CUT int nfiles = DragQueryFile(h, 0xffffffff, buf, sizeof(buf));
+ //CUT #endif
+
+ // convert them all to PlayItem *'s
+ for (int i = 0; i < nfiles; i++)
+ {
+ DragQueryFileW(h, i, buf, WA_MAX_PATH);
+ addDroppedFile(buf, &keep); // recursive
+
+ }
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ dragging = 1;
+ if (dragEnter(this))
+ {
+ if (dragOver(dp.x, dp.y, this)) dragDrop(this, dp.x, dp.y);
+ }
+ else
+ {
+ dragLeave(this);
+#ifdef FORWARD_DRAGNDROP
+ HWND w = WASABI_API_WND->main_getRootWnd()->gethWnd();
+ SendMessageW(w, WM_DROPFILES, wParam, lParam);
+#endif
+
+ }
+ dragging = 0;
+
+ // remove data
+ keep.deleteAll();
+ resetDragSet();
+
+ onExternalDropEnd();
+ WASABI_API_WND->popModalWnd();
+ }
+ return 0; // dropfiles
+
+ case WM_CAPTURECHANGED:
+ /* static int cc=0;
+ DebugString("capture changed! %d\n", cc++);*/
+ if (preventcancelcapture) return 0;
+ inputCaptured = 0;
+ if (curVirtualChildCaptured != NULL)
+ {
+ ifc_window *w = curVirtualChildCaptured;
+ curVirtualChildCaptured = NULL;
+ w->onCancelCapture();
+ }
+ else
+ {
+ onCancelCapture();
+ }
+ return 0;
+
+ } //switch
+
+ if (WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg &&
+ WM_NULL != WINAMP_WM_DIRECT_MOUSE_WHEEL)
+ {
+ wndProc(hWnd, WM_MOUSEWHEEL, wParam, lParam);
+ return TRUE;
+ }
+
+ if (uMsg >= WM_USER)
+ {
+ int ret;
+ if (onUserMessage(uMsg, (int)wParam, (int)lParam, &ret))
+ return ret;
+ return 0;
+ }
+
+ return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+}
+#endif
+int BaseWnd::onUserMessage(int msg, int w, int l, int *r)
+{
+ return 0;
+}
+
+int BaseWnd::checkDoubleClick(int b, int x, int y)
+{
+#ifdef _WIN32
+ uint32_t now = Wasabi::Std::getTickCount();
+
+ switch (b)
+ {
+ case WM_LBUTTONDOWN:
+ if (lastClick[0] > now - Wasabi::Std::getDoubleClickDelay())
+ {
+ lastClick[0] = 0;
+ if (ABS(lastClickP[0].x - x) > Wasabi::Std::getDoubleClickX() || ABS(lastClickP[0].y - y) > Wasabi::Std::getDoubleClickY()) return 0;
+ return 1;
+ }
+ lastClick[0] = now;
+ lastClickP[0].x = x;
+ lastClickP[0].y = y;
+ break;
+
+ case WM_RBUTTONDOWN:
+ if (lastClick[1] > now - Wasabi::Std::getDoubleClickDelay())
+ {
+ lastClick[1] = 0;
+ if (ABS(lastClickP[1].x - x) > Wasabi::Std::getDoubleClickX() || ABS(lastClickP[1].y - y) > Wasabi::Std::getDoubleClickY()) return 0;
+ return 1;
+ }
+ lastClick[1] = now;
+ lastClickP[1].x = x;
+ lastClickP[1].y = y;
+ break;
+ }
+#else
+#warning port me
+#endif
+ return 0;
+}
+
+int BaseWnd::onMouseWheelUp(int click, int lines)
+{
+ return 0;
+}
+
+int BaseWnd::onMouseWheelDown(int click, int lines)
+{
+ return 0;
+}
+
+int BaseWnd::onContextMenu(int x, int y)
+{
+ return 0;
+}
+
+int BaseWnd::onChildContextMenu(int x, int y)
+{
+ return 0;
+}
+
+int BaseWnd::onDeferredCallback(intptr_t param1, intptr_t param2)
+{
+ switch (param1)
+ {
+ case DEFERREDCB_FLUSHPAINT:
+ do_flushPaint();
+ break;
+ case DEFERREDCB_INVALIDATE:
+ if (isPostOnInit())
+ invalidate();
+ break;
+ case DC_KILLGHOST:
+ if (ghosthwnd.getNumItems() > 0)
+ {
+ preventcancelcapture = 1;
+ for (int i = 0;i < ghosthwnd.getNumItems();i++)
+ Wasabi::Std::Wnd::destroyWnd(ghosthwnd.enumItem(i));
+ ghosthwnd.freeAll();
+ preventcancelcapture = 0;
+ }
+ break;
+ case DEFERREDCB_FOCUSFIRST:
+ assignRootFocus(NULL);
+ if (Wasabi::Std::Wnd::getFocus() == getOsWindowHandle())
+ {
+ focusNext();
+ }
+ break;
+ case 0x7849 /*DEFERREDCB_ONHIDE*/:
+ {
+ foreach(rootwndchildren)
+ ifc_window *w = rootwndchildren.getfor();
+ if (w->isVisible(1)) // check internal flag only
+ w->onSetVisible(0);
+ endfor;
+ dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_SETVISIBLE, 0);
+ break;
+ }
+ }
+ return 0;
+}
+
+int BaseWnd::onPaint(Canvas *canvas)
+{
+#if 0
+ // example:
+ PaintCanvas c;
+ if (!c.beginPaint(this)) return 0;
+ (do some painting)
+ c will self -destruct on return
+#endif
+ if (renderbasetexture)
+ {
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ RECT r;
+ getNonClientRect(&r);
+ RenderBaseTexture(canvas, r);
+ }
+ return 0;
+}
+
+int BaseWnd::onPaint(Canvas *canvas, api_region *h)
+{
+ if (!canvas) return onPaint(canvas);
+
+#ifdef _WIN32
+ int sdc = SaveDC(canvas->getHDC());
+#elif defined(__APPLE__)
+ CGContextSaveGState(canvas->getHDC());
+#endif
+
+ canvas->selectClipRgn(h);
+
+ int rs = onPaint(canvas);
+
+#ifdef _WIN32
+ RestoreDC(canvas->getHDC(), sdc);
+#elif defined(__APPLE__)
+ CGContextRestoreGState(canvas->getHDC());
+#endif
+
+ return rs;
+}
+
+int BaseWnd::getTransparency()
+{
+ return wndalpha;
+}
+
+void BaseWnd::setTransparency(int amount)
+{
+ //if (wndalpha == amount) return;
+ if (amount == 254) amount = 255;
+ if (amount == 1) amount = 0;
+
+ if (amount != -1) wndalpha = amount; else amount = wndalpha;
+
+ if (!Wasabi::Std::Wnd::isDesktopAlphaAvailable())
+ {
+ wndalpha = 255;
+ return ;
+ }
+
+ if (w2k_alpha)
+ {
+ invalidate();
+ return ;
+ }
+
+#ifdef WIN32
+
+ if (!isInited() || isVirtual()) return ;
+ if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ;
+
+ if (amount < -1) amount = 0;
+ else if (amount > 255) amount = 255;
+
+ //CUT DWORD dwLong = GetWindowLong(hwnd, GWL_EXSTYLE);
+ if (amount == 255 && !forceTransparencyFlag())
+ {
+ Wasabi::Std::Wnd::setLayeredWnd(hwnd, FALSE);
+ //CUT if (dwLong & WS_EX_LAYERED)
+ //CUT SetWindowLong(hwnd, GWL_EXSTYLE, dwLong & ~WS_EX_LAYERED);
+ has_alpha_flag = 0;
+ }
+ else
+ {
+ if (!Wasabi::Std::Wnd::isLayeredWnd(hwnd))
+ Wasabi::Std::Wnd::setLayeredWnd(hwnd, TRUE);
+ //CUT if (!(dwLong & WS_EX_LAYERED))
+ //CUT SetWindowLong(hwnd, GWL_EXSTYLE, dwLong | WS_EX_LAYERED);
+ Wasabi::Std::Wnd::setLayeredAlpha(hwnd, amount);
+ //CUT setLayeredWindowAttributes(hwnd, RGB(0,0,0), amount, LWA_ALPHA);
+ has_alpha_flag = 1;
+ }
+#endif
+}
+
+int BaseWnd::forceTransparencyFlag()
+{
+ return 0;
+}
+
+int BaseWnd::beginCapture()
+{
+ if (!getCapture())
+ {
+ disable_tooltip_til_recapture = 0;
+ curVirtualChildCaptured = NULL;
+ /* oldCapture = */Wasabi::Std::Wnd::setCapture(getOsWindowHandle());
+ /* if (oldCapture) {
+ DebugString("Stolen capture detected, this may be ok, but try to avoid it if possible. Saving old capture\n");
+ }*/
+ inputCaptured = 1;
+ }
+ return 1;
+}
+
+int BaseWnd::endCapture()
+{
+ preventcancelcapture = 1;
+ if (Wasabi::Std::Wnd::getCapture() == getOsWindowHandle()) Wasabi::Std::Wnd::releaseCapture();
+ /* if (oldCapture) {
+ DebugString("Restoring old capture\n");
+ SetCapture(oldCapture);
+ oldCapture = NULL;
+ }*/
+ inputCaptured = 0;
+ preventcancelcapture = 0;
+ return 1;
+}
+
+int BaseWnd::getCapture()
+{
+ if (inputCaptured && Wasabi::Std::Wnd::getCapture() == getOsWindowHandle() && curVirtualChildCaptured == NULL) return 1;
+ return 0;
+}
+
+void BaseWnd::cancelCapture()
+{
+ if (curVirtualChildCaptured != NULL)
+ {
+ curVirtualChildCaptured->cancelCapture();
+ return ;
+ }
+ if (getCapture()) endCapture();
+ onCancelCapture();
+}
+
+int BaseWnd::onMouseMove(int x, int y)
+{
+ onTipMouseMove();
+ return 0;
+}
+
+void BaseWnd::onTipMouseMove()
+{
+ POINT p;
+
+ if (dragging) return ;
+ if (disable_tooltip_til_recapture) return ;
+
+ tipbeenchecked = TRUE;
+
+ Wasabi::Std::getMousePos(&p);
+
+ if (WASABI_API_WND->rootWndFromPoint(&p) != (ifc_window *)this)
+ {
+ // leaving area
+ tip_done = FALSE;
+ if (tipawaytimer)
+ killTimer(TIP_AWAY_ID);
+ tipawaytimer = FALSE;
+ if (tipshowtimer)
+ {
+ // TODO: on the mac, use CreateMouseTrackingRegion
+ TRACKMOUSEEVENT tracker;
+ tracker.cbSize=sizeof(tracker);
+ tracker.dwFlags = TME_HOVER|TME_CANCEL;
+ tracker.hwndTrack = this->getOsWindowHandle();
+ tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
+
+ TrackMouseEvent(&tracker);
+ }
+ tipshowtimer = FALSE;
+ destroyTip();
+ }
+ else
+ {
+ // moving in area
+ const wchar_t *t = getTip();
+ if (!disable_tooltip_til_recapture && !tipshowtimer && !tip_done && t != NULL && *t != 0)
+ {
+ //entering area & need tip
+
+ // TODO: on the mac, use CreateMouseTrackingRegion
+ TRACKMOUSEEVENT tracker;
+ tracker.cbSize=sizeof(tracker);
+ tracker.dwFlags = TME_HOVER;
+ tracker.hwndTrack = this->getOsWindowHandle();
+ tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
+
+ TrackMouseEvent(&tracker);
+
+ tipshowtimer = TRUE;
+ }
+ /*else if (tipshowtimer)
+ {
+ TRACKMOUSEEVENT tracker;
+ tracker.cbSize=sizeof(tracker);
+ tracker.dwFlags = TME_HOVER;
+ tracker.hwndTrack = this->getOsWindowHandle();
+ tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
+
+ TrackMouseEvent(&tracker);
+ }*/
+ }
+}
+
+int BaseWnd::onLeftButtonDblClk(int x, int y)
+{
+ return 0;
+}
+
+int BaseWnd::onRightButtonDblClk(int x, int y)
+{
+ return 0;
+}
+
+int BaseWnd::onGetFocus()
+{
+ // return TRUE if you override this
+ hasfocus = 1;
+ notifyParent(ChildNotify::GOTFOCUS);
+ getRootParent()->onSetRootFocus(this);
+ invalidate();
+ Accessible *a = getAccessibleObject();
+ if (a != NULL)
+ a->onGetFocus();
+ return 1;
+}
+
+int BaseWnd::onKillFocus()
+{
+ // return TRUE if you override this
+ hasfocus = 0;
+ notifyParent(ChildNotify::KILLFOCUS);
+ invalidate();
+ return 1;
+}
+
+#if defined(_WIN64)
+int BaseWnd::childNotify(ifc_window* child, int msg, int p1, int p2)
+{
+ return 0;
+}
+#else
+int BaseWnd::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)
+{
+ return 0;
+}
+#endif
+
+int BaseWnd::addDragItem(const wchar_t *droptype, void *item)
+{
+ ASSERT(droptype != NULL);
+ if (item == NULL) return -1;
+ DragSet *set;
+ int pos = dragCheckData(droptype);
+ if (pos == -1)
+ {
+ set = new DragSet();
+ set->setName(droptype);
+ dragsets.addItem(set);
+ pos = dragsets.getNumItems() - 1;
+ }
+ else set = dragsets[pos];
+ set->addItem(item);
+ return pos;
+}
+
+#ifdef _WIN32
+int BaseWnd::handleDrag()
+{
+ abortTip();
+ if (dragsets.getNumItems() == 0) return 0;
+
+ Wasabi::Std::Wnd::setCapture(hwnd);
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
+
+ dragging = 1;
+ stickyWnd = NULL;
+
+ return 1;
+}
+#endif
+
+int BaseWnd::resetDragSet()
+{
+ dragsets.deleteAll();
+ return 1;
+}
+
+int BaseWnd::dragEnter(ifc_window *sourceWnd)
+{
+ ifc_window *rw = getParent(); //api_window::rootwndFromRootWnd(getParent()); //FG> note to self, check!
+ if (rw) return DI(rw).dragEnter(sourceWnd);
+ return 0;
+}
+
+int BaseWnd::dragSetSticky(ifc_window *wnd, int left, int right, int up, int down)
+{
+ ASSERT(dragging);
+ stickyWnd = wnd;
+
+ if (left < 0) left = 0;
+ if (right < 0) right = 0;
+ if (up < 0) up = 0;
+ if (down < 0) down = 0;
+
+ Wasabi::Std::setRect(&sticky, left, up, right, down);
+
+ return 1;
+}
+
+void BaseWnd::setSuggestedDropTitle(const wchar_t *title)
+{
+ ASSERT(title != NULL);
+ suggestedTitle = title;
+}
+
+const wchar_t *BaseWnd::dragGetSuggestedDropTitle()
+{
+ return suggestedTitle; // can be NULL
+}
+
+int BaseWnd::dragCheckData(const wchar_t *type, int *nitems)
+{
+ for (int i = 0; i < dragsets.getNumItems(); i++)
+ {
+ if (!WCSICMP(type, dragsets[i]->getName()))
+ {
+ if (nitems != NULL) *nitems = dragsets[i]->getNumItems();
+ return i;
+ }
+ }
+ return -1;
+}
+
+void *BaseWnd::dragGetData(int slot, int itemnum)
+{
+ if (slot < 0 || slot >= dragsets.getNumItems()) return 0;
+ if (itemnum < 0 || itemnum >= dragsets[slot]->getNumItems()) return 0;
+ return dragsets[slot]->enumItem(itemnum);
+}
+
+void BaseWnd::addDroppedFile(const wchar_t *filename, PtrList<FilenamePS> *plist)
+{
+#ifdef RECURSE_SUBDIRS_ON_DROP
+ const char *slash = filename + STRLEN(filename) - 1;
+ for (; slash > filename; slash--) if (*slash == '/' || *slash == '\\') break;
+ if (STREQL(slash + 1, ".") || STREQL(slash + 1, "..")) return ;
+
+ char buf[WA_MAX_PATH] = {0};
+ STRCPY(buf, filename);
+ // try to resolve shortcuts
+ char *ext = buf + STRLEN(buf) - 1;
+ for (; ext > buf; ext--) if (*ext == '.' || *ext == '\\' || *ext == '/') break;
+#ifdef WIN32
+ if (!STRICMP(ext, ".lnk"))
+ {
+ char buf2[MAX_PATH] = {0};
+ if (StdFile::resolveShortcut(buf, buf2)) STRCPY(buf, buf2);
+ }
+#endif
+
+ int isdir = 0;
+
+ // handle root dir specially?
+ WIN32_FIND_DATA data = {0};
+ HANDLE r = FindFirstFile(buf, &data);
+ if (!r) return ;
+ FindClose(r);
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) isdir = 1;
+
+ if (isdir)
+ {
+ onExternalDropDirScan(buf);
+
+ // enumerate that dir
+ char search[WA_MAX_PATH] = {0};
+ wsprintf(search, "%s\\*.*", buf);
+ HANDLE files = FindFirstFile(search, &data);
+ if (files == INVALID_HANDLE_VALUE) return ; // nothin' in it
+ for (;;)
+ {
+ wchar_t obuf[WA_MAX_PATH] = {0};
+ swprintf(obuf, L"%s\\%s", buf, data.cFileName);
+ addDroppedFile(obuf, plist);
+ if (!FindNextFile(files, &data))
+ {
+ FindClose(files);
+ return ;
+ }
+ }
+
+ // should never get here
+ }
+ else
+ {
+ addDragItem(DD_FILENAME, plist->addItem(new FilenamePS(StringPrintfW(L"file:%s", buf))));
+ }
+#else
+ addDragItem(DD_FILENAME, plist->addItem(new FilenamePS(StringPrintfW(L"file:%s", filename))));
+#endif
+}
+
+bool BaseWnd::getNoCopyBits(void)
+{
+ return ncb;
+}
+
+void BaseWnd::setNoCopyBits(bool newncb)
+{
+ ncb = newncb;
+}
+
+int BaseWnd::onEraseBkgnd(HDC dc)
+{
+ return 1;
+}
+
+void BaseWnd::setIcon(OSICONHANDLE icon, int _small)
+{
+ Wasabi::Std::Wnd::setIcon(getOsWindowHandle(), icon, !_small);
+ //CUT SendMessageW(getOsWindowHandle(), WM_SETICON, _small ? ICON_SMALL : ICON_BIG, (int)icon);
+}
+
+const wchar_t *BaseWnd::getTip()
+{
+ return tip;
+}
+
+void BaseWnd::setTip(const wchar_t *_tooltip)
+{
+ tip = _tooltip;
+ abortTip();
+}
+
+int BaseWnd::getStartHidden()
+{
+ return start_hidden;
+}
+
+void BaseWnd::abortTip()
+{
+ if (tipshowtimer)
+ {
+ // TODO: on the mac, use CreateMouseTrackingRegion
+ TRACKMOUSEEVENT tracker;
+ tracker.cbSize=sizeof(tracker);
+ tracker.dwFlags = TME_HOVER|TME_CANCEL;
+ tracker.hwndTrack = this->getOsWindowHandle();
+ tracker.dwHoverTime = TIP_TIMER_THRESHOLD;
+
+ TrackMouseEvent(&tracker);
+ }
+ tipshowtimer = FALSE;
+ if (tipawaytimer)
+ killTimer(TIP_AWAY_ID);
+ tipawaytimer = FALSE;
+ if (tipdestroytimer)
+ killTimer(TIP_DESTROYTIMER_ID);
+ tipdestroytimer = FALSE;
+ destroyTip();
+ tip_done = FALSE;
+ RECT r;
+ if (getOsWindowHandle() && Wasabi::Std::Wnd::getUpdateRect(getOsWindowHandle(), &r) != 0) // FG> avoids xoring over disapearing tip
+ repaint();
+}
+
+int BaseWnd::isVisible(int within)
+{
+ if (!isVirtual() && !getOsWindowHandle()) return 0;
+ if (!this_visible) return 0;
+
+ if (within) return this_visible; // whatever, local
+
+ if (isVirtual()) // virtual, global
+ if (getParent())
+ return getParent()->isVisible();
+ else
+ return 0;
+
+ // non virtual, global
+ if (Wasabi::Std::Wnd::isPopup(getOsWindowHandle())) return this_visible;
+ if (!Wasabi::Std::Wnd::isValidWnd(Wasabi::Std::Wnd::getParent(getOsWindowHandle()))) return 0;
+ if (getParent()) return getParent()->isVisible(); // not a popup, check its parent or fail
+ return this_visible;
+}
+
+void BaseWnd::registerRootWndChild(ifc_window *child)
+{
+ rootwndchildren.addItem(child);
+ if (child->isVirtual())
+ virtualChildren.addItem(child);
+}
+
+void BaseWnd::unregisterRootWndChild(ifc_window *child)
+{
+ delTabOrderEntry(child);
+ rootwndchildren.removeItem(child);
+ if (curVirtualChildCaptured == child)
+ {
+ setVirtualChildCapture(NULL);
+ }
+ if (curVirtualChildFocus == child)
+ curVirtualChildFocus = NULL;
+ virtualChildren.removeItem(child);
+ //WASABI_API_WND->timer_remove(this, -1);
+ if (isPostOnInit() && isVisible())
+ postDeferredCallback(DEFERREDCB_INVALIDATE, 0);
+}
+
+int BaseWnd::isVirtual()
+{
+ return 0;
+}
+
+//CUT?inline int isInRect(RECT *r,int x,int y) {
+//CUT? if (x>=r->left&&x<=r->right&&y>=r->top&&y<=r->bottom) return 1;
+//CUT? return 0;
+//CUT?}
+
+int BaseWnd::ensureVirtualCanvasOk()
+{
+ RECT ncr;
+
+ if (isVirtual() && getParent()) return 1;
+
+ int size_w = rwidth;
+ int size_h = rheight;
+
+ if (!size_w || !size_h) return 0;
+
+ if (!virtualCanvas || virtualCanvasH != size_h || virtualCanvasW != size_w)
+ {
+ if (virtualCanvas)
+ {
+ deleteFrameBuffer(virtualCanvas);
+ virtualCanvas = NULL;
+ }
+ delete scalecanvas;
+ scalecanvas = NULL;
+ virtualCanvas = createFrameBuffer(size_w, size_h);
+ prepareFrameBuffer(virtualCanvas, size_w, size_h);
+ virtualCanvas->setBaseWnd(this);
+ virtualCanvasH = size_h; virtualCanvasW = size_w;
+ BaseWnd::getNonClientRect(&ncr);
+ deferedInvalidateRect(&ncr);
+ }
+ return 1;
+}
+
+Canvas *BaseWnd::createFrameBuffer(int w, int h)
+{
+ return new BltCanvas(w, h, getOsWindowHandle());
+}
+
+void BaseWnd::prepareFrameBuffer(Canvas *canvas, int w, int h)
+{
+ RECT r = {0, 0, w, h};
+ RegionI reg(&r);
+ virtualBeforePaint(&reg);
+#ifdef _WIN32
+ canvas->selectClipRgn(NULL);
+ canvas->fillRect(&r, 0);
+#elif defined(__APPLE__)
+ CGContextClearRect(canvas->getHDC(), CGRectInfinite); // TODO: make "clear" function in canvas
+#endif
+ virtualAfterPaint(&reg);
+}
+
+void BaseWnd::deleteFrameBuffer(Canvas *canvas)
+{
+ delete canvas;
+}
+
+// paints the client content, followed by the virtual child tree. recursive
+int BaseWnd::paintTree(Canvas *canvas, api_region *r)
+{
+ onPaint(canvas, r);
+
+#ifdef WASABI_DRAW_FOCUS_RECT
+ if (gotFocus())
+ {
+ RECT ncr;
+ getNonClientRect(&ncr);
+ // try to use skinned focus rect
+ if (WASABI_API_WND->paintset_present(Paintset::FOCUSRECT))
+ WASABI_API_WND->paintset_render(Paintset::FOCUSRECT, canvas, &ncr, 128);
+ else // otherwise this looks kinda nice :P
+ canvas->drawRect(&ncr, 0, 0xFFFFFF, 128);
+ }
+#endif
+
+ if (isVirtual() && !hasVirtualChildren()) return 0;
+
+ api_region *hostrgn = NULL;
+ api_region *update = r;
+
+ if (!(hwnd != NULL && getParent() == NULL))
+ {
+ hostrgn = getRegion();
+ update = r->clone();
+ if (hostrgn && !isRectRgn())
+ {
+ RECT ncr = clientRect();
+ api_region *hostclone = hostrgn->clone();
+ hostclone->addRegion(getComposedRegion());
+ hostclone->offset(ncr.left, ncr.top);
+ update->andRegion(hostclone);
+ hostrgn->disposeClone(hostclone);
+ }
+ }
+
+ RegionI client_update;
+ for (int i = 0;i < virtualChildren.getNumItems();i++)
+ {
+ if (!virtualChildren[i]->isVisible(1)) continue;
+ RECT rChild;
+ ifc_window *w = virtualChildren[i];
+ w->getNonClientRect(&rChild);
+ if ((rChild.right != rChild.left) && (rChild.bottom != rChild.top))
+ if (update->intersectRect(&rChild, &client_update))
+ {
+ w->paintTree(canvas, &client_update);
+ }
+ }
+
+ if (update != r) r->disposeClone(update);
+
+ return 1;
+}
+
+void BaseWnd::setVirtualCanvas(Canvas *c)
+{
+ virtualCanvas = c;
+}
+
+int BaseWnd::pointInWnd(POINT *p)
+{
+ RECT r;
+ if (!isVisible(1)) return 0;
+ getWindowRect(&r);
+ if (!Wasabi::Std::pointInRect(r, *p))
+ return 0;
+ for (int i = 0; i < getNumRootWndChildren(); i++)
+ {
+ ifc_window *c = enumRootWndChildren(i);
+ if (!c->isVisible(1)) continue;
+ RECT rChild;
+ c->getWindowRect(&rChild);
+ if (Wasabi::Std::pointInRect(rChild, *p))
+ return 0;
+ }
+ //NONPORTABLE
+ /* HWND child = GetWindow(getOsWindowHandle(), GW_CHILD);
+ while (child != NULL) {
+ if (IsWindowVisible(child)) {
+ RECT r2;
+ GetWindowRect(child, &r2);
+ if (Std::pointInRect(r2, *p))
+ return 0;
+ }
+ child = GetWindow(child, GW_HWNDNEXT);
+ }*/
+ return 1;
+}
+
+int BaseWnd::paint(Canvas *c, api_region *r)
+{
+ if (isVirtual())
+ {
+ RegionI d;
+ RECT cr;
+ getClientRect(&cr);
+ if (r == NULL)
+ {
+ d.addRect(&cr);
+ }
+ else
+ {
+ d.addRegion(r);
+ d.offset(cr.left, cr.top);
+ }
+ ifc_window *rp = getRootParent();
+ deferedInvalidate();
+ rp->paint(NULL, &d);
+ BltCanvas *cc = static_cast<BltCanvas*>(rp->getFrameBuffer());
+ if (r != NULL) c->selectClipRgn(r);
+ cc->blit(cr.left, cr.top, c, 0, 0, cr.right - cr.left, cr.bottom - cr.top);
+ return 1;
+ }
+
+ if (!ensureVirtualCanvasOk()) return 0;
+ RegionI *deleteme = NULL;
+ if (r == NULL)
+ {
+ RECT cr;
+ getNonClientRect(&cr);
+ deleteme = new RegionI(&cr);
+ r = deleteme;
+ }
+
+ virtualBeforePaint(r);
+
+ RECT rcPaint;
+ r->getBox(&rcPaint);
+
+ double ra = getRenderRatio();
+
+ if (deferedInvalidRgn)
+ {
+ api_region *nr = NULL;
+ if (renderRatioActive())
+ {
+ nr = r->clone();
+ double d = 1.0 / ra;
+ nr->scale(d, d, TRUE);
+ }
+
+ if (deferedInvalidRgn->isEmpty() == 0)
+ {
+ // some deferednvalidated regions needs to be repainted
+ // TODO: need a "clear region" function in canvas
+ api_region *i = deferedInvalidRgn->clone();
+#ifdef _WIN32
+ FillRgn(virtualCanvas->getHDC(), i->getOSHandle(), (HBRUSH)GetStockObject(BLACK_BRUSH));
+#elif defined(__APPLE__)
+ CGContextSaveGState(virtualCanvas->getHDC());
+ virtualCanvas->selectClipRgn(i);
+ CGContextClearRect(virtualCanvas->getHDC(), CGRectInfinite);
+// virtualCanvas->selectClipRgn(0);
+ CGContextRestoreGState(virtualCanvas->getHDC());
+#endif
+ paintTree(virtualCanvas, i);
+
+ deferedValidateRgn(i);
+ deferedInvalidRgn->disposeClone(i);
+
+ }
+ if (nr) r->disposeClone(nr);
+ }
+
+ virtualAfterPaint(r);
+
+ if (c != NULL)
+ {
+ commitFrameBuffer(c, &rcPaint, ra); //TH WDP2-212
+ }
+
+ delete deleteme;
+ return 1;
+}
+
+int BaseWnd::virtualOnPaint()
+{
+#ifdef _WIN32
+ RECT cr;
+ getNonClientRect(&cr);
+ if (cr.left >= cr.right || cr.top >= cr.bottom) return 0;
+
+ if (!ensureVirtualCanvasOk()) return 0;
+
+ RegionI reg;
+
+ //CUT GetUpdateRgn(getOsWindowHandle(), r->getOSHandle(), FALSE);
+ Wasabi::Std::Wnd::getUpdateRegion(getOsWindowHandle(), reg.getOSHandle());
+
+ PaintCanvas paintcanvas;
+ if (!paintcanvas.beginPaint(this))
+ {
+ virtualAfterPaint(&reg); return 0;
+ }
+
+ // DO NOT DELETE - This looks like it does nothing, but it actually makes the GDI call us again with WM_PAINT if some window
+ // moves over this one between BeginPaint and EndPaint. We still use GetUpdateRgn so we don't have to check for
+ // the version of Windows. See doc. If this function is not available (should be here in 95/98/NT/2K, but we never know)
+ // then we use the rcPaint rect... less precise, but still works.
+ //CUT if (getRandomRgn) {
+ if (Wasabi::Std::Wnd::haveGetRandomRegion())
+ {
+ RegionI zap;
+ //CUT getRandomRgn(paintcanvas.getHDC(), zap.getOSHandle(), SYSRGN);
+ Wasabi::Std::Wnd::getRandomRegion(paintcanvas.getHDC(), zap.getOSHandle());
+ }
+ else
+ {
+ RECT z;
+ paintcanvas.getRcPaint(&z);
+ reg.setRect(&z);
+ }
+
+ // -------------
+
+ /*// for debug
+ HDC dc = GetDC(getOsWindowHandle());
+ InvertRgn(dc, r->getHRGN());
+ InvertRgn(dc, r->getHRGN());
+ ReleaseDC(getOsWindowHandle(), dc);*/
+
+ paint(&paintcanvas, &reg);
+#else
+#warning port me or remove me
+#endif
+
+ return 1;
+}
+
+ifc_window *BaseWnd::enumVirtualChild(int _enum)
+{
+ return virtualChildren[_enum];
+}
+
+int BaseWnd::getNumVirtuals()
+{
+ return virtualChildren.getNumItems();
+}
+
+ifc_window *BaseWnd::enumRootWndChildren(int n)
+{
+ return rootwndchildren.enumItem(n);
+}
+
+int BaseWnd::getNumRootWndChildren()
+{
+ return rootwndchildren.getNumItems();
+}
+
+ifc_window *BaseWnd::findRootWndChild(int x, int y, int only_virtuals)
+{
+ for (int i = getNumRootWndChildren() - 1; i > -1; i--)
+ {
+ RECT r;
+ ifc_window *child = enumRootWndChildren(i);
+ //DebugStringW(L"findRootWndChild = entering = %s\n", child->getId());
+ if (only_virtuals && !child->isVirtual()) continue;
+ child->getNonClientRect(&r);
+ int _x = x;
+ int _y = y;
+ if (!child->isVirtual())
+ {
+ POINT pt;
+ child->getPosition(&pt);
+ _x -= pt.x;
+ _y -= pt.y;
+ }
+ int iv = child->isVisible(1);
+ //int gpa = child->getPaintingAlpha();
+ POINT _p = Wasabi::Std::makePoint(_x, _y);
+ if (iv /*&& gpa > 0*/ && Wasabi::Std::pointInRect(r, _p))
+ {
+ // GROUP
+ ifc_window *z = child->findRootWndChild(_x, _y);
+ if (z) return z;
+ }
+ /*gpa > 0 &&*/
+ /*if (iv && _x>=r.left&&_x<=r.right&&_y>=r.top&&_y<=r.bottom && !child->isClickThrough() && child->ptInRegion(_x, _y)) {
+ return child;
+ }*/
+ }
+ return (!isClickThrough() && ptInRegion(x, y)) ? this : NULL;
+}
+
+//PORTME
+int BaseWnd::handleVirtualChildMsg(UINT uMsg, int x, int y, void *p, void *d)
+{
+#ifdef _WIN32
+ ifc_window *child = NULL;
+
+ if (curVirtualChildCaptured)
+ child = curVirtualChildCaptured;
+ else
+ child = findRootWndChild(x, y, 1); // warning, can return this which is not virtual
+
+ // ASSERT(child != NULL); // BU this came up and I don't know why, looks like it should never happen
+ // FG> actually it can happen when coming back from a popup menu when cpu usage is high, the window might be
+ // hidden (destroying) and ptInRegion returns false.
+ if (!child) return 0;
+
+ //int isvirtual = child->isVirtual();
+
+ if (child) child = child->getForwardWnd();
+
+ if (child && child->isEnabled())
+ {
+ switch (uMsg)
+ {
+ case WM_LBUTTONDOWN:
+ /* if (isvirtual && child != curVirtualChildFocus)
+ focusVirtualChild(child);*/
+ autoFocus(child);
+ if (child->wantLeftClicks())
+ child->onLeftButtonDown(x, y);
+ if (child->checkDoubleClick(uMsg, x, y) && child->wantDoubleClicks())
+ child->onLeftButtonDblClk(x, y);
+ return 1;
+ case WM_RBUTTONDOWN:
+ /* if (isvirtual && child != curVirtualChildFocus)
+ focusVirtualChild(child);*/
+ autoFocus(child);
+ if (child->wantRightClicks())
+ child->onRightButtonDown(x, y);
+ if (child->checkDoubleClick(uMsg, x, y) && child->wantDoubleClicks())
+ child->onRightButtonDblClk(x, y);
+ return 1;
+ case WM_LBUTTONUP:
+ if (child->wantLeftClicks())
+ child->onLeftButtonUp(x, y);
+ return 1;
+ case WM_RBUTTONUP:
+ if (child->wantRightClicks())
+ child->onRightButtonUp(x, y);
+ return 1;
+ case WM_MOUSEMOVE:
+ {
+ if (curVirtualChildCaptured == child || (curVirtualChildCaptured == NULL))
+ {
+ if (child->wantMouseMoves())
+ child->onMouseMove(x, y);
+ return 1;
+ }
+ return 0;
+ }
+ case WM_MOUSEHOVER:
+ ((BaseWnd *)child)->onTip();
+ break;
+ case WM_SETCURSOR:
+ int a = child->getCursorType(x, y);
+ if (!p) return 0;
+ *(int *)p = a;
+ if (a == BASEWND_CURSOR_USERSET)
+ {
+ OSCURSORHANDLE c = child->getCustomCursor(x, y);
+ if (!d) return 0;
+ *(OSCURSORHANDLE *)d = c;
+ }
+ return 1;
+ }
+ }
+#else
+#warning port me or remove me
+#endif
+ return 0;
+}
+
+int BaseWnd::onLeftButtonDown(int x, int y)
+{
+ disable_tooltip_til_recapture = 1;
+ abortTip();
+ return 0;
+}
+
+int BaseWnd::onLeftButtonUp(int x, int y)
+{
+ disable_tooltip_til_recapture = 1;
+ abortTip();
+ return 0;
+}
+
+void BaseWnd::setVirtualChildCapture(ifc_window *child)
+{
+ if (child)
+ {
+ if (!inputCaptured)
+ {
+ beginCapture();
+ }
+ }
+ else
+ {
+ endCapture();
+ }
+ curVirtualChildCaptured = child;
+}
+
+ifc_window *BaseWnd::getVirtualChildCapture()
+{
+ if (inputCaptured && Wasabi::Std::Wnd::getCapture() == getOsWindowHandle())
+ return curVirtualChildCaptured;
+ else
+ if (inputCaptured) inputCaptured = 0;
+ return NULL;
+}
+
+ifc_window *BaseWnd::getBaseTextureWindow()
+{
+ // return our base texture window if we have it
+ if (btexture)
+ return btexture;
+ // return our parent's if they have it
+ if (getParent())
+ return getParent()->getBaseTextureWindow();
+ else
+ return NULL;
+}
+
+void BaseWnd::renderBaseTexture(ifc_canvas *c, const RECT &r, int alpha)
+{
+ WASABI_API_WND->skin_renderBaseTexture(getBaseTextureWindow(), c, r, this, alpha);
+}
+
+void BaseWnd::setBaseTextureWindow(ifc_window *w)
+{
+ btexture = w;
+}
+
+void BaseWnd::setNotifyWindow(ifc_window *newnotify)
+{
+ notifyWindow = newnotify;
+}
+
+ifc_window *BaseWnd::getNotifyWindow()
+{
+ return destroying ? NULL : notifyWindow;
+}
+
+int BaseWnd::gotFocus()
+{
+ return hasfocus && curVirtualChildFocus == NULL;
+}
+
+int BaseWnd::isActive()
+{
+ OSWINDOWHANDLE h = hwnd;
+ if (h == NULL)
+ {
+ ifc_window *par = getParent();
+ if (par == NULL) return 0;
+ h = par->getOsWindowHandle();
+ }
+ if (h == NULL) return 0;
+ return (Wasabi::Std::Wnd::getActiveWindow() == h);
+}
+
+int BaseWnd::onChar(unsigned int c)
+{
+ switch (c)
+ {
+ case 9: // TAB
+ if (Std::keyModifier(STDKEY_SHIFT))
+ focusPrevious();
+ else
+ focusNext();
+ return 1;
+ }
+ return 0;
+}
+
+/*int BaseWnd::focusVirtualChild(api_window *child) {
+ if (!gotFocus()) setFocus();
+ if (!child->wantFocus()) return 0;
+ setVirtualChildFocus(child);
+ return 1;
+}*/
+
+int BaseWnd::wantFocus()
+{
+ return 0;
+}
+
+// Return 1 if there is a modal window that is not this
+int BaseWnd::checkModal()
+{
+ if (bypassModal()) return 0;
+ ifc_window *w = WASABI_API_WND->getModalWnd();
+ if (w && w != static_cast<ifc_window*>(this) && w != getDesktopParent())
+ {
+ return 1;
+ }
+ return 0;
+}
+
+int BaseWnd::cascadeRepaintFrom(ifc_window *who, int pack)
+{
+ RECT r;
+ BaseWnd::getNonClientRect(&r);
+ return BaseWnd::cascadeRepaintRect(&r, pack);
+}
+
+int BaseWnd::cascadeRepaint(int pack)
+{
+ return cascadeRepaintFrom(this, pack);
+}
+
+int BaseWnd::cascadeRepaintRgn(api_region *r, int pack)
+{
+ return cascadeRepaintRgnFrom(r, this, pack);
+}
+
+int BaseWnd::cascadeRepaintRect(RECT *r, int pack)
+{
+ return cascadeRepaintRectFrom(r, this, pack);
+}
+
+int BaseWnd::cascadeRepaintRectFrom(RECT *r, ifc_window *who, int pack)
+{
+ RegionI reg(r);
+ int rt = cascadeRepaintRgnFrom(&reg, who, pack);
+ return rt;
+}
+
+void BaseWnd::_cascadeRepaintRgn(api_region *rg)
+{
+ if (!ensureVirtualCanvasOk()) return ;
+
+ WndCanvas paintcanvas;
+ if (paintcanvas.attachToClient(this) == 0)
+ return;
+
+ virtualBeforePaint(rg);
+
+ deferedInvalidateRgn(rg);
+ paintTree(virtualCanvas, rg);
+
+ virtualAfterPaint(rg);
+
+ double ra = getRenderRatio();
+
+ RECT rcPaint;
+ rg->getBox(&rcPaint);
+
+ RECT rc;
+ getClientRect(&rc); //JF> this gets it in virtual (non-scaled) coordinates,
+ // so we need to do these comparisons before scaling.
+ rcPaint.bottom = MIN((int)rc.bottom, (int)rcPaint.bottom);
+ rcPaint.right = MIN((int)rc.right, (int)rcPaint.right);
+
+ if (renderRatioActive()) // probably faster than scaling the clone
+ {
+ rcPaint.left = (int)((rcPaint.left - 1) * ra);
+ rcPaint.top = (int)((rcPaint.top - 1) * ra);
+ rcPaint.right = (int)(rcPaint.right * ra + 0.999999);
+ rcPaint.bottom = (int)(rcPaint.bottom * ra + 0.999999);
+ }
+ rcPaint.left = MAX(0, (int)rcPaint.left);
+ rcPaint.top = MAX(0, (int)rcPaint.top);
+ rcPaint.right = MIN((int)rcPaint.right, (int)(rwidth * ra));
+ rcPaint.bottom = MIN((int)rcPaint.bottom, (int)(rheight * ra));
+
+ commitFrameBuffer(&paintcanvas, &rcPaint, ra);
+}
+
+
+void BaseWnd::packCascadeRepaintRgn(api_region *rg)
+{
+ if (!deferedCascadeRepaintRgn) deferedCascadeRepaintRgn = new RegionI;
+ deferedCascadeRepaintRgn->addRegion(rg);
+ need_flush_cascaderepaint = 1;
+}
+
+int BaseWnd::cascadeRepaintRgnFrom(api_region *_rg, ifc_window *who, int pack)
+{
+
+ api_region *rg = _rg->clone();
+
+ int j = virtualChildren.searchItem(who);
+ for (int i = 0; i < virtualChildren.getNumItems(); i++)
+ {
+ ifc_window *w = virtualChildren[i];
+ if (w != who && w->wantSiblingInvalidations())
+ w->onSiblingInvalidateRgn(rg, who, j, i);
+ }
+
+ if (!pack)
+ {
+ _cascadeRepaintRgn(rg);
+ }
+ else
+ {
+ packCascadeRepaintRgn(rg);
+ }
+
+ _rg->disposeClone(rg);
+
+ return 1;
+}
+
+void BaseWnd::setDesktopAlpha(int a)
+{
+ if (a && !Wasabi::Std::Wnd::isDesktopAlphaAvailable()) return ;
+ if (a == w2k_alpha) return ;
+ w2k_alpha = a;
+ if (!a && scalecanvas)
+ {
+ delete scalecanvas;
+ scalecanvas = NULL;
+ }
+ setLayeredWindow(w2k_alpha);
+ onSetDesktopAlpha(a);
+}
+
+void BaseWnd::onSetDesktopAlpha(int a) { }
+
+void BaseWnd::commitFrameBuffer(Canvas *paintcanvas, RECT *r, double ra)
+{
+ if (w2k_alpha && Wasabi::Std::Wnd::isDesktopAlphaAvailable() && !cloaked)
+ {
+ //CUT BLENDFUNCTION blend= {AC_SRC_OVER, 0, wndalpha, AC_SRC_ALPHA };
+ //CUT POINT pt={0,0};
+ RECT spr;
+ getWindowRect(&spr);
+ //CUT POINT sp={spr.left,spr.top};
+ //CUT SIZE ss={spr.right-spr.left, spr.bottom-spr.top};
+ int sw = spr.right - spr.left, sh = spr.bottom - spr.top;
+ //CUT SysCanvas c;
+
+ if (handleRatio() && renderRatioActive())
+ {
+ // eek slow!
+ RECT r;
+ getWindowRect(&r);
+ int w = r.right - r.left;
+ int h = r.bottom - r.top;
+ if (!scalecanvas) scalecanvas = new BltCanvas(w, h, getOsWindowHandle());
+ virtualCanvas->stretchblit(0, 0, (int)((double)virtualCanvasW * 65536.0), (int)((double)virtualCanvasH * 65536.0), scalecanvas, 0, 0, w, h);
+ }
+
+ //CUT updateLayeredWindow(hwnd, c.getHDC(), &sp, &ss, (scalecanvas ? scalecanvas : virtualCanvas)->getHDC(), &pt, 0, &blend, ULW_ALPHA);
+ Wasabi::Std::Wnd::updateLayeredWnd(hwnd, spr.left, spr.top, sw, sh, (scalecanvas ? scalecanvas : virtualCanvas)->getHDC(), wndalpha);
+ }
+ else
+ {
+ if (ABS(ra - 1.0) <= 0.01)
+ {
+ virtualCanvas->blit(r->left, r->top, paintcanvas, r->left, r->top, r->right - r->left, r->bottom - r->top);
+ }
+ else
+ {
+ RECT tr = *r;
+
+ double invra = 65536.0 / ra;
+ int lp = tr.left;
+ int tp = tr.top;
+ int w = tr.right - tr.left;
+ int h = tr.bottom - tr.top;
+
+ int sx = (int)((double)lp * invra);
+ int sy = (int)((double)tp * invra);
+ int sw = (int)((double)w * invra);
+ int sh = (int)((double)h * invra);
+
+ virtualCanvas->stretchblit(sx, sy, sw, sh, paintcanvas, lp, tp, w, h);
+ }
+ }
+}
+
+void BaseWnd::flushPaint()
+{
+ postDeferredCallback(DEFERREDCB_FLUSHPAINT, 0);
+}
+
+void BaseWnd::do_flushPaint()
+{
+ if (!deferedInvalidRgn || deferedInvalidRgn->isEmpty()) return ;
+ api_region *r = deferedInvalidRgn->clone();
+ cascadeRepaintRgn(r);
+ deferedInvalidRgn->disposeClone(r);
+ deferedInvalidRgn->empty();
+}
+
+int BaseWnd::isMouseOver(int x, int y)
+{
+ POINT pt = {x, y};
+ clientToScreen(&pt);
+
+ return (WASABI_API_WND->rootWndFromPoint(&pt) == this);
+}
+
+void BaseWnd::freeResources()
+{}
+
+void BaseWnd::reloadResources()
+{
+ invalidate();
+}
+
+double BaseWnd::getRenderRatio()
+{
+ if (!handleRatio()) return 1.0;
+ if (!ratiolinked) return ratio;
+ return getParent() ? getParent()->getRenderRatio() : ratio;
+}
+
+void BaseWnd::setRenderRatio(double r)
+{
+ // "snap" to 1.0
+ if (ABS(r - 1.0) <= 0.02f) r = 1.0;
+ if (scalecanvas)
+ {
+ delete scalecanvas;
+ scalecanvas = NULL;
+ }
+ if (isInited() && r != ratio && !isVirtual() && (!getParent() || !ratiolinked))
+ {
+ // must scale size & region accordingly
+ RECT rc;
+ BaseWnd::getWindowRect(&rc);
+ rc.right = rc.left + rwidth;
+ rc.bottom = rc.top + rheight;
+ ratio = r;
+
+ resize(&rc);
+
+ invalidate();
+ if (isPostOnInit())
+ onRatioChanged();
+ }
+}
+
+void BaseWnd::setRatioLinked(int l)
+{
+ ratiolinked = l;
+ if (isPostOnInit())
+ setRenderRatio(ratio);
+}
+
+int BaseWnd::renderRatioActive()
+{
+ return ABS(getRenderRatio() - 1.0) > 0.01f;
+}
+
+void BaseWnd::multRatio(int *x, int *y)
+{
+ double rr = getRenderRatio();
+ if (x) *x = (int)((double)(*x) * rr);
+ if (y) *y = (int)((double)(*y) * rr);
+}
+
+void BaseWnd::multRatio(RECT *r)
+{
+ Wasabi::Std::scaleRect(r, getRenderRatio());
+}
+
+void BaseWnd::divRatio(int *x, int *y)
+{
+ double rr = getRenderRatio();
+ if (x) *x = (int)((double)(*x) / rr + 0.5);
+ if (y) *y = (int)((double)(*y) / rr + 0.5);
+}
+
+void BaseWnd::divRatio(RECT *r)
+{
+ double rr = getRenderRatio();
+ Wasabi::Std::scaleRect(r, 1./rr);
+}
+
+void BaseWnd::bringVirtualToFront(ifc_window *w)
+{
+ changeChildZorder(w, 0);
+}
+
+void BaseWnd::bringVirtualToBack(ifc_window *w)
+{
+ changeChildZorder(w, virtualChildren.getNumItems()-1);
+}
+
+void BaseWnd::bringVirtualAbove(ifc_window *w, ifc_window *b)
+{
+ ASSERT(b->isVirtual());
+ int p = virtualChildren.searchItem(b);
+ if (p == -1) return ;
+ changeChildZorder(w, p);
+}
+
+void BaseWnd::bringVirtualBelow(ifc_window *w, ifc_window *b)
+{
+ ASSERT(b->isVirtual());
+ int p = virtualChildren.searchItem(b);
+ if (p == -1) return ;
+ changeChildZorder(w, p + 1);
+}
+
+void BaseWnd::changeChildZorder(ifc_window *w, int newpos)
+{
+ int p = newpos;
+ p = MAX(p, (int)0);
+ p = MIN(p, virtualChildren.getNumItems()-1);
+ RECT cr;
+ w->getClientRect(&cr);
+
+ PtrList<ifc_window> l;
+ int i;
+ for (i = 0;i < virtualChildren.getNumItems();i++)
+ if (virtualChildren[i] != w)
+ l.addItem(virtualChildren[i]);
+
+ p = virtualChildren.getNumItems() - newpos - 1;
+ virtualChildren.removeAll();
+
+ int done = 0;
+
+ for (i = 0;i < l.getNumItems();i++)
+ if (i == p && !done)
+ {
+ virtualChildren.addItem(w);
+ i--;
+ done++;
+ }
+ else
+ {
+ RECT dr, intersection;
+ l.enumItem(i)->getClientRect(&dr);
+ if (Wasabi::Std::rectIntersect(intersection, dr, &cr))
+ l[i]->invalidateRect(&intersection);
+ virtualChildren.addItem(l.enumItem(i));
+ }
+ if (i == p && !done)
+ virtualChildren.addItem(w);
+ w->invalidate();
+}
+
+int BaseWnd::onActivate()
+{
+ if (hasVirtualChildren())
+ {
+ int l = getNumVirtuals();
+ for (int i = 0; i < l; i++)
+ {
+ ifc_window *r = enumVirtualChild(i);
+ r->onActivate();
+ }
+ }
+
+ return 0;
+}
+
+int BaseWnd::onDeactivate()
+{
+ if (hasVirtualChildren())
+ {
+ int l = getNumVirtuals();
+ for (int i = 0; i < l; i++)
+ {
+ ifc_window *r = enumVirtualChild(i);
+ r->onDeactivate();
+ }
+ }
+ return 0;
+}
+
+int BaseWnd::getDesktopAlpha()
+{
+ return w2k_alpha;
+}
+
+api_region *BaseWnd::getRegion()
+{
+ return NULL;
+}
+
+//CUT int BaseWnd::isTransparencyAvailable() {
+//CUT #ifdef WIN32
+//CUT #else
+//CUT #pragma warning port me!
+//CUT #endif
+//CUT return 0;
+//CUT }
+
+int BaseWnd::handleTransparency()
+{
+ return 1; // by default all windows handle transparency, only windows blitting directly on the SCREEN (if you blit directly on the DC it's still ok),
+} // for instance, a vis or a video using overlay should return 0, this will let the layout auto manage its alpha as that window is shown/hiden
+
+void BaseWnd::setAlpha(int active, int inactive)
+{
+ if (active == 254) active = 255;
+ if (active == 1) active = 0;
+ if (inactive == 254) inactive = 255;
+ if (inactive == 1) inactive = 0;
+ int oldactivealpha = activealpha;
+ active = MIN(255, MAX(0, active));
+ if (inactive != -1) inactive = MIN(255, MAX(0, inactive));
+
+ if (active != activealpha)
+ {
+ activealpha = active;
+ if (isActive())
+ {
+ invalidate();
+ if ((oldactivealpha == 0 || activealpha == 0) && (oldactivealpha != 0 || activealpha != 0))
+ invalidateWindowRegion();
+ }
+ }
+ if (inactive == -1) inactive = active;
+ if (inactive != inactivealpha)
+ {
+ inactivealpha = inactive;
+ if (!isActive())
+ {
+ invalidate();
+ if ((oldactivealpha == 0 || activealpha == 0) && (oldactivealpha != 0 || activealpha != 0))
+ invalidateWindowRegion();
+ }
+ }
+}
+
+void BaseWnd::getAlpha(int *active, int *inactive)
+{
+ if (active) *active = activealpha;
+ if (inactive) *inactive = inactivealpha;
+}
+
+int BaseWnd::getPaintingAlpha(void)
+{
+ int a = isActive() ? MIN(255, MAX(0, activealpha)) : MIN(255, MAX(0, inactivealpha));
+ ASSERT(a >= 0 && a <= 255);
+ if (getParent() && getParent()->isVirtual())
+ {
+ int b = getParent()->getPaintingAlpha();
+ a = (int)((double)a / 255.0 * (double)b);
+ }
+ if (a == 254) a = 255;
+ if (a == 1) a = 0;
+ if (!isEnabled()) a = (int)(a*0.6);
+ return a;
+}
+
+void BaseWnd::setClickThrough(int ct)
+{
+ clickthrough = ct;
+}
+
+int BaseWnd::isClickThrough()
+{
+ return clickthrough;
+}
+
+int BaseWnd::handleRatio()
+{
+ return 1;
+}
+
+#include <api/script/objects/c_script/c_rootobj.h>
+
+int BaseWnd::createTip()
+{
+ destroyTip();
+ tooltip = new Tooltip(getTip());
+ return -1;
+}
+
+void BaseWnd::destroyTip()
+{
+ // this is to avoid pb if destroytip() is being called by a time while destroying tip
+ Tooltip *tt = tooltip;
+ tooltip = NULL;
+ delete tt;
+}
+
+
+int BaseWnd::runModal()
+{
+ //PORTME
+#ifdef _WIN32
+ ifc_window *dp = getDesktopParent();
+ if (dp && dp != this)
+ return dp->runModal();
+
+ MSG msg;
+
+ // SetCapture(NULL);
+ SetFocus(getOsWindowHandle());
+
+ WASABI_API_WND->pushModalWnd(this);
+ returnvalue = 0;
+ mustquit = 0;
+
+ // Main message loop:
+ while (!mustquit)
+ {
+ mustquit = !GetMessage(&msg, NULL, 0, 0);
+ if (!msg.hwnd || !TranslateAccelerator(msg.hwnd, NULL, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ WASABI_API_WND->popModalWnd(this);
+ // SetCapture(NULL);
+ return returnvalue;
+#else
+#warning port me
+ return 0;
+#endif
+}
+
+void BaseWnd::endModal(int ret)
+{
+ ifc_window *dp = getDesktopParent();
+ if (dp && dp != this)
+ {
+ dp->endModal(ret);
+ return ;
+ }
+ returnvalue = ret;
+ mustquit = 1;
+}
+
+int BaseWnd::wantAutoContextMenu()
+{
+ return 1;
+}
+
+void BaseWnd::onCancelCapture()
+{}
+
+ifc_window *BaseWnd::getNextVirtualFocus(ifc_window *w)
+{
+ if (w == NULL)
+ {
+ if (childtabs.getNumItems() > 0)
+ return childtabs.getFirst()->wnd;
+ }
+
+ int a = getTabOrderEntry(w) + 1;
+
+ if (a < childtabs.getNumItems())
+ return childtabs.enumItem(a)->wnd;
+
+ return NULL;
+}
+
+
+void BaseWnd::setVirtualChildFocus(ifc_window *w)
+{
+ ASSERT(w && w->isVirtual());
+ if (curVirtualChildFocus)
+ curVirtualChildFocus->onKillFocus();
+ curVirtualChildFocus = w;
+ onSetRootFocus(w);
+ Wasabi::Std::Wnd::setFocus(getOsWindowHandle());
+ if (curVirtualChildFocus)
+ curVirtualChildFocus->onGetFocus();
+}
+
+int BaseWnd::ptInRegion(int x, int y)
+{
+ RECT cr;
+ getNonClientRect(&cr);
+ POINT pt = {x - cr.left, y - cr.top};
+ api_region *reg = getRegion();
+ if (isRectRgn())
+ return (x >= cr.left && x <= cr.right && y >= cr.top && y <= cr.bottom);
+ return reg ? reg->ptInRegion(&pt) : 0;
+}
+
+api_region *BaseWnd::getComposedRegion()
+{
+ ensureWindowRegionValid();
+ return composedrgn;
+}
+
+api_region *BaseWnd::getSubtractorRegion()
+{
+ ensureWindowRegionValid();
+ return subtractorrgn;
+}
+
+int BaseWnd::ensureWindowRegionValid()
+{
+ if (!isInited()) return 0;
+ if (wndregioninvalid)
+ {
+ computeComposedRegion();
+ return 1;
+ }
+ return 0;
+}
+
+void BaseWnd::invalidateWindowRegion()
+{
+ wndregioninvalid = 1;
+ if (getParent()) getParent()->invalidateWindowRegion();
+}
+
+void BaseWnd::computeComposedRegion()
+{
+ if (!isPostOnInit()) return ;
+
+ wndregioninvalid = 0;
+
+ RECT r;
+ getNonClientRect(&r);
+
+ api_region *reg = getRegion();
+ RegionI *_reg = NULL;
+
+ if (!reg)
+ {
+ _reg = new RegionI;
+ reg = _reg;
+ if (isRectRgn())
+ reg->setRect(&r);
+ }
+ else
+ if (isRectRgn())
+ reg->setRect(&r);
+
+ api_region *wr = reg->clone();
+
+ if (!subtractorrgn) subtractorrgn = new RegionI();
+ subtractorrgn->empty();
+ if (!composedrgn) composedrgn = new RegionI;
+ composedrgn->empty();
+
+ RegionI *subme = NULL;
+ RegionI *andme = NULL;
+ RegionI *orme = NULL;
+
+ // if subregion is now empty, we need to only use our region
+ RECT gr;
+ getNonClientRect(&gr);
+ for (int i = 0;i < virtualChildren.getNumItems();i++)
+ {
+ ifc_window *srw = virtualChildren.enumItem(i);
+ if (!srw->isVisible(1) || srw->getPaintingAlpha() == 0) continue;
+ if (srw->getRegionOp() != REGIONOP_NONE)
+ {
+ api_region *sr = srw->getComposedRegion();
+ if (sr)
+ {
+ api_region *osr = sr->clone();
+ RECT r;
+ srw->getNonClientRect(&r);
+ r.left -= gr.left;
+ r.top -= gr.top;
+ osr->offset(r.left, r.top);
+ /* sr->debug();
+ osr->debug();*/
+ if (srw->getRegionOp() == REGIONOP_OR)
+ {
+ if (!orme) orme = new RegionI;
+ orme->addRegion(osr);
+ }
+ else if (srw->getRegionOp() == REGIONOP_AND)
+ {
+ if (!andme) andme = new RegionI;
+ andme->addRegion(osr);
+ }
+ else if (srw->getRegionOp() == REGIONOP_SUB)
+ {
+ if (!subme) subme = new RegionI;
+ subme->addRegion(osr);
+ }
+ else if (srw->getRegionOp() == REGIONOP_SUB2)
+ {
+ if (!subme) subme = new RegionI;
+ subtractorrgn->addRegion(osr);
+ }
+ sr->disposeClone(osr);
+ }
+ }
+ api_region *sr = srw->getSubtractorRegion();
+ if (sr != NULL && !sr->isEmpty())
+ {
+ api_region *osr = sr->clone();
+ RECT r;
+ srw->getNonClientRect(&r);
+ r.left -= gr.left;
+ r.top -= gr.top;
+ osr->offset(r.left, r.top);
+ subtractorrgn->addRegion(osr);
+ sr->disposeClone(osr);
+ }
+ }
+
+ if (andme)
+ {
+ wr->andRegion(andme);
+ delete andme;
+ }
+ if (orme)
+ {
+ wr->addRegion(orme);
+ delete orme;
+ }
+ if (subme)
+ {
+ wr->subtractRgn(subme);
+ delete subme;
+ }
+
+ composedrgn->addRegion(wr);
+ reg->disposeClone(wr);
+ delete _reg;
+}
+
+void BaseWnd::updateWindowRegion()
+{
+ if (!isPostOnInit() || isVirtual()) return ;
+ if (getDesktopAlpha())
+ {
+ // if desktopalpha is on, we can't use regions (thanks MS), we have to rely on the framebuffer correctness
+ //CUT SetWindowRgn(getOsWindowHandle(), NULL, FALSE);
+ Wasabi::Std::Wnd::setWndRegion(getOsWindowHandle(), NULL);
+ return ;
+ }
+ api_region *_r = getComposedRegion();
+ api_region *_s = getSubtractorRegion();
+ ASSERT(_r != NULL && _s != NULL);
+
+ api_region *z = _r->clone();
+ z->subtractRgn(_s);
+
+ assignWindowRegion(z);
+ _r->disposeClone(z);
+}
+
+// wr is NOT scaled!!!
+void BaseWnd::assignWindowRegion(api_region *wr)
+{
+ ASSERT(wr != NULL);
+
+ if (!isPostOnInit()) return ;
+
+ int isrect = wr->isRect();
+
+ RECT r;
+ BaseWnd::getWindowRect(&r);
+
+ //DebugStringW( L"\nBaseWnd::assignWindowRegion() r before - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
+
+ r.right -= r.left;
+ r.left = 0;
+ r.bottom -= r.top;
+ r.top = 0;
+
+ //DebugStringW( L"BaseWnd::assignWindowRegion() r after - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
+
+ RECT z;
+ wr->getBox(&z);
+
+ //DebugStringW( L"BaseWnd::assignWindowRegion() z before - x = %d, y = %d, w = %d, h = %d \n", z.left, z.top, z.right - z.left, z.bottom - z.top );
+
+ z.left = 0;
+ z.top = 0;
+
+ //DebugStringW( L"BaseWnd::assignWindowRegion() z after - x = %d, y = %d, w = %d, h = %d \n", z.left, z.top, z.right - z.left, z.bottom - z.top );
+
+ if (renderRatioActive())
+ {
+ double i = getRenderRatio();
+ wr->scale(i, i, FALSE);
+ }
+
+ RECT sz;
+ wr->getBox(&sz);
+
+ //DebugStringW( L"BaseWnd::assignWindowRegion() sz before - x = %d, y = %d, w = %d, h = %d \n", sz.left, sz.top, sz.right - sz.left, sz.bottom - sz.top );
+
+ sz.right -= sz.left;
+ sz.bottom -= sz.top;
+ sz.left = 0;
+ sz.top = 0;
+
+ //DebugStringW( L"BaseWnd::assignWindowRegion() sz after - x = %d, y = %d, w = %d, h = %d \n", sz.left, sz.top, sz.right - sz.left, sz.bottom - sz.top );
+
+ if (isrect &&
+ ((z.right == rwidth && z.bottom == rheight) ||
+ (sz.left == r.left && sz.right == r.right && sz.top == r.top && sz.bottom == r.bottom) ||
+ (0)
+ )
+ )
+ {
+ //CUT SetWindowRgn(getOsWindowHandle(), NULL, TRUE);
+ if (!lastnullregion)
+ {
+ Wasabi::Std::Wnd::setWndRegion(getOsWindowHandle(), NULL, TRUE);
+ lastnullregion = 1;
+ }
+ }
+ else
+ {
+ //DebugStringW(L"setting region, rwidth = %d, rheight = %d, z.right = %d, z.bottom = %d\n", rwidth, rheight, z.right, z.bottom);
+ //CUT SetWindowRgn(getOsWindowHandle(), wr->makeWindowRegion(), TRUE);
+ Wasabi::Std::Wnd::setWndRegion(getOsWindowHandle(), wr->makeWindowRegion(), TRUE);
+ lastnullregion = 0;
+ }
+}
+
+void BaseWnd::performBatchProcesses()
+{
+ // recompute the window region if needed and apply it to the HWND
+ if (wndregioninvalid && !isVirtual())
+ if (ensureWindowRegionValid())
+ updateWindowRegion();
+ if (need_flush_cascaderepaint)
+ {
+ _cascadeRepaintRgn(deferedCascadeRepaintRgn);
+ deferedCascadeRepaintRgn->empty();
+ need_flush_cascaderepaint = 0;
+ }
+}
+
+int BaseWnd::getRegionOp()
+{
+ return regionop;
+}
+
+void BaseWnd::setRegionOp(int op)
+{
+ if (regionop != op)
+ {
+ regionop = op;
+ invalidateWindowRegion();
+ }
+}
+
+int BaseWnd::isRectRgn()
+{
+ return rectrgn;
+}
+
+void BaseWnd::setRectRgn(int i)
+{
+ rectrgn = i;
+}
+
+TimerClient *BaseWnd::timerclient_getMasterClient()
+{
+ if (!isVirtual()) return this;
+ ifc_window *w = getParent();
+ if (w)
+ {
+ TimerClient *tc = w->getTimerClient();
+ if (tc)
+ return tc->timerclient_getMasterClient();
+ }
+ return NULL;
+}
+
+void BaseWnd::timerclient_onMasterClientMultiplex()
+{
+ performBatchProcesses();
+}
+
+TimerClient *BaseWnd::getTimerClient()
+{
+ return this;
+}
+
+ifc_dependent *BaseWnd::rootwnd_getDependencyPtr()
+{
+ return this;
+}
+
+ifc_dependent *BaseWnd::timerclient_getDependencyPtr()
+{
+ return this;
+}
+
+void BaseWnd::addMinMaxEnforcer(ifc_window *w)
+{
+ minmaxEnforcers.addItem(w);
+ signalMinMaxEnforcerChanged();
+}
+
+void BaseWnd::removeMinMaxEnforcer(ifc_window *w)
+{
+ minmaxEnforcers.removeItem(w);
+ signalMinMaxEnforcerChanged();
+}
+
+void BaseWnd::signalMinMaxEnforcerChanged(void)
+{
+ ifc_window *w = getDesktopParent();
+ if (w == NULL || w == this) onMinMaxEnforcerChanged();
+ else w->signalMinMaxEnforcerChanged();
+}
+
+int BaseWnd::getNumMinMaxEnforcers()
+{
+ return minmaxEnforcers.getNumItems();
+}
+
+ifc_window *BaseWnd::enumMinMaxEnforcer(int n)
+{
+ return minmaxEnforcers.enumItem(n);
+}
+
+int BaseWnd::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+ return 1;
+}
+
+int BaseWnd::sendAction(ifc_window *target, const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen)
+{
+ ASSERT(target != NULL);
+ return target->onAction(action, param, x, y, p1, p2, data, datalen, this);
+}
+
+int BaseWnd::virtualBeforePaint(api_region *r)
+{
+ if (!virtualCanvas) return 0;
+ PaintCallbackInfoI pc(virtualCanvas, r);
+ dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_ONPAINT, PaintCallback::BEFOREPAINT, &pc);
+ return 1;
+}
+
+int BaseWnd::virtualAfterPaint(api_region *r)
+{
+ if (!virtualCanvas) return 0;
+ PaintCallbackInfoI pc(virtualCanvas, r);
+ dependent_sendEvent(BaseWnd::depend_getClassGuid(), Event_ONPAINT, PaintCallback::AFTERPAINT, &pc);
+ return 1;
+}
+
+int BaseWnd::timerclient_onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ TimerClientI::timerclient_onDeferredCallback(p1, p2);
+ return onDeferredCallback(p1, p2);
+}
+
+void BaseWnd::timerclient_timerCallback(int id)
+{
+ TimerClientI::timerclient_timerCallback(id);
+ timerCallback(id);
+}
+
+int BaseWnd::setTimer(int id, int ms)
+{
+ return timerclient_setTimer(id, ms);
+}
+
+int BaseWnd::killTimer(int id)
+{
+ return timerclient_killTimer(id);
+}
+
+void BaseWnd::postDeferredCallback(intptr_t p1, intptr_t p2, int mindelay)
+{
+#ifdef _WIN32
+ // TODO: re-enable, but post to some other window (e.g. some singleton window), not this window
+ // because our message pump might be blocked
+ // maybe make a hidden window in api_timer for this purpose
+
+ //if (mindelay)
+ timerclient_postDeferredCallback(p1, p2, mindelay);
+ //else
+ //PostMessage(hwnd, WM_DEFER_CALLBACK, p1, p2);
+#else
+#warning "port me - I can be optimized - don't use timers for this, use mac os x equiv of PostMessage!"
+ timerclient_postDeferredCallback(p1, p2, mindelay);
+#endif
+}
+
+int BaseWnd::bypassModal()
+{
+ return 0;
+}
+
+void BaseWnd::setRenderBaseTexture(int r)
+{
+ renderbasetexture = r;
+ if (isInited()) invalidate();
+}
+
+int BaseWnd::getRenderBaseTexture()
+{
+ return renderbasetexture;
+}
+
+GuiObject *BaseWnd::getGuiObject()
+{
+ if (my_guiobject == NULL)
+ {
+ my_guiobject = static_cast<GuiObject *>(getInterface(guiObjectGuid));
+ }
+ return my_guiobject;
+}
+
+//CUT someday
+int BaseWnd::getFlag(int flag)
+{
+ /* switch (flag) {
+ }*/
+ return 0;
+}
+
+int BaseWnd::triggerEvent(int event, intptr_t p1, intptr_t p2)
+{
+ //PORTME
+ switch (event)
+ {
+ case TRIGGER_ONRESIZE:
+ if (isPostOnInit())
+ onResize();
+ break;
+ case TRIGGER_INVALIDATE:
+ if (isPostOnInit())
+ invalidate();
+ break;
+ }
+ return 0;
+}
+
+void BaseWnd::registerAcceleratorSection(const wchar_t *name, int global)
+{
+#if defined(WASABI_COMPILE_LOCALES)
+ WASABI_API_LOCALE->locales_registerAcceleratorSection(name, this, global);
+#endif
+}
+
+int BaseWnd::onAcceleratorEvent(const wchar_t *name)
+{
+ for (int i = 0;i < getNumRootWndChildren();i++)
+ if (enumRootWndChildren(i)->onAcceleratorEvent(name))
+ return 1;
+ return 0;
+}
+
+int BaseWnd::allowDeactivation()
+{
+ return allow_deactivate & ((WASABI_API_WND == NULL) || WASABI_API_WND->appdeactivation_isallowed(this));
+}
+
+void BaseWnd::onMinimize()
+{
+ if (!isVirtual())
+ {
+ dropVirtualCanvas();
+ }
+}
+
+void BaseWnd::dropVirtualCanvas()
+{
+ deferedInvalidate();
+ delete virtualCanvas;
+ virtualCanvas = NULL;
+}
+
+void BaseWnd::onRestore()
+{
+ if (getDesktopParent() == this)
+ {
+ cascadeRepaint(TRUE);
+ }
+}
+
+ifc_window *BaseWnd::findWindow(const wchar_t *id)
+{
+ RootWndFinder find_object;
+ find_object.reset();
+ find_object.setFindId(id);
+ ifc_window *ret = findWindowChain(&find_object);
+
+#ifdef _DEBUG
+ if (ret == NULL)
+ DebugStringW(L"findWindow : window not found by id ! %s \n", id);
+#endif
+
+ return ret;
+}
+
+ifc_window *BaseWnd::findWindowByInterface(GUID interface_guid)
+{
+ RootWndFinder find_object;
+ find_object.reset();
+ find_object.setFindGuid(interface_guid);
+ ifc_window *ret = findWindowChain(&find_object);
+
+#ifdef _DEBUG
+ char str[256] = {0};
+ nsGUID::toChar(interface_guid, str);
+ if (ret == NULL)
+ DebugStringW(L"findWindow : object not found by guid ! %s \n", str);
+#endif
+
+ return ret;
+}
+
+ifc_window *BaseWnd::findWindowByCallback(FindObjectCallback *cb)
+{
+ ifc_window *ret = findWindowChain(cb);
+#ifdef _DEBUG
+ if (ret == NULL)
+ DebugStringW(L"findWindow : object not found by callback!\n");
+#endif
+
+ return ret;
+}
+
+ifc_window *BaseWnd::findWindowChain(FindObjectCallback *cb, ifc_window *wcaller)
+{
+
+ if (!cb) return NULL;
+
+ if (cb->findobjectcb_matchObject(this)) return this;
+
+ // first lets not look in subdirectories
+
+ for (int i = 0;i < getNumRootWndChildren();i++)
+ {
+ ifc_window *child = enumRootWndChildren(i);
+ if (!child || child == wcaller) continue;
+ if (cb->findobjectcb_matchObject(child))
+ return child;
+ }
+
+ // ok so it wasn't in our content, lets try to find it as a grandchildren
+
+ for (int i = 0;i < getNumRootWndChildren();i++)
+ {
+ ifc_window *child = enumRootWndChildren(i);
+ if (child->getNumRootWndChildren() > 0)
+ {
+ ifc_window *ret = child->findWindowChain(cb, this);
+ if (ret) return ret;
+ }
+ }
+
+ // so it wasnt one of our children, we'll hop the tree up one level and ask our parent to find it
+ // for us. of course, our parents are smart, they won't ask us back when asking our sibblings
+ ifc_window *p = getParent();
+ if (p != NULL && wcaller != p)
+ {
+ return p->findWindowChain(cb, this);
+ }
+
+ return NULL;
+}
+
+
+const wchar_t *BaseWnd::timerclient_getName()
+{
+ tcname = StringPrintfW(L"name=\"%S\", id=\"%s\"", getRootWndName(), getId());
+ return tcname;
+}
+
+void BaseWnd::setTabOrder(int a)
+{
+ if (getParent() != NULL)
+ getParent()->setVirtualTabOrder(this, a);
+}
+
+int BaseWnd::getTabOrder()
+{
+ if (getParent() != NULL)
+ return getParent()->getVirtualTabOrder(this);
+ return -1;
+}
+
+void BaseWnd::recursive_setVirtualTabOrder(ifc_window *w, float a, float lambda)
+{
+ ASSERT(w != NULL);
+ childtabs.setAutoSort(0);
+ int i = getTabOrderEntry(a);
+ if (i != -1)
+ {
+ TabOrderEntry *toe = childtabs.enumItem(i);
+ if (toe->wnd != w)
+ {
+ lambda += TABORDER_K;
+ if (lambda != 1.0)
+ recursive_setVirtualTabOrder(toe->wnd, a + lambda, lambda);
+ }
+ else
+ {
+ return ;
+ }
+ }
+ i = getTabOrderEntry(w);
+ if (i != -1)
+ {
+ delete childtabs.enumItem(i);
+ childtabs.removeByPos(i);
+ }
+ TabOrderEntry *toe = new TabOrderEntry;
+ toe->wnd = w;
+ toe->order = a;
+ childtabs.addItem(toe);
+}
+
+void BaseWnd::setVirtualTabOrder(ifc_window *w, int a)
+{
+ if (a == -1)
+ {
+ delTabOrderEntry(w);
+ return ;
+ }
+ recursive_setVirtualTabOrder(w, (float)a);
+}
+
+int BaseWnd::getVirtualTabOrder(ifc_window *w)
+{
+ int a = (int)getTabOrderEntry(w);
+ if (a == -1) return -1;
+ return (int)childtabs.enumItem(a);
+}
+
+int BaseWnd::getTabOrderEntry(ifc_window *w)
+{
+ foreach(childtabs)
+ if (childtabs.getfor()->wnd == w)
+ return foreach_index;
+ endfor;
+ return -1;
+}
+
+void BaseWnd::delTabOrderEntry(int i)
+{
+ int a = getTabOrderEntry((float)i);
+ if (a == -1) return ;
+ childtabs.removeByPos(a);
+}
+
+void BaseWnd::delTabOrderEntry(ifc_window *w)
+{
+ int a = getTabOrderEntry(w);
+ if (a == -1) return ;
+ delete childtabs.enumItem(a);
+ childtabs.removeByPos(a);
+}
+
+int BaseWnd::getTabOrderEntry(float order)
+{
+ foreach(childtabs)
+ if (childtabs.getfor()->order == order)
+ return foreach_index;
+ endfor;
+ return -1;
+}
+
+void BaseWnd::setAutoTabOrder()
+{
+ if (!getParent()) return ;
+ getParent()->setVirtualAutoTabOrder(this);
+}
+
+void BaseWnd::setVirtualAutoTabOrder(ifc_window *w)
+{
+ delTabOrderEntry(w);
+ float o = 0;
+ for (int i = 0;i < childtabs.getNumItems();i++)
+ {
+ o = MAX(o, childtabs.enumItem(i)->order);
+ }
+ setVirtualTabOrder(w, ((int)o) + 1);
+}
+
+void BaseWnd::focusNext()
+{
+ ifc_window *dp = getDesktopParent();
+ if (dp != this)
+ {
+ if (dp != NULL)
+ dp->focusNext();
+ return ;
+ }
+ ifc_window *w = getTab(TAB_GETNEXT);
+ if (w != NULL) w->setFocus();
+}
+
+void BaseWnd::focusPrevious()
+{
+ ifc_window *dp = getDesktopParent();
+ if (dp != this)
+ {
+ if (dp != NULL)
+ getDesktopParent()->focusPrevious();
+ return ;
+ }
+ ifc_window *w = getTab(TAB_GETPREVIOUS);
+ if (w != NULL) w->setFocus();
+}
+
+void BaseWnd::recursive_buildTabList(ifc_window *from, PtrList<ifc_window> *list)
+{
+ for (int i = 0;i < from->getNumTabs();i++)
+ {
+ ifc_window *r = from->enumTab(i);
+ if (r->isVisible() && r->getPaintingAlpha() > 0)
+ {
+ if (r->wantFocus())
+ list->addItem(r);
+ recursive_buildTabList(r, list);
+ }
+ }
+}
+
+ifc_window *BaseWnd::getTab(int what)
+{
+ PtrList<ifc_window> listnow;
+
+ recursive_buildTabList(this, &listnow);
+
+ int p = listnow.searchItem(rootfocus);
+
+ if (p == -1)
+ for (int i = 0; i < listnow.getNumItems(); i++)
+ {
+ ifc_window *r = listnow.enumItem(i);
+ if (r->gotFocus())
+ {
+ //DebugString("desync of rootfocus, fixing\n");
+ p = i;
+ assignRootFocus(r);
+ break;
+ }
+ }
+
+ if (what == TAB_GETNEXT && rootfocus != NULL)
+ {
+
+ p++;
+ if (p >= listnow.getNumItems())
+ p = 0;
+ return listnow.enumItem(p);
+
+ }
+ else if (what == TAB_GETPREVIOUS && rootfocus != NULL)
+ {
+
+ p--;
+ if (p < 0) p = listnow.getNumItems() - 1;
+ return listnow.enumItem(p);
+
+ }
+ else if (what == TAB_GETCURRENT)
+ {
+
+ return rootfocus;
+
+ }
+ else if (what == TAB_GETFIRST || (what == TAB_GETNEXT && rootfocus == NULL))
+ {
+
+ return listnow.getFirst();
+
+ }
+ else if (what == TAB_GETLAST || (what == TAB_GETPREVIOUS && rootfocus == NULL))
+ {
+
+ return listnow.getLast();
+
+ }
+
+ return NULL;
+}
+
+int BaseWnd::getNumTabs()
+{
+ return childtabs.getNumItems();
+}
+
+ifc_window *BaseWnd::enumTab(int i)
+{
+ childtabs.sort();
+ return childtabs.enumItem(i)->wnd;
+}
+
+void BaseWnd::onSetRootFocus(ifc_window *w)
+{
+ assignRootFocus(w);
+ ifc_window *dp = getDesktopParent();
+ if (dp && dp != this) dp->onSetRootFocus(w);
+}
+
+void BaseWnd::autoFocus(ifc_window *w)
+{
+ if (w->getFocusOnClick() && w->wantFocus())
+ {
+ w->setFocus();
+ return ;
+ }
+ ifc_window *g = w;
+ while (1)
+ {
+ ifc_window *p = g->getParent();
+ if (p == NULL) break;
+ ifc_window *dp = p->getDesktopParent();
+ if (dp && dp != p)
+ {
+ if (p->wantFocus() && p->getFocusOnClick())
+ {
+ p->setFocus();
+ return ;
+ }
+ g = p;
+ }
+ else
+ break;
+ }
+}
+
+void BaseWnd::setNoLeftClicks(int no)
+{
+ noleftclick = no;
+}
+
+void BaseWnd::setNoRightClicks(int no)
+{
+ norightclick = no;
+}
+
+void BaseWnd::setNoDoubleClicks(int no)
+{
+ nodoubleclick = no;
+}
+
+void BaseWnd::setNoMouseMoves(int no)
+{
+ nomousemove = no;
+}
+
+void BaseWnd::setNoContextMenus(int no)
+{
+ nocontextmnu = no;
+}
+
+void BaseWnd::setDefaultCursor(Cursor *c)
+{
+ customdefaultcursor = c;
+}
+
+
+OSCURSORHANDLE BaseWnd::getCustomCursor(int x, int y)
+{
+#ifdef _WIN32
+ return customdefaultcursor ? customdefaultcursor->getOSHandle() : NULL;
+#else
+#warning port me
+ return 0;
+#endif
+}
+
+Accessible *BaseWnd::createNewAccObj()
+{
+ waServiceFactory *f = WASABI_API_SVC->service_enumService(WaSvc::ACCESSIBILITY, 0);
+ if (f != NULL)
+ {
+ svc_accessibility *svc = castService<svc_accessibility>(f);
+ if (svc != NULL)
+ {
+ Accessible *a = svc->createAccessibleObject(this);
+ WASABI_API_SVC->service_release(svc);
+ return a;
+ }
+ }
+ return NULL;
+}
+
+Accessible *BaseWnd::getAccessibleObject(int createifnotexist)
+{
+ if (!createifnotexist) return accessible;
+ if (!accessible)
+ accessible = createNewAccObj();
+ else
+ accessible->addRef();
+ return accessible;
+}
+
+int BaseWnd::accessibility_getState()
+{
+ int state = 0;
+ if (!isVisible()) state |= STATE_SYSTEM_INVISIBLE;
+ //if (isVirtual() && !wantFocus()) state |= STATE_SYSTEM_INVISIBLE;
+ if (gotFocus()) state |= STATE_SYSTEM_FOCUSED;
+ return state;
+}
+
+void BaseWnd::activate()
+{
+ Wasabi::Std::Wnd::setActiveWindow(getRootParent()->getOsWindowHandle());
+}
+
+void BaseWnd::setOSWndName(const wchar_t *name)
+{
+ if (isVirtual()) return ;
+//#ifdef COMPILE_WASABI_SKIN // for some reason this isn't being correctly defined
+ if (name)
+ {
+ Wasabi::Std::Wnd::setWndName(getOsWindowHandle(), name);
+ }
+ else
+ Wasabi::Std::Wnd::setWndName(getOsWindowHandle(), L"");
+
+}
+
+const wchar_t *BaseWnd::getOSWndName()
+{
+ if (isVirtual()) return NULL;
+ wchar_t str[4096] = {0};
+ Wasabi::Std::Wnd::getWndName(getOsWindowHandle(), str, 4095);
+ str[4095] = '\0';
+ osname = str;
+ return osname;
+}
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+void BaseWnd::setAlwaysOnTop(int i)
+{
+ // this function should not optimize itself
+ if (getDesktopParent() == this)
+ {
+ if (i)
+ {
+ //CUT SetWindowPos(getOsWindowHandle(), HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER);
+ Wasabi::Std::Wnd::setTopmost(getOsWindowHandle(), TRUE);
+ }
+ else
+ {
+ saveTopMosts();
+ //CUT SetWindowPos(getOsWindowHandle(), HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER);
+ Wasabi::Std::Wnd::setTopmost(getOsWindowHandle(), FALSE);
+ restoreTopMosts();
+ }
+ alwaysontop = i;
+ return ;
+ }
+ ifc_window *p = getParent();
+ if (p != NULL)
+ p->setAlwaysOnTop(i);
+}
+
+int BaseWnd::getAlwaysOnTop()
+{
+ if (getDesktopParent() == this)
+ return alwaysontop;
+ ifc_window *p = getParent();
+ if (!p) return 0;
+ return p->getAlwaysOnTop();
+}
+#endif
+
+void BaseWnd::wndwatcher_onDeleteWindow(ifc_window *w)
+{
+ if (w == rootfocus)
+ {
+ rootfocus = NULL;
+ }
+}
+
+void BaseWnd::assignRootFocus(ifc_window *w)
+{
+ rootfocuswatcher.watchWindow(w);
+ rootfocus = w;
+}
+
+
+Canvas *BaseWnd::getFrameBuffer()
+{
+ return virtualCanvas;
+}
+
+void BaseWnd::setForeignWnd(int i)
+{
+ m_takenOver = i;
+}
+
+int BaseWnd::bufferizeLockedUIMsg(int uMsg, int wParam, int lParam)
+{
+ if (WASABI_API_SKIN && !WASABI_API_SKIN->skin_getLockUI()) return 0;
+ if (!uiwaslocked)
+ {
+ uiwaslocked = 1;
+ setTimer(BUFFEREDMSG_TIMER_ID, 20);
+ }
+ bufferedMsgStruct msg;
+ msg.msg = uMsg;
+ msg.wparam = wParam;
+ msg.lparam = lParam;
+ bufferedmsgs.addItem(msg);
+ return 1;
+}
+
+void BaseWnd::checkLockedUI()
+{
+ //PORTME :(
+#ifdef _WIN32
+
+ if (WASABI_API_SKIN && !WASABI_API_SKIN->skin_getLockUI())
+ {
+ uiwaslocked = 0;
+ killTimer(BUFFEREDMSG_TIMER_ID);
+ while (bufferedmsgs.getNumItems() > 0)
+ {
+ bufferedMsgStruct msg = bufferedmsgs.enumItem(0);
+ bufferedmsgs.delByPos(0);
+ SendMessageW(gethWnd(), msg.msg, msg.wparam, msg.lparam);
+ }
+ uiwaslocked = 0;
+ killTimer(BUFFEREDMSG_TIMER_ID);
+ }
+#else
+#warning port me
+#endif
+}
+
+int BaseWnd::isMinimized()
+{
+ ifc_window *w = getDesktopParent();
+ if (w == this || w == NULL) return minimized;
+ return w->isMinimized();
+}
+
+int BaseWnd::reinit()
+{
+#ifdef _WIN32
+ int nochild = (GetWindowLong(gethWnd(), GWL_STYLE) & WS_POPUP) ? 1 : 0;
+ int r = reinit(parentWnd ? parentWnd : WASABI_API_WND->main_getRootWnd(), nochild);
+
+ if (w2k_alpha)
+ setLayeredWindow(1);
+
+ return r;
+#else
+#warning port me!
+#endif
+}
+
+
+int BaseWnd::reinit(ifc_window *parWnd, int nochild)
+{
+ OSWINDOWHANDLE phwnd = parWnd->getOsWindowHandle();
+ ASSERT(phwnd != NULL);
+ int ret;
+ if (!nochild) parentWnd = parWnd;
+ else parentWnd = NULL;
+ ret = reinit(parWnd->getOsModuleHandle(), phwnd, nochild);
+ if (!ret) parentWnd = NULL; // abort
+ return ret;
+}
+
+int BaseWnd::reinit(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild)
+{
+ RECT r;
+ int w, h;
+
+ onBeforeReinit();
+
+ pushWindowRect();
+ preventcancelcapture = 1;
+
+ int _isvisible = isVisible(1);
+ int hadcapture = inputCaptured;
+ //DebugString("had capture = %d\n", hadcapture);
+ Wasabi::Std::Wnd::releaseCapture();
+
+ unparentHWNDChildren();
+
+ BaseWnd::getClientRect(&r);
+
+ hinstance = moduleHandle;
+
+ ASSERT(hinstance != NULL);
+
+ w = (r.right - r.left);
+ h = (r.bottom - r.top);
+
+ rwidth = w;
+ rheight = h;
+ rx = r.left;
+ ry = r.top;
+
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+
+ // destroy old window
+ Wasabi::Std::Wnd::hideWnd(hwnd); //Wasabi::Std::Wnd::destroyWnd(hwnd);
+ ghosthwnd.addItem(hwnd);
+
+ hwnd = Wasabi::Std::Wnd::createWnd(&r, nochild, acceptExternalDrops(), parent, hinstance, static_cast<ifc_window*>(this));
+#ifdef __APPLE__
+#warning remove me
+ Wasabi::Std::Wnd::showWnd(hwnd);
+#endif
+
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+
+ //ASSERT(hwnd != NULL); // lets fail nicely, this could happen for some win32 reason, we don't want to fail the whole app for it, so lets just fail the wnd
+ if (hwnd == NULL)
+ {
+ preventcancelcapture = 0;
+ return 0;
+ }
+
+ //CUT nreal++;
+
+#ifdef _WIN32
+ //FUCKO
+#ifdef URLDROPS
+ if (acceptExternalDrops()) RegisterDragDrop(hwnd, &m_target);
+#elif !defined(WA3COMPATIBILITY)
+ if (!m_target && WASABI_API_WND != NULL)
+ m_target = WASABI_API_WND->getDefaultDropTarget();
+ if (m_target != NULL)
+ {
+ RegisterDragDrop(hwnd, (IDropTarget *)m_target);
+ }
+#endif
+#else
+#warning port me - register drag & drop
+#endif
+
+ this_visible = _isvisible;
+
+ //onInit();
+ //this_visible = !start_hidden;
+
+ reparentHWNDChildren();
+
+ popWindowRect();
+
+ invalidateWindowRegion();
+ updateWindowRegion();
+
+ if (this_visible)
+ Wasabi::Std::Wnd::showWnd(hwnd, FALSE);
+
+ if (hadcapture)
+ {
+ Wasabi::Std::Wnd::setCapture(hwnd);
+ }
+ preventcancelcapture = 0;
+
+ forcedOnResize();
+ redrawHWNDChildren();
+ //onPostOnInit();
+
+ onAfterReinit();
+
+#ifdef WASABI_ON_REPARENT
+ WASABI_ON_REINIT(getOsWindowHandle());
+#endif
+
+ return 1;
+}
+
+ReparentWndEntry::ReparentWndEntry(OSWINDOWHANDLE _wnd, OSWINDOWHANDLE parentwnd)
+{
+ wnd = _wnd;
+ Wasabi::Std::Wnd::getWindowRect(wnd, &rect);
+ Wasabi::Std::Wnd::screenToClient(wnd, (int *)&(rect.left), (int *)&(rect.top));
+ Wasabi::Std::Wnd::clientToScreen(parentwnd, (int *)&(rect.left), (int *)&(rect.top));
+}
+
+void ReparentWndEntry::unparent()
+{
+ Wasabi::Std::Wnd::setWndPos(wnd, NULL, rect.left, -30000, 0, 0, TRUE, TRUE, FALSE, FALSE, TRUE);
+ Wasabi::Std::Wnd::setParent(wnd, NULL);
+}
+
+void ReparentWndEntry::reparent(OSWINDOWHANDLE newparent)
+{
+ Wasabi::Std::Wnd::setParent(wnd, newparent);
+ Wasabi::Std::Wnd::setWndPos(wnd, NULL, rect.left, rect.top, 0, 0, TRUE, TRUE, FALSE, FALSE, TRUE);
+}
+
+#ifdef _WIN32
+void BaseWnd::unparentHWNDChildren()
+{
+ // just in case
+ reparentwnds.deleteAll();
+
+#ifndef WIN32
+#error port me ! // make a list of all the children oswindows and reparent them to the desktop somewhere we can't see
+#endif
+
+ OSWINDOWHANDLE wnd = GetWindow(getOsWindowHandle(), GW_CHILD);
+ while (wnd)
+ {
+ reparentwnds.addItem(new ReparentWndEntry(wnd, getOsWindowHandle()));
+ wnd = GetWindow(wnd, GW_HWNDNEXT);
+ }
+ foreach(reparentwnds)
+ reparentwnds.getfor()->unparent();
+ endfor;
+}
+#endif
+
+void BaseWnd::reparentHWNDChildren()
+{
+ // reparent to the new oswindowhandle
+ foreach(reparentwnds)
+ reparentwnds.getfor()->reparent(getOsWindowHandle());
+ endfor;
+}
+
+void BaseWnd::redrawHWNDChildren()
+{
+ // reparent to the new oswindowhandle
+ foreach(reparentwnds)
+ Wasabi::Std::Wnd::update(getOsWindowHandle());
+ endfor;
+}
+
+void BaseWnd::maximize(int axis)
+{
+ //DebugString("maximize!\n");
+ // if already maximized, don't use current rect, use restore_rect
+ if (!maximized)
+ {
+ restore_rect.left = rx;
+ restore_rect.top = ry;
+ restore_rect.right = rx + rwidth;
+ restore_rect.bottom = ry + rheight;
+ }
+
+ RECT nr = restore_rect;
+ RECT dr;
+
+ Wasabi::Std::getViewport(&dr, NULL, NULL, getOsWindowHandle(), 0);
+
+ if (axis & MAXIMIZE_WIDTH)
+ {
+ nr.left = dr.left;
+ nr.right = dr.right;
+ }
+ if (axis & MAXIMIZE_HEIGHT)
+ {
+ nr.top = dr.top;
+ nr.bottom = dr.bottom;
+ }
+ maximized = 1;
+ if (axis != 0) resize(&nr);
+ onMaximize();
+}
+
+void BaseWnd::restore(int what)
+{
+ if (maximized)
+ {
+ //DebugString("restore!\n");
+ if (what == (RESTORE_X | RESTORE_Y | RESTORE_WIDTH | RESTORE_HEIGHT))
+ resize(&restore_rect);
+ else
+ {
+ resize((what & RESTORE_X) ? restore_rect.left : NOCHANGE,
+ (what & RESTORE_Y) ? restore_rect.top : NOCHANGE,
+ (what & RESTORE_WIDTH) ? restore_rect.right - restore_rect.left : NOCHANGE,
+ (what & RESTORE_HEIGHT) ? restore_rect.bottom - restore_rect.top : NOCHANGE);
+ }
+ maximized = 0;
+ onRestore();
+ }
+}
+
+void BaseWnd::pushWindowRect()
+{
+ //DebugString("pushWindowRect\n");
+ RECT wr;
+ getWindowRect(&wr);
+ wr.right = wr.left + rwidth;
+ wr.bottom = wr.top + rheight;
+ windowrectstack.push(wr);
+}
+
+int BaseWnd::popWindowRect(RECT *rc, int applyhow)
+{
+ //DebugString("popWindowRect\n");
+ if (windowrectstack.peek() == 0) return 0;
+ RECT _rc;
+ windowrectstack.pop(&_rc);
+ RECT r;
+ getWindowRect(&r);
+ divRatio(&r);
+ if (applyhow)
+ {
+ if (applyhow == PWR_POSITION)
+ {
+ move(_rc.left, _rc.top);
+ if (rc)
+ {
+ int w = r.right - r.left;
+ int h = r.bottom - r.top;
+ rc->left = _rc.left;
+ rc->top = _rc.top;
+ rc->right = rc->left + w;
+ rc->bottom = rc->top + h;
+ }
+ }
+ else
+ {
+ if (applyhow & PWR_X) r.left = _rc.left;
+ if (applyhow & PWR_Y) r.top = _rc.top;
+ if (applyhow & PWR_WIDTH) r.right = r.left + (_rc.right - _rc.left);
+ if (applyhow & PWR_HEIGHT) r.bottom = r.top + (_rc.bottom - _rc.top);
+ resizeToRect(&r);
+ if (rc) *rc = _rc;
+ }
+ }
+ else if (rc) *rc = _rc;
+ return 1;
+}
+
+void BaseWnd::setRestoredRect(RECT *r)
+{
+ if (!r)
+ return ;
+
+ restore_rect = *r;
+ maximized = 1;
+}
+
+int BaseWnd::getRestoredRect(RECT *r)
+{
+ if (!r)
+ return 0;
+
+ if (!maximized)
+ return 0;
+
+ *r = restore_rect;
+
+ return 1;
+}
+
+void BaseWnd::notifyDeferredMove(int x, int y)
+{
+ rx = x;
+ ry = y;
+}
+
+void BaseWnd::setWindowTitle(const wchar_t *title)
+{
+ Layout *l = static_cast<Layout *>(getInterface(layoutGuid));
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ c->setName(title);
+ }
+ }
+}
+
+#ifdef __APPLE__
+OSStatus BaseWnd::eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
+{
+ return eventNotHandledErr;
+}
+#endif
diff --git a/Src/Wasabi/api/wnd/basewnd.h b/Src/Wasabi/api/wnd/basewnd.h
new file mode 100644
index 00000000..b8747af0
--- /dev/null
+++ b/Src/Wasabi/api/wnd/basewnd.h
@@ -0,0 +1,944 @@
+//NONPORTABLE
+#ifndef _BASEWND_H
+#define _BASEWND_H
+
+#include <api/wnd/api_wnd.h>
+#include <api/timer/api_timer.h>
+#include <bfc/wasabi_std.h>
+#include <bfc/common.h>
+#include <api/wnd/api_window.h>
+#include <api/wnd/drag.h>
+#include <bfc/ptrlist.h>
+#include <bfc/tlist.h>
+#include <bfc/named.h>
+#include <api/timer/timerclient.h>
+#include <api/wnd/findobjectcb.h>
+#include <bfc/stack.h>
+#include <api/wnd/rootwnd.h>
+class BaseWnd;
+#include <tataki/canvas/bltcanvas.h>
+class FilenamePS;
+class Canvas;
+class ifc_canvas;
+class RegionI;
+class DragSet;
+class VirtualWnd;
+class Tooltip;
+class svc_toolTipsRenderer;
+class Accessible;
+
+// for triggerEvent()
+#define TRIGGER_ONRESIZE 1000
+#define TRIGGER_INVALIDATE 2000
+
+// it is safe to use anything higher than this for your own funky messages
+#define BASEWND_NOTIFY_USER NUM_NOTIFY_MESSAGES
+
+#define BASEWND_CURSOR_USERSET -1// window will do own setting
+#define BASEWND_CURSOR_POINTER 1
+#define BASEWND_CURSOR_NORTHSOUTH 2
+#define BASEWND_CURSOR_EASTWEST 3
+#define BASEWND_CURSOR_NORTHWEST_SOUTHEAST 4
+#define BASEWND_CURSOR_NORTHEAST_SOUTHWEST 5
+#define BASEWND_CURSOR_4WAY 6
+#define BASEWND_CURSOR_EDIT 7
+
+// Our own defined window messages
+
+#define WM_WA_CONTAINER_TOGGLED WM_USER+0x1338
+#define WM_WA_COMPONENT_TOGGLED WM_USER+0x1339
+#define WM_WA_RELOAD WM_USER+0x133A
+#define WM_WA_GETFBSIZE WM_USER+0x133B
+
+#define DEFERREDCB_FLUSHPAINT 0x200
+
+#define SYSRGN 4
+
+#define REGIONOP_NONE 0
+#define REGIONOP_OR 1
+#define REGIONOP_AND 2
+#define REGIONOP_SUB -1
+#define REGIONOP_SUB2 -2
+
+#define TABORDER_K 0.0001f
+
+class ReparentWndEntry {
+ public:
+ ReparentWndEntry(OSWINDOWHANDLE wnd, OSWINDOWHANDLE parentwnd);
+ virtual ~ReparentWndEntry() {}
+ void unparent();
+ void reparent(OSWINDOWHANDLE newparent);
+ private:
+ RECT rect;
+ OSWINDOWHANDLE wnd;
+};
+
+class virtualChildTimer {
+ public:
+ virtualChildTimer(int _id, ifc_window *_child) : id(_id), child(_child) { }
+ virtual ~virtualChildTimer() {}
+ int id;
+ ifc_window *child;
+};
+
+class RootWndFinder : public FindObjectCallbackI {
+ public:
+
+ RootWndFinder() { findobject_guid = INVALID_GUID; }
+ virtual ~RootWndFinder() { }
+
+ void reset() { findobject_id = L""; findobject_guid = INVALID_GUID; }
+ void setFindId(const wchar_t *id) { findobject_id = id; }
+ void setFindGuid(GUID guid) { findobject_guid = guid; }
+
+ virtual int findobjectcb_matchObject(ifc_window *w) {
+ if (!findobject_id.isempty()) {
+ if (w != NULL) {
+ const wchar_t *id = w->getId();
+ return WCSCASEEQLSAFE(id, findobject_id);
+ }
+ } else if (findobject_guid != INVALID_GUID) {
+ return (w->getInterface(findobject_guid) != NULL);
+ }
+ return 0;
+ }
+
+ private:
+
+ StringW findobject_id;
+ GUID findobject_guid;
+};
+
+#ifdef _WIN32
+typedef struct {
+ HWND owner;
+ HWND hthis;
+ PtrList<ifc_window> *hlist;
+} enumownedstruct;
+#endif
+
+class WndWatcher: public DependentViewerI {
+ public:
+ WndWatcher(BaseWnd *b) : watched(NULL), dep(NULL), watcher(b) { ASSERT(watcher != NULL); }
+ WndWatcher() : watched(NULL), dep(NULL), watcher(NULL) { }
+ virtual ~WndWatcher() {}
+
+ virtual void setWatcher(BaseWnd *w) {
+ if (watcher != NULL)
+ watchWindow(NULL);
+ watcher = w;
+ }
+
+ virtual void watchWindow(ifc_window *w) {
+ ASSERT(watcher != NULL);
+ if (dep != NULL) {
+ viewer_delViewItem(dep);
+ dep = NULL;
+ watched = NULL;
+ }
+ if (w != NULL) {
+ watched = w;
+ dep = w->getDependencyPtr();
+ viewer_addViewItem(dep);
+ }
+ }
+
+ virtual int viewer_onItemDeleted(ifc_dependent *item);
+
+ private:
+ ifc_window *watched;
+ ifc_dependent *dep;
+ BaseWnd *watcher;
+};
+
+#ifdef _WIN32
+BOOL CALLBACK EnumOwnedTopMostWindows(HWND hwnd, LPARAM lParam);
+#endif
+
+class TabOrderEntry {
+ public:
+ ifc_window *wnd;
+ float order; // yes, float. if a wnd tries to set order n and n is already set for another wnd, that other wnd will be pushed to n+k
+ // with k = 0.0001 . recursively, if n+k is taken, it'll push that wnd to n+2k, which if taken has its wnd pushed to n+3k, etc
+ // if n+xk >= n+1 (when x = 10000), the 10000th entry is discarded (if you manage to make a dialog with 10000 keyboard fields inside
+ // a single group, you're nuts anyway, and you should die a painful death)
+};
+
+class TabOrderSort {
+public:
+ static int compareItem(TabOrderEntry *p1, TabOrderEntry *p2) {
+ if (p1->order < p2->order) return -1;
+ if (p1->order > p2->order) return 1;
+ return 0;
+ }
+};
+
+
+// base class
+#define BASEWND_PARENT RootWndI
+class NOVTABLE BaseWnd :
+ public RootWndI,
+ public DragInterface,
+ public NamedW,
+ public DependentI,
+ public TimerClientI
+{
+
+ friend class VirtualWnd;
+
+protected:
+ // override constructor to init your data, but don't create anything yet
+ BaseWnd();
+
+public:
+
+ virtual ~BaseWnd();
+
+//INITIALIZATION
+ // these actually create the window
+ // try REALLY hard to not have to override these, and if you do,
+ // override the second one
+ virtual int init(ifc_window *parent, int nochild=FALSE);
+ virtual int init(OSMODULEHANDLE hInstance, OSWINDOWHANDLE parent, int nochild=FALSE);
+ virtual int isInited(); // are we post init() ?
+ virtual int isPostOnInit() { return postoninit; }
+
+ virtual int setVirtual(int i) { return 0; }
+
+ // if at all possible put your init stuff in this one, and call up the
+ // heirarchy BEFORE your code
+ virtual int onInit();
+ virtual int onPostOnInit(); // this one is called after onInit so you get a chance to do something after your inheritor override
+
+ // use this to return the cursor type to show
+ virtual int getCursorType(int x, int y);
+
+// WINDOW SIZING/MOVEMENT/CONTROL
+ virtual int getFontSize() { return 0; }
+ virtual int setFontSize(int size) { return -1; }
+
+ // if you override it, be sure to call up the heirarchy
+ virtual void resize(int x, int y, int w, int h, int wantcb=1); // resize yourself
+ void resize(RECT *r, int wantcb=1);
+ void resizeToRect(RECT *r) { resize(r); }//helper
+
+ // called after resize happens, return TRUE if you override
+ virtual int onResize();
+ virtual int onAfterResize() { return 1; }
+ void resizeToClient(BaseWnd *wnd); // resize a window to match you
+ virtual int onPostedMove(); // whenever WM_WINDOWPOSCHANGED happens, use mainly to record positions when moved by the window tracker, avoid using for another prupose, not portable
+
+ // move only, no resize
+ virtual void move(int x, int y);
+
+ virtual void notifyDeferredMove(int x, int y);
+
+ // puts window on top of its siblings
+ virtual void bringToFront();
+ // puts window behind its siblings
+ virtual void bringToBack();
+
+ // fired when a sibbling invalidates a region. you can change the region before returning, use with care, can fuck up everything if not used well
+ virtual int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx) { return 0; }
+
+ // set window's visibility
+ virtual void setVisible(int show);
+ virtual void setCloaked(int cloak);
+ virtual void onSetVisible(int show); // override this one
+ virtual void onChildInvalidate(api_region *r, ifc_window *w) {}
+
+ // enable/disable window for input
+ virtual void setEnabled(int en);
+ // grab the keyboard focus
+ virtual void setFocus();
+ virtual void setFocusOnClick(int f);
+ virtual int getFocusOnClick() { return focus_on_click; }
+
+ virtual int pointInWnd(POINT *p);
+
+ // repaint yourself
+ virtual void invalidate(); // mark entire window for repainting
+ virtual void invalidateRect(RECT *r);// mark specific rect for repainting
+ virtual void invalidateRgn(api_region *r);// mark specific rgn for repainting
+ virtual void invalidateFrom(ifc_window *who); // mark entire window for repainting
+ virtual void invalidateRectFrom(RECT *r, ifc_window *who);// mark specific rect for repainting
+ virtual void invalidateRgnFrom(api_region *r, ifc_window *who);// mark specific rgn for repainting
+ virtual void validate(); // unmark the entire window from repainting
+ virtual void validateRect(RECT *r); // unmark specific rect from repainting
+ virtual void validateRgn(api_region *reg); // unmark specific region from repainting
+
+ // no virtual on these please
+ void deferedInvalidateRgn(api_region *h);
+ void deferedInvalidateRect(RECT *r);
+ void deferedInvalidate();
+ void deferedValidateRgn(api_region *h);
+ void deferedValidateRect(RECT *r);
+ void deferedValidate();
+ api_region *getDeferedInvalidRgn();
+ int hasVirtualChildren();
+ virtual void setVirtualChildFocus(ifc_window *w);
+ virtual ifc_window *getNextVirtualFocus(ifc_window *w);
+ void setVirtualTabOrder(ifc_window *w, int a);
+ int getVirtualTabOrder(ifc_window *w);
+ virtual void setTabOrder(int a);
+ virtual int getTabOrder();
+ virtual void setAutoTabOrder();
+ virtual void setVirtualAutoTabOrder(ifc_window *w);
+ virtual void focusNext();
+ virtual void focusPrevious();
+ virtual ifc_window *getCurVirtualChildFocus() { return curVirtualChildFocus; }
+ virtual ifc_window *getTab(int what=TAB_GETNEXT);
+
+private:
+ //virtual int focusVirtualChild(api_window *child);
+ virtual void physicalInvalidateRgn(api_region *r);
+ void autoFocus(ifc_window *w);
+protected:
+ virtual int ensureVirtualCanvasOk();
+ virtual void setVirtualCanvas(Canvas *c);
+ virtual void setRSize(int x, int y, int w, int h);
+
+public:
+ virtual void repaint(); // repaint right now!
+
+ // override this to add decorations
+ virtual void getClientRect(RECT *);
+ RECT clientRect(); // helper
+ virtual void getNonClientRect(RECT *);
+ RECT nonClientRect(); // helper
+ virtual void getWindowRect(RECT *); // windows coords in screen system
+ RECT windowRect(); // helper
+ virtual void getPosition(POINT *pt); // window coord relative to os window (instead of rootparent)
+
+ virtual void *getInterface(GUID interface_guid) { return NULL; }
+ virtual void *dependent_getInterface(const GUID *classguid);
+
+ virtual void clientToScreen(int *x, int *y); // convenience fn
+ virtual void screenToClient(int *x, int *y); // convenience fn
+ virtual void clientToScreen(POINT *pt); // convenience fn
+ virtual void screenToClient(POINT *pt); // convenience fn
+ virtual void clientToScreen(RECT *r); // convenience fn
+ virtual void screenToClient(RECT *r); // convenience fn
+
+ void setIcon(OSICONHANDLE icon, int _small);
+ virtual void setSkinId(int id);
+
+ virtual int getPreferences(int what);
+ virtual void setPreferences(int what, int v);
+ virtual void setStartHidden(int wtf);
+
+ virtual void setDefaultCursor(Cursor *c);
+ virtual Canvas *getFrameBuffer();
+
+ void setWindowTitle(const wchar_t *title);
+
+
+// from api_window
+protected:
+ virtual DragInterface *getDragInterface();
+ virtual ifc_window *rootWndFromPoint(POINT *pt);
+ virtual int rootwnd_paintTree(ifc_canvas *canvas, api_region *r);
+
+ void assignRootFocus(ifc_window *w);
+
+public:
+ // override for custom processing (NONPORTABLE!)
+#ifdef _WIN32
+ virtual LRESULT wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#elif defined(__APPLE__)
+ virtual OSStatus eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
+#endif
+ virtual void performBatchProcesses(); // this is called after wndProc is called (under win32) to recompute batch operations such as calculating window regions, cascaderepainting, etc. this prevents N children from independently calling repaintTree for the whole gui on overlaping zones of the framebuffer. under OSes other than win32, this should be called after you've executed all your window events for this poll, try not to use it, or use a dirty bit to cut down on your job
+ virtual const wchar_t *getRootWndName();
+ virtual const wchar_t *getId();
+// end from api_window
+
+ // or override these, they're more portable
+ virtual int onContextMenu(int x, int y); // always return 1 if accept msg
+ virtual int onChildContextMenu(int x, int y); // always return 1 if accept msg
+
+ // called on WM_PAINT by onPaint(Canvas, api_region *), if the canvas is null, create your own, if not, it will have update regions clipped for you
+ virtual int onPaint(Canvas *canvas);
+ void setTransparency(int amount); // 0..255
+ int getTransparency();
+
+ // override those two
+ virtual void timerCallback(int id);
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ int setTimer(int id, int ms);
+ int killTimer(int id);
+ void postDeferredCallback(intptr_t p1, intptr_t p2=0, int mindelay=0);
+
+ // from timerclient
+ virtual int timerclient_onDeferredCallback(intptr_t p1, intptr_t p2);
+ virtual void timerclient_timerCallback(int id);
+ virtual TimerClient *timerclient_getMasterClient();
+ virtual void timerclient_onMasterClientMultiplex();
+ virtual TimerClient *getTimerClient();
+ virtual const wchar_t *timerclient_getName();
+
+private:
+ virtual int onPaint(Canvas *canvas, api_region *r);
+
+public:
+ // click-drag. FYI, the drag-drop handling overrides these
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onRightButtonDown(int x, int y) { return 0; }
+ virtual int onMouseMove(int x, int y); // only called when mouse captured
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onRightButtonUp(int x, int y) { return 0; }
+ virtual int onMouseWheelUp(int click, int lines);
+ virtual int onMouseWheelDown(int click, int lines);
+ virtual int beginCapture();
+ virtual int endCapture();
+ virtual int getCapture(); // returns 1 if this window has mouse/keyb captured
+ virtual void onCancelCapture(); // called when someone steals the capture from you
+ virtual void cancelCapture();
+
+ // these will not be called in the middle of a drag operation
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int onRightButtonDblClk(int x, int y);
+
+ virtual int onGetFocus(); // you have the keyboard focus
+ virtual int onKillFocus(); // you lost the keyboard focus
+ virtual int gotFocus();
+ virtual int isActive();
+ virtual int onActivate();
+ virtual void activate();
+ virtual int onDeactivate();
+ virtual int onEnable(int en);
+ virtual int isEnabled(int within=0);
+
+ virtual void registerAcceleratorSection(const wchar_t *name, int global=0);
+ virtual int onAcceleratorEvent(const wchar_t *name);
+
+ virtual int onChar(unsigned int c);
+ virtual int onKeyDown(int keyCode) { return 0; }
+ virtual int onKeyUp(int keyCode) { return 0; }
+ virtual int onSysKeyDown(int keyCode, int keyData) { return 0; }
+ virtual int onSysKeyUp(int keyCode, int keyData) { return 0; }
+
+ virtual int onEraseBkgnd(HDC dc);// override and return 0 to authorize bkg painting, 1 to avoid it (default to 1)
+ virtual int onUserMessage(int msg, int w, int l, int *r);
+
+//CHILD->PARENT MESSAGES
+ // feel free to override for your own messages, but be sure to call up the
+ // chain for unhandled msgs
+ // children should not call this directly if they don't have to; use
+ // notifyParent on yourself instead
+ // message ids should be put in notifmsg.h to avoid conflicts
+ virtual int childNotify(ifc_window *child, int msg,
+ int param1=0, int param2=0);
+
+
+ // don't try to override these
+ void setParent(ifc_window *newparent);
+ ifc_window *getParent();
+ virtual ifc_window *getRootParent();
+ virtual ifc_window *getDesktopParent();
+
+ // avoid overriding this one if you can
+ virtual int reparent(ifc_window *newparent);
+
+ // override this one
+ virtual void onSetParent(ifc_window *newparent) {}
+
+ virtual api_region *getRegion(); // override to return your client region
+ virtual void setRegionOp(int op); // 0 = none, 1 == or, 2=and, 3=xor, -1 = sub, -2 = sub thru groups
+ virtual void setRectRgn(int i); // set to 1 if you don't want your region to clip your clicks
+
+ virtual void invalidateWindowRegion(); // call this when your region has changed
+
+ api_region *getComposedRegion(); // returns the result of and/or/subing your children regions with your region
+ api_region *getSubtractorRegion(); // returns the composed subtracting region, that region is automatically subtracted from the desktop root parent's region
+ int ptInRegion(int x, int y); // handled automatically if you override getRegion and isRectRgn, but you can still override it if you need
+ virtual int getRegionOp(); //
+ virtual int isRectRgn();
+
+ // call this to notify your parent via its childNotify method
+ virtual int notifyParent(int msg, int param1=0, int param2=0);
+
+ // call this when you have received a childNotify and wish to
+ // defer the notification to your own notify object.
+ virtual int passNotifyUp(ifc_window *child, int msg,
+ int param1=0, int param2=0);
+
+ // This allows you to set a custom integer ID for any object you control,
+ // such that you can use its ID in a switch statement by calling getNotifyId()
+ // which is dispatched through api_window.
+ void setNotifyId(int id);
+ virtual int getNotifyId();
+
+ // from class Named
+ virtual void onSetName();
+ // non-virtuals only: sets the exported name of the OS window WITHOUT changing the Named member (getRootWndName() will not return this string)
+ virtual void setOSWndName(const wchar_t *name);
+ // non-virtuals only: retreive the exported name of the OS window. This is NOT the same as getRootWndName().
+ virtual const wchar_t *getOSWndName();
+
+ virtual const wchar_t *getTip();
+ virtual void setTip(const wchar_t *tooltip);
+ virtual int getStartHidden();
+ virtual void abortTip();
+ virtual int isVisible(int within=0);
+
+ // Virtual windows functions
+ virtual Canvas *createFrameBuffer(int w, int h);
+ virtual void prepareFrameBuffer(Canvas *canvas, int w, int h);
+ virtual void deleteFrameBuffer(Canvas *canvas);
+
+ virtual void registerRootWndChild(ifc_window *child);
+ virtual void unregisterRootWndChild(ifc_window *child);
+ virtual ifc_window *findRootWndChild(int x, int y, int only_virtuals=0);
+ virtual ifc_window *enumRootWndChildren(int _enum);
+ virtual int getNumRootWndChildren();
+
+ virtual int isVirtual();
+ virtual ifc_window *enumVirtualChild(int _enum);
+ virtual int getNumVirtuals();
+
+ virtual int handleVirtualChildMsg(UINT uMsg,int x, int y, void *p=NULL, void *d=NULL);
+ virtual void setVirtualChildCapture(ifc_window *child);
+ virtual ifc_window *getVirtualChildCapture();
+
+ virtual int cascadeRepaintFrom(ifc_window *who, int pack=1);
+ virtual int cascadeRepaintRgnFrom(api_region *reg, ifc_window *who, int pack=1);
+ virtual int cascadeRepaintRectFrom(RECT *r, ifc_window *who, int pack=1);
+ virtual int cascadeRepaint(int pack=1);
+ virtual int cascadeRepaintRgn(api_region *reg, int pack=1);
+ virtual int cascadeRepaintRect(RECT *r, int pack=1);
+ virtual void flushPaint();
+
+ virtual void onMinimize();
+ virtual void onRestore();
+ virtual int isMinimized();
+ virtual int isMaximized() { return maximized; }
+ virtual void onMaximize() { }
+
+ virtual void freeResources();
+ virtual void reloadResources();
+ virtual int getDesktopAlpha();
+ virtual int handleDesktopAlpha() { return isVirtual(); }
+ virtual int getPaintingAlpha(); // this one is a hint for painting, it returns either activealpha or inactivealpha
+ virtual void setAlpha(int activealpha, int inactivealpha=-1); // -1 means same as activealpha
+ virtual void getAlpha(int *activealpha=NULL, int *inactivealpha=NULL);
+ virtual int getFlag(int flag);
+ virtual int triggerEvent(int event, intptr_t p1, intptr_t p2);
+
+ void commitFrameBuffer(Canvas *canvas, RECT *r, double ratio);
+
+ virtual int paint(Canvas *canvas, api_region *r);
+
+protected:
+ void do_flushPaint();
+ virtual int paintTree(Canvas *canvas, api_region *r);
+ virtual int virtualBeforePaint(api_region *r);
+ virtual int virtualAfterPaint(api_region *r);
+ int virtualOnPaint();
+ virtual void setDesktopAlpha(int do_alpha);
+ virtual void onSetDesktopAlpha(int a);
+
+public:
+
+ virtual OSWINDOWHANDLE getOsWindowHandle();
+ virtual OSMODULEHANDLE getOsModuleHandle();
+
+public:
+
+ bool getNoCopyBits(void);
+ void setNoCopyBits(bool ncb);
+ BltCanvas *scalecanvas;
+
+protected:
+ virtual int checkDoubleClick(int button, int x, int y);
+
+//MISC
+public:
+ virtual int isDestroying(); // in the middle of dying
+
+//DRAGGING AND DROPPING -- (derived from DragInterface)
+
+ // derived windows should call this if they detect a drag beginning
+ // call once per datum per type of data being exposed. order is maintained
+ int addDragItem(const wchar_t *droptype, void *item);
+ // returns TRUE if drop was accepted
+ int handleDrag();
+ int resetDragSet(); // you don't need to call this
+
+ // (called on dest) when dragged item enters the winder
+ virtual int dragEnter(ifc_window *sourceWnd);
+ // (called on dest) during the winder
+ // FG> x/y are in screen corrdinates because target is a rootwnd
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd) { return 0; }
+ // (called on src)
+ virtual int dragSetSticky(ifc_window *wnd, int left, int right, int up, int down);
+ // (called on dest) when dragged item leaves the winder
+ virtual int dragLeave(ifc_window *sourceWnd) { return 0; }
+
+ // when it finally is dropped:
+
+ // called on destination window
+ // FG> x/y are in screen corrdinates because target is a rootwnd
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y) { return 0; }
+ // called on source window
+ virtual int dragComplete(int success) { return 0; }
+ // in that order
+ // must be called right before handleDrag(); (sender)
+ void setSuggestedDropTitle(const wchar_t *title);
+
+ // must be called from dragDrop(); (receiver)
+ virtual const wchar_t *dragGetSuggestedDropTitle(void);
+ virtual int dragCheckData(const wchar_t *type, int *nitems=NULL);
+ virtual void *dragGetData(int slot, int itemnum);
+ virtual int dragCheckOption(int option) { return 0; }
+
+ // return TRUE if you support any of the datatypes this window is exposing
+ virtual int checkDragTypes(ifc_window *sourceWnd) { return 0; }
+
+// external drops
+ // override this and return 1 to receive drops from the OS
+ virtual int acceptExternalDrops() { return 0; }
+
+ virtual void onExternalDropBegin() {}
+ virtual void onExternalDropDirScan(const wchar_t *dirname) {}
+ virtual void onExternalDropEnd() {}
+
+ virtual int bypassModal();
+
+ virtual ifc_window *findWindow(const wchar_t *id);
+ virtual ifc_window *findWindowByInterface(GUID interface_guid);
+ virtual ifc_window *findWindowByCallback(FindObjectCallback *cb);
+ virtual ifc_window *findWindowChain(FindObjectCallback *cb, ifc_window *wcaller=NULL);
+
+private:
+ void addDroppedFile(const wchar_t *filename, PtrList<FilenamePS> *plist); // recursive
+ void setLayeredWindow(int i);
+ Accessible *createNewAccObj();
+
+public:
+//FG> alternate notify window
+ virtual void setNotifyWindow(ifc_window *newnotify);
+ virtual ifc_window *getNotifyWindow();
+
+ virtual double getRenderRatio();
+ virtual void setRenderRatio(double r);
+ virtual void onRatioChanged() {}
+ virtual void setRatioLinked(int l);
+ virtual int handleRatio();
+ int renderRatioActive();
+ void multRatio(int *x, int *y=NULL);
+ void multRatio(RECT *r);
+ void divRatio(int *x, int *y=NULL);
+ void divRatio(RECT *r);
+ virtual int isClickThrough();
+ virtual void setClickThrough(int ct);
+ virtual ifc_window *getForwardWnd() { return this; }
+
+ virtual void setNoLeftClicks(int no);
+ virtual void setNoRightClicks(int no);
+ virtual void setNoDoubleClicks(int no);
+ virtual void setNoMouseMoves(int no);
+ virtual void setNoContextMenus(int no);
+
+ // these functions are override that can be changed via XML. They are not intended to describe how your wnd should receive its messages, they are here rather
+ // to allow a skinner to disable part of the functionality of an object (ie: removing the context menu via nocontextmenu="1").
+ virtual int wantDoubleClicks() { return !nodoubleclick; }
+ virtual int wantLeftClicks() { return !noleftclick; }
+ virtual int wantRightClicks() { return !norightclick; }
+ virtual int wantMouseMoves() { return !nomousemove; }
+ virtual int wantContextMenus() { return !nocontextmnu; }
+
+
+// DERIVED WINDOW BEHAVIORAL PREFERENCES
+protected:
+ // return 1 to get onMouseOver even if mouse isn't captured
+ virtual int wantSiblingInvalidations();
+
+ virtual int wantFocus();
+ virtual int wantAutoContextMenu(); // return 1 if you want to auto popup the main app context menu
+
+protected:
+
+ void onTipMouseMove();
+ void renderBaseTexture(ifc_canvas *c, const RECT &r, int alpha=255);
+ void rootwnd_renderBaseTexture(ifc_canvas *c, const RECT *r, int alpha=255) { renderBaseTexture(c, *r, alpha); }
+
+ int getTabOrderEntry(ifc_window *w);
+ void delTabOrderEntry(int i);
+ int getTabOrderEntry(float order);
+ void delTabOrderEntry(ifc_window *w);
+
+ virtual OSCURSORHANDLE getCustomCursor(int x, int y);
+
+public:
+ virtual ifc_window *getBaseTextureWindow();
+ void setBaseTextureWindow(ifc_window *w);
+ virtual int isMouseOver(int x, int y);
+
+ virtual void bringVirtualToFront(ifc_window *w);
+ virtual void bringVirtualToBack(ifc_window *w);
+ virtual void bringVirtualAbove(ifc_window *w, ifc_window *b);
+ virtual void bringVirtualBelow(ifc_window *w, ifc_window *b);
+ void changeChildZorder(ifc_window *w, int newpos);
+
+//CUT static int isDesktopAlphaAvailable();
+//CUT static int isTransparencyAvailable();
+ virtual int handleTransparency(); // return 0 if you use overlay mode to render your stuff
+ virtual int runModal();
+ virtual int exec() { return runModal(); }
+ virtual void endModal(int ret);
+
+ ifc_dependent *rootwnd_getDependencyPtr();
+ ifc_dependent *timerclient_getDependencyPtr();
+
+ virtual void signalMinMaxEnforcerChanged(void);
+ virtual void onMinMaxEnforcerChanged(void) {}
+ virtual void addMinMaxEnforcer(ifc_window *w);
+ virtual void removeMinMaxEnforcer(ifc_window *w);
+ virtual ifc_window *enumMinMaxEnforcer(int n);
+ virtual int getNumMinMaxEnforcers();
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+ virtual int sendAction(ifc_window *target, const wchar_t *action, const wchar_t *param=NULL, int x=0, int y=0, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0);
+
+ virtual void setRenderBaseTexture(int r);
+ virtual int getRenderBaseTexture();
+
+ virtual GuiObject *getGuiObject();
+
+ void setAutoResizeAfterInit(int tf) { want_autoresize_after_init = tf; }
+ virtual void setAllowDeactivation(int allow) { allow_deactivate = allow; }
+ virtual int allowDeactivation();
+
+ int getNumTabs();
+ ifc_window *enumTab(int i);
+ virtual void onSetRootFocus(ifc_window *w);
+
+ virtual int wantActivation() { return 1; } // return 0 if you don't want activation upon click
+
+ virtual Accessible *getAccessibleObject(int createifnotexists=1);
+
+ virtual int accessibility_getState();
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ virtual void setAlwaysOnTop(int i);
+ virtual int getAlwaysOnTop();
+#endif
+ virtual void wndwatcher_onDeleteWindow(ifc_window *w);
+
+ virtual void setOSModuleHandle(OSMODULEHANDLE module) { hinstance = module; }
+
+#ifndef WA3COMPATIBILITY
+ virtual void setDropTarget(void *dt);
+ virtual void *getDropTarget();
+#endif
+
+ virtual void pushWindowRect();
+ virtual int popWindowRect(RECT *rc=NULL, int applyhow=PWR_DIMENTIONS|PWR_POSITION);
+
+ virtual void maximize(int axis=MAXIMIZE_WIDTH|MAXIMIZE_HEIGHT);
+ virtual void restore(int what=RESTORE_X|RESTORE_Y|RESTORE_WIDTH|RESTORE_HEIGHT);
+ virtual int getRestoredRect(RECT *r);
+ virtual void setRestoredRect(RECT *r); // turns maximized state on automatically
+ virtual int forcedOnResize();
+ virtual void forcedOnResizeChain(ifc_window *w);
+
+protected:
+
+ void setForeignWnd(int i); // set to 1 if this basewnd was wrapped around an OSWINDOWHANDLE
+ // this means mainly that the destructor will not destroy the window handle.
+
+protected:
+ // ATTENTION: note the capitalization on these -- so as not to mix up with
+ // wndProc()'s hWnd
+ OSMODULEHANDLE hinstance;
+ OSWINDOWHANDLE hwnd;
+
+private:
+ ifc_window *parentWnd;
+
+ int inputCaptured;
+
+ void onTab();
+//CUT HWND createWindow(int x, int y, int w, int h, int nochild, HWND parent, HINSTANCE hinstance);
+ void recursive_setVirtualTabOrder(ifc_window *w, float a, float lambda=TABORDER_K);
+ void recursive_buildTabList(ifc_window *from, PtrList<ifc_window> *list);
+
+ RECT restore_rect;
+ int maximized;
+
+protected:
+
+ void dropVirtualCanvas();
+ int bufferizeLockedUIMsg(int uMsg, int wParam, int lParam);
+ void clearBufferizedUI() { bufferedmsgs.removeAll(); }
+ void checkLockedUI();
+ int checkModal();
+ void hintDestroying() { destroying=TRUE; } // call that in your destructor if you'd otherwise generate virtual calls after your destructor
+ virtual int forceTransparencyFlag();
+
+ int dragging;
+
+ Canvas *virtualCanvas;
+
+ void updateWindowRegion();
+ int isWindowRegionValid() { return !wndregioninvalid; }
+ virtual int wantRedrawOnResize() { return 1; }
+ int ensureWindowRegionValid();
+ int disable_tooltip_til_recapture;
+
+ virtual int reinit(); // calls reinit(api_window *parWnd, int nochild);
+ virtual int reinit(ifc_window *parWnd, int nochild); // calls reinit(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild);
+ virtual int reinit(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild);
+
+ int inonresize;
+
+ virtual void onBeforeReinit() {}
+ virtual void onAfterReinit() {}
+
+ StringW tip;
+private:
+ void reparentHWNDChildren();
+ void redrawHWNDChildren();
+ void unparentHWNDChildren();
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ void saveTopMosts();
+ void restoreTopMosts();
+#endif
+ void _cascadeRepaintRgn(api_region *rg);
+ void packCascadeRepaintRgn(api_region *rg);
+ int createTip();
+ void destroyTip(); // called in destructor, do not override
+ PtrList<DragSet> dragsets;
+ ifc_window *prevtarg;
+ StringW suggestedTitle;
+
+ typedef struct {
+ int msg;
+ int wparam;
+ int lparam;
+ } bufferedMsgStruct;
+
+ TList<bufferedMsgStruct> bufferedmsgs;
+ int uiwaslocked;
+
+ void onTip();
+ //FG
+ int start_hidden;
+ svc_toolTipsRenderer *tipsvc;
+
+ int tipid;
+ bool tip_done;
+ bool tipawaytimer;
+ bool tipshowtimer;
+ bool tipbeenchecked;
+ bool tipdestroytimer;
+
+ //FG
+ bool ncb;
+ uint32_t lastClick[2];
+ POINT lastClickP[2];
+
+ //FG
+ ifc_window *btexture;
+
+ //FG
+ ifc_window *notifyWindow;
+ bool destroying;
+
+ //CT:Virtual children
+ PtrList<ifc_window> virtualChildren;
+ PtrList<ifc_window> rootwndchildren; //FG
+ int virtualCanvasHandled;
+ int virtualCanvasH,virtualCanvasW;
+ int rwidth, rheight, rx, ry;
+ ifc_window *curVirtualChildCaptured;
+
+ //FG>
+ RegionI *deferedInvalidRgn;
+
+ OSWINDOWHANDLE oldCapture;
+
+ int hasfocus;
+ ifc_window *curVirtualChildFocus;
+
+ double ratio;
+ int skin_id;
+ int wndalpha;
+ int w2k_alpha;
+ int curframerate;
+
+ int notifyid;
+ int activealpha;
+ int inactivealpha;
+ int clickthrough;
+ int triedtipsvc;
+ int mustquit;
+ int returnvalue;
+ int postoninit;
+ int inited;
+ int skipnextfocus;
+ RegionI *subtractorrgn, *composedrgn;
+ void setWindowRegion(api_region *r);
+ void computeComposedRegion();
+ void assignWindowRegion(api_region *wr);
+ int wndregioninvalid;
+ int rectrgn, regionop;
+ RegionI *deferedCascadeRepaintRgn;
+ int need_flush_cascaderepaint;
+ Tooltip *tooltip;
+ PtrList<ifc_window> minmaxEnforcers;
+ int this_visible;
+ int renderbasetexture;
+ GuiObject *my_guiobject;
+ int want_autoresize_after_init;
+ int resizecount;
+ double lastratio;
+ int suggested_w, suggested_h;
+ int maximum_w, maximum_h;
+ int minimum_w, minimum_h;
+ int allow_deactivate;
+ int minimized;
+ int deleting;
+ int preventcancelcapture;
+ StringW tcname;
+ int focus_on_click;
+ PtrListQuickSorted<TabOrderEntry, TabOrderSort> childtabs;
+ ifc_window *rootfocus;
+ int ratiolinked;
+ int nodoubleclick, noleftclick, norightclick, nomousemove, nocontextmnu;
+ Cursor *customdefaultcursor;
+ Accessible *accessible;
+ StringW osname;
+ int focusEventsEnabled;
+ PtrList<ifc_window> ontoplist;
+ int alwaysontop;
+ WndWatcher rootfocuswatcher;
+
+ int cloaked;
+ int m_takenOver;
+ int this_enabled;
+ int has_alpha_flag;
+ RECT *commitfb_rect;
+ PtrList<ReparentWndEntry> reparentwnds;
+#ifndef WA3COMPATIBILITY
+ void *m_target;
+#endif
+ int lastnullregion;
+ Stack<RECT> windowrectstack;
+ TList<OSWINDOWHANDLE> ghosthwnd;
+ int ghostbust;
+
+ OSWINDOWHANDLE lastActiveWnd;
+
+};
+
+#ifdef WIN32
+__inline HINSTANCE HINSTANCEfromHWND(HWND wnd) {
+ if (wnd == NULL) return NULL;
+ return (HINSTANCE)(LONG_PTR)GetWindowLongPtrW(wnd, GWLP_HINSTANCE);
+}
+#endif
+
+#endif
diff --git a/Src/Wasabi/api/wnd/bitmap.cpp b/Src/Wasabi/api/wnd/bitmap.cpp
new file mode 100644
index 00000000..f89da5f6
--- /dev/null
+++ b/Src/Wasabi/api/wnd/bitmap.cpp
@@ -0,0 +1,1584 @@
+#include <precomp.h>
+
+//#define NO_SIMPLEFASTMODE
+#include <api/imgldr/api_imgldr.h>
+#include <api/wnd/blending.h>
+
+#include "bitmap.h"
+#ifndef _NOSTUDIO
+#include <api/api.h>
+#endif
+#include <bfc/std.h>
+#include <api/wnd/bltcanvas.h>
+
+#include <api/memmgr/memmgrapi.h>
+
+
+#if !defined(WIN32) && !defined(LINUX)
+#error port me!
+#endif
+
+#define ERRORBMP L"wasabi.bitmapnotfound"
+#define HARDERRORBMP L"xml/wasabi/window/error.png"
+// do not define NO_MMX in this file. :)
+
+#ifndef NO_MMX
+
+#ifdef WIN32
+#define MMX_CONST const
+#else
+#define MMX_CONST
+#endif
+
+static unsigned int MMX_CONST SkinBitmap_mmx_revn2[2]={0x01000100,0x01000100};
+static unsigned int MMX_CONST SkinBitmap_mmx_zero[2];
+static unsigned int MMX_CONST SkinBitmap_mmx_one[2]={1,0};
+#define HAS_MMX Blenders::MMX_AVAILABLE()
+
+#else
+
+//NO_MMX defined
+#define HAS_MMX 0
+
+#endif
+
+
+#ifndef _NOSTUDIO
+
+#ifdef WASABI_COMPILE_IMGLDR
+SkinBitmap::SkinBitmap(HINSTANCE hInstance, int id, const wchar_t *forcegroup)
+{
+ bitmapname = L"";
+ subimage_w=-1;
+ subimage_h=-1;
+ x_offset=-1;
+ y_offset=-1;
+ fullimage_w=fullimage_h=0;
+ has_alpha = 0;
+ ASSERT(hInstance != NULL);
+ ownbits=1;
+ fromskin = 0;
+ bits=WASABI_API_IMGLDR->imgldr_makeBmp(hInstance, id,&has_alpha,&fullimage_w,&fullimage_h, forcegroup);
+ last_failed = 0;
+ #ifdef WASABI_COMPILE_SKIN
+ if (bits == NULL)
+ {
+ //last_failed = 1;
+ //TODO: bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(ERRORBMP, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ }
+ #endif
+ if (bits == NULL)
+ {
+ last_failed = 1;
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(HARDERRORBMP, &has_alpha, &fullimage_w, &fullimage_h);
+ }
+}
+#endif
+#endif
+
+// TODO: benski> make sure this works :)
+SkinBitmap::SkinBitmap(ARGB32 *_bits, int w, int h)
+{
+ subimage_w=-1;
+ subimage_h=-1;
+ x_offset=-1;
+ y_offset=-1;
+ bitmapname = L"";
+ fullimage_w=fullimage_h=0;
+ has_alpha = 1;
+ ownbits=0;
+ bits = _bits;
+ fromskin = 0;
+ last_failed = 0;
+}
+
+// TODO: benski> could we be using GetDIBits here?
+void SkinBitmap::bmpToBits(HBITMAP hbmp, HDC defaultDC)
+{
+#ifdef WIN32
+ if (hbmp && !bits)
+ {
+ BITMAPINFO srcbmi={0,};
+ HDC hMemDC, hMemDC2;
+ HBITMAP hprev,hprev2=0;
+ HBITMAP hsrcdib;
+ void *srcdib;
+ BITMAP bm;
+ int r = GetObject(hbmp, sizeof(BITMAP), &bm);
+ ASSERT(r != 0);
+
+ fullimage_w=bm.bmWidth;
+ fullimage_h=ABS(bm.bmHeight);
+
+ int bmw=getWidth();
+ int bmh=getHeight();
+ int xo=getX();
+ int yo=getY();
+
+ srcbmi.bmiHeader.biSize=sizeof(srcbmi.bmiHeader);
+ srcbmi.bmiHeader.biWidth=bmw;
+ srcbmi.bmiHeader.biHeight=-bmh;
+ srcbmi.bmiHeader.biPlanes=1;
+ srcbmi.bmiHeader.biBitCount=32;
+ srcbmi.bmiHeader.biCompression=BI_RGB;
+ hMemDC = CreateCompatibleDC(NULL);
+ hsrcdib=CreateDIBSection(hMemDC,&srcbmi,DIB_RGB_COLORS,&srcdib,NULL,0);
+ ASSERTPR(hsrcdib != 0, "CreateDIBSection() failed #6");
+ if (defaultDC)
+ hMemDC2 = defaultDC;
+ else {
+ hMemDC2 = CreateCompatibleDC(NULL);
+ hprev2 = (HBITMAP) SelectObject(hMemDC2, hbmp);
+ }
+ hprev = (HBITMAP) SelectObject(hMemDC, hsrcdib);
+ BitBlt(hMemDC,0,0,bmw,bmh,hMemDC2,xo,yo,SRCCOPY);
+ SelectObject(hMemDC, hprev);
+ if (!defaultDC) {
+ SelectObject(hMemDC2, hprev2);
+ DeleteDC(hMemDC2);
+ }
+ DeleteDC(hMemDC);
+ bits=(ARGB32*)MALLOC_(bmw*bmh*4);
+ if (getHeight()+getY() > bm.bmHeight || getWidth()+getX() > bm.bmWidth) {
+ ASSERTALWAYS(StringPrintf("Subbitmap coordinates outside master bitmap [%d,%d,%d,%d in 0,0,%d,%d]", getX(), getY(), getWidth(), getHeight(), bm.bmWidth, bm.bmHeight));
+ }
+ MEMCPY32(bits,srcdib,bmw*bmh/**sizeof(ARGB32)*/);
+ DeleteObject(hsrcdib);
+ x_offset=-1;
+ y_offset=-1;
+ subimage_w=-1;
+ subimage_h=-1;
+ fullimage_w=bmw;
+ fullimage_h=bmh;
+ }
+#endif
+#ifdef LINUX
+ if ( ! bits ) {
+ fullimage_w=hbmp.bmWidth;
+ fullimage_h=ABS(hbmp.bmHeight);
+
+ bits=(ARGB32*)MALLOC_( fullimage_w * fullimage_h * 4 );
+ MEMCPY32( bits, hbmp.shmseginfo->shmaddr, fullimage_w * fullimage_h );
+ x_offset=-1;
+ y_offset=-1;
+ subimage_w=-1;
+ subimage_h=-1;
+ }
+#endif
+}
+
+#ifndef _NOSTUDIO
+#ifdef WASABI_COMPILE_IMGLDR
+SkinBitmap::SkinBitmap(const wchar_t *elementname, int _cached)
+{
+ ASSERT(elementname!= NULL);
+
+ bitmapname = elementname;
+ x_offset = -1;
+ y_offset = -1;
+ subimage_w = -1;
+ subimage_h = -1;
+ fullimage_w=fullimage_h=0;
+ ownbits=1;
+ bits = NULL;
+ fromskin = 0;
+ last_failed = 0;
+#ifdef WASABI_COMPILE_SKIN
+ bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(elementname, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ fromskin = (bits != NULL);
+#endif
+ if (bits == NULL)
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(elementname, &has_alpha, &fullimage_w, &fullimage_h);
+ #ifdef WASABI_COMPILE_SKIN
+ if (bits == NULL)
+ {
+ bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(ERRORBMP, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ last_failed = 1;
+ }
+ #endif
+ if (bits == NULL)
+ {
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(HARDERRORBMP, &has_alpha, &fullimage_w, &fullimage_h);
+ last_failed = 1;
+ }
+
+ // check that coordinates are correct
+ if(x_offset!=-1 && x_offset>fullimage_w) x_offset=fullimage_w-1;
+ if(y_offset!=-1 && y_offset>fullimage_h) y_offset=fullimage_h-1;
+ if(subimage_w!=-1 && (x_offset+subimage_w)>fullimage_w) subimage_w=fullimage_w-x_offset;
+ if(subimage_h!=-1 && (y_offset+subimage_h)>fullimage_h) subimage_h=fullimage_h-y_offset;
+
+ // ASSERTPR(bits != NULL, elementname);
+ if (bits == NULL) {
+ DebugString("element not found ! %s\n", elementname);
+ int n = 10*10;
+ bits = (ARGB32 *)WASABI_API_MEMMGR->sysMalloc(n * 4);
+
+
+ ARGB32 *p = bits;
+ while (n--)
+ *p++ = 0xFFFF00FF;
+ }
+}
+#endif
+#endif
+
+SkinBitmap::SkinBitmap(HBITMAP bitmap)
+{
+#ifdef WIN32
+ ASSERT(bitmap != NULL);
+#endif
+ subimage_w=-1;
+ subimage_h=-1;
+ x_offset=-1;
+ y_offset=-1;
+ bitmapname = L"";
+ fullimage_w=fullimage_h=0;
+ has_alpha = 0;
+ ownbits=1;
+ bits = NULL;
+ fromskin = 0;
+ last_failed = 0;
+ bmpToBits(bitmap,NULL);
+}
+
+SkinBitmap::SkinBitmap(HBITMAP bitmap, HDC dc, int _has_alpha, void *_bits)
+{
+ subimage_w=-1;
+ subimage_h=-1;
+ x_offset=-1;
+ y_offset=-1;
+ fromskin = 0;
+ last_failed = 0;
+ bitmapname = L"";
+ fullimage_w=fullimage_h=0;
+#ifdef WIN32
+ ASSERT(bitmap != NULL);
+#endif
+ has_alpha = _has_alpha;
+ bits = (ARGB32*)_bits;
+ if (!_bits)
+ {
+ ownbits=1;
+ bmpToBits(bitmap,dc);
+ }
+ else
+ {
+#ifdef WIN32
+ BITMAP bm;
+ ownbits=0;
+ int r = GetObject(bitmap, sizeof(BITMAP), &bm);
+ ASSERT(r != 0);
+ fullimage_w=bm.bmWidth;
+ fullimage_h=ABS(bm.bmHeight);
+#endif
+#ifdef LINUX
+ ownbits=0;
+ fullimage_w=bitmap.bmWidth;
+ fullimage_h=ABS(bitmap.bmHeight);
+#endif
+//port me
+ }
+}
+
+SkinBitmap::SkinBitmap(int w, int h, DWORD bgcolor) {
+ subimage_w=-1;
+ subimage_h=-1;
+ x_offset=-1;
+ y_offset=-1;
+ fullimage_w=w;
+ bitmapname = L"";
+ fullimage_h=h;
+ fromskin = 0;
+ last_failed = 0;
+
+ int memsize = w*h*sizeof(ARGB32);
+ if (memsize == 0) memsize++; // +1 so no failure when 0x0
+ bits = (ARGB32*)MALLOC_(memsize);
+
+ DWORD *dw = (DWORD *)bits;
+ MEMFILL<DWORD>(dw, bgcolor, w*h);
+
+ has_alpha = TRUE;
+ ownbits=2; // 2 specifies should be FREE()'d
+}
+
+SkinBitmap::~SkinBitmap() {
+ if (bits) {
+ if (ownbits==2) FREE(bits);
+#ifndef _NOSTUDIO
+#ifdef WASABI_COMPILE_IMGLDR
+ else if (ownbits) {
+#ifdef WASABI_COMPILE_SKIN
+ if (fromskin)
+ WASABI_API_IMGLDR->imgldr_releaseSkinBitmap(bits);
+ else
+#endif
+#ifndef _WASABIRUNTIME
+ WASABI_API_IMGLDR->imgldr_releaseBmp(bits);
+#else
+ WASABI_API_IMGLDR->imgldr_releaseSkinBitmap(bits);
+#endif
+ }
+#endif
+#endif
+ }
+ bits=NULL;
+}
+
+void SkinBitmap::blit(ifc_canvas *canvas, int x, int y) {
+ RECT src, dst;
+ src.left=0;
+ src.top=0;
+ src.bottom=getHeight();
+ src.right=getWidth();
+ dst.left=x;
+ dst.right=x+getWidth();
+ dst.top=y;
+ dst.bottom=y+getHeight();
+ blitToRect(canvas,&src,&dst,255);
+}
+
+void SkinBitmap::blitRectToTile(ifc_canvas *canvas, RECT *dest, RECT *src, int xoffs, int yoffs, int alpha) {
+ int startx,starty;
+
+ int w,h;
+
+ w = src->right-src->left;
+ h = src->bottom-src->top;
+ if (w <= 0 || h <= 0) return; //wtfmf
+
+ RECT c;
+ if (canvas->getClipBox(&c) == NULLREGION) {
+ c = *dest;
+ } else {
+ if (dest->left > c.left) c.left = dest->left;
+ if (dest->top > c.top) c.top = dest->top;
+ if (dest->right < c.right) c.right = dest->right;
+ if (dest->bottom < c.bottom) c.bottom = dest->bottom;
+ }
+
+
+ starty = c.top-((c.top - dest->top) % h)- yoffs;
+ startx = c.left-((c.left - dest->left) % w) - xoffs;
+
+ for (int j=starty;j<c.bottom;j+=h)
+ for (int i=startx;i<c.right;i+=w) {
+ int xp=i;
+ int yp=j;
+ int xo=0;
+ int yo=0;
+ int _w=getWidth();
+ int _h=getHeight();
+ if (xp < c.left) {
+ xo=c.left-xp;
+ _w+=xo;
+ xp=c.left;
+ }
+ if (yp < c.top) {
+ yo=c.top-yp;
+ _h+=yo;
+ yp=c.top;
+ }
+ if (xp + _w >= c.right) _w=c.right-xp;
+ if (yp + _h >= c.bottom) _h=c.bottom-yp;
+ RECT _s={xo, yo, xo+_w, yo+_h};
+ RECT _d={xp, yp, xp+_w, yp+_h};
+ blitToRect(canvas, &_s, &_d, alpha);
+ }
+}
+
+
+void SkinBitmap::blitTile(ifc_canvas *canvas, RECT *dest, int xoffs, int yoffs, int alpha) {
+ RECT r={0,0,getWidth(),getHeight()};
+ blitRectToTile(canvas, dest, &r, xoffs, yoffs, alpha);
+}
+
+#ifdef WIN32
+#pragma warning(push)
+#pragma warning(disable : 4799)
+#endif
+
+
+#define DEFAULT_CACHE_WIDTH 64
+#define DEFAULT_CACHE_HEIGHT 64
+int cacheWidth = DEFAULT_CACHE_WIDTH;
+int cacheHeight = DEFAULT_CACHE_HEIGHT;
+BltCanvas blitToRectCanvas(DEFAULT_CACHE_WIDTH,DEFAULT_CACHE_HEIGHT);
+
+void SkinBitmap::blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha) { // only dst(top,left) are used
+
+ if (alpha <= 0) return;
+ if (alpha > 255) alpha = 255;
+
+ HDC hdc = canvas->getHDC();
+ if (hdc == NULL) return;
+ void *dib=canvas->getBits();
+ int cwidth,cheight, pitch;
+ BaseCloneCanvas clone(canvas);
+ bool usingBlitCanvas = false;
+ RECT destrect=*dst;
+ destrect.bottom=destrect.top+(src->bottom-src->top);
+ destrect.right=destrect.left+(src->right-src->left);
+
+ RECT c;
+ int ctype=canvas->getClipBox(&c);
+
+ if (c.top > destrect.top) destrect.top=c.top;
+ if (c.left > destrect.left) destrect.left=c.left;
+ if (c.bottom < destrect.bottom) destrect.bottom=c.bottom;
+ if (c.right < destrect.right) destrect.right=c.right;
+
+#ifdef NO_SIMPLEFASTMODE
+ dib=NULL;
+#endif
+
+ if (destrect.right <= destrect.left || destrect.bottom <= destrect.top) return;
+ int xs,yp,xe,ye;
+
+ if (!dib || canvas->getDim(NULL,&cheight,&cwidth) || !cwidth || cheight < 1 || ctype == COMPLEXREGION)
+ {
+ cwidth=destrect.right-destrect.left;
+ cheight=destrect.bottom-destrect.top;
+ if (cwidth > cacheWidth || cheight > cacheHeight)
+ {
+ cacheWidth=MAX(cacheWidth, cwidth);
+ cacheHeight=MAX(cacheHeight, cheight);
+ blitToRectCanvas.DestructiveResize(cacheWidth, cacheHeight);
+ }
+
+ dib = blitToRectCanvas.getBits();
+ if (has_alpha || alpha < 255)
+ clone.blit(destrect.left, destrect.top, &blitToRectCanvas, 0, 0, cwidth, cheight);
+
+ xs=0;
+ yp=0;
+ xe=cwidth;
+ ye=cheight;
+ pitch=cacheWidth;
+ usingBlitCanvas = true;
+ }
+ else
+ {
+
+ xs=destrect.left;
+ xe=destrect.right;
+ yp=destrect.top;
+ ye=destrect.bottom;
+
+ cwidth/=4;
+ pitch=cwidth;
+ }
+ int xpo=(dst->left-destrect.left+xs)-(getX()+src->left);
+ int ypo=(dst->top-destrect.top+yp)-(getY()+src->top);
+
+ if (yp < 0) yp=0;
+ if (xs < 0) xs=0;
+
+ if (yp<getY()+ypo) yp=ypo+getY();
+ if (xs<getX()+xpo) xs=xpo+getX();
+
+ if (xe > getWidth()+getX()+xpo) xe=getWidth()+getX()+xpo;
+ if (ye > getHeight()+getY()+ypo) ye=getHeight()+getY()+ypo;
+
+ // blend bitmap to dib
+
+ if (xs<xe) for (; yp < ye; yp ++) {
+ int xp=xe-xs;
+ unsigned int *dest=((unsigned int*)dib) + pitch*yp + xs;
+ unsigned int *src=((unsigned int*)bits) + (yp-ypo)*fullimage_w + (xs-xpo);
+
+ if (!has_alpha && alpha==255) // simple copy
+ {
+ MEMCPY32(dest,src,xp);
+ }
+ else if (!has_alpha) { // no alpha channel info, but just a simple blend
+ if (!HAS_MMX)
+ while (xp--) *dest++ = Blenders::BLEND_ADJ1(*src++, *dest, alpha);
+
+ #ifndef NO_MMX
+ else
+ {
+#ifdef WIN32
+ if (xp>1) __asm
+ {
+ movd mm3, [alpha]
+ mov ecx, xp
+
+ movq mm4, [SkinBitmap_mmx_revn2]
+ packuswb mm3, mm3 // 0000HHVV
+
+ paddusw mm3, [SkinBitmap_mmx_one]
+ mov edi, dest
+
+ punpcklwd mm3, mm3 // HHVVHHVV
+ mov esi, src
+
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+ shr ecx, 1
+
+ psubw mm4, mm3
+
+ align 16
+ _blitAlpha_Loop1:
+
+ movd mm0, [edi]
+
+ movd mm1, [esi]
+ punpcklbw mm0, [SkinBitmap_mmx_zero]
+
+ movd mm7, [edi+4]
+ punpcklbw mm1, [SkinBitmap_mmx_zero]
+
+ pmullw mm0, mm4
+ pmullw mm1, mm3
+
+ movd mm6, [esi+4]
+ punpcklbw mm7, [SkinBitmap_mmx_zero]
+
+ punpcklbw mm6, [SkinBitmap_mmx_zero]
+
+ pmullw mm7, mm4
+ pmullw mm6, mm3
+
+ paddw mm0, mm1
+
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+ add esi, 8
+
+ movd [edi], mm0
+ paddw mm7, mm6
+
+ psrlw mm7, 8
+
+ packuswb mm7, mm7
+
+ movd [edi+4], mm7
+
+ add edi, 8
+
+ dec ecx
+ jnz _blitAlpha_Loop1
+ mov src, esi
+ mov dest, edi
+#else
+ if ( xp > 1 ) {
+ __asm__ volatile (
+ "movd %6, %%mm3\n"
+ "mov %2, %%ecx\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm4\n"
+ "packuswb %%mm3, %%mm3\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm3\n"
+ "mov %0, %%edi\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "mov %1, %%esi\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "shr $1, %%ecx\n"
+ "psubw %%mm3, %%mm4\n"
+ ".align 16\n"
+ "_blitAlpha_Loop1:\n"
+ "movd (%%edi), %%mm0\n"
+ "movd (%%esi), %%mm1\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm0\n"
+ "movd 4(%%edi), %%mm7\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm1\n"
+ "pmullw %%mm3, %%mm0\n"
+ "pmullw %%mm4, %%mm1\n"
+ "movd 4(%%esi), %%mm6\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm7\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm6\n"
+ "pmullw %%mm4, %%mm6\n"
+ "pmullw %%mm3, %%mm7\n"
+ "paddw %%mm1, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "add $8, %%esi\n"
+ "movd %%mm0, (%%edi)\n"
+ "paddw %%mm6, %%mm7\n"
+ "psrlw $8, %%mm7\n"
+ "packuswb %%mm7, %%mm7\n"
+ "movd %%mm7, 4(%%edi)\n"
+ "add $8, %%edi\n"
+ "dec %%ecx\n"
+ "jnz _blitAlpha_Loop1\n"
+ "mov %%esi, %1\n"
+ "mov %%edi, %0\n"
+
+ : "=m" (dest), "=m" (src), "=m" (xp)
+ : "0" (dest), "1" (src), "2" (xp), "m" (alpha)
+ : "%eax", "%ecx", "%esi", "%edi" );
+
+#endif
+ }
+ if (xp & 1) *dest++ = Blenders::BLEND_ADJ1_MMX(*src++, *dest, alpha);
+ } // mmx available
+ #endif // !NO_MMX
+ }
+ else if (alpha == 255) { // no global alpha, just alpha channel
+ if (!HAS_MMX)
+ while (xp--) *dest++ = Blenders::BLEND_ADJ2(*dest, *src++);
+
+ #ifndef NO_MMX
+ else
+ {
+#ifdef WIN32
+ if (xp > 1) __asm
+ {
+ mov ecx, xp
+ shr ecx, 1
+ mov edi, dest
+ mov esi, src
+ align 16
+ _blitAlpha_Loop2:
+
+ movd mm3, [esi]
+ movd mm5, [esi+4]
+
+ movq mm2, [SkinBitmap_mmx_revn2]
+ psrld mm3, 24
+
+ movq mm4, [SkinBitmap_mmx_revn2]
+ psrld mm5, 24
+
+ movd mm0, [edi]
+ packuswb mm3, mm3 // 0000HHVV
+
+ movd mm1, [esi]
+ packuswb mm5, mm5 // 0000HHVV
+
+ movd mm6, [esi+4]
+ paddusw mm3, [SkinBitmap_mmx_one]
+
+ punpcklwd mm3, mm3 // HHVVHHVV
+ paddusw mm5, [SkinBitmap_mmx_one]
+
+ movd mm7, [edi+4]
+ punpcklwd mm5, mm5 // HHVVHHVV
+
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+ punpckldq mm5, mm5 // HHVVHHVV HHVVHHVV
+
+ punpcklbw mm6, [SkinBitmap_mmx_zero]
+ psubw mm4, mm5
+
+ punpcklbw mm0, [SkinBitmap_mmx_zero]
+ psubw mm2, mm3
+
+ punpcklbw mm7, [SkinBitmap_mmx_zero]
+ pmullw mm0, mm2
+
+ pmullw mm7, mm4
+ punpcklbw mm1, [SkinBitmap_mmx_zero]
+
+ psubw mm2, mm3
+
+ psrlw mm0, 8
+ psrlw mm7, 8
+ paddw mm0, mm1
+
+ paddw mm7, mm6
+ packuswb mm0, mm0
+
+ movd [edi], mm0
+ packuswb mm7, mm7
+
+ movd [edi+4], mm7
+
+ add esi, 8
+ add edi, 8
+
+ dec ecx
+ jnz _blitAlpha_Loop2
+ mov src, esi
+ mov dest, edi
+#else
+ if( xp > 1 ) {
+ __asm__ volatile (
+ "mov %4, %%ecx\n"
+ "shr $1, %%ecx\n"
+ "mov %0, %%edi\n"
+ "mov %1, %%esi\n"
+ ".align 16\n"
+ "_blitAlpha_Loop2:\n"
+ "movd (%%esi), %%mm3\n"
+ "movd 4(%%esi), %%mm5\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm2\n"
+ "psrld $24, %%mm3\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm4\n"
+ "psrld $24, %%mm5\n"
+ "movd (%%edi), %%mm0\n"
+ "packuswb %%mm3, %%mm3\n"
+ "movd (%%esi), %%mm1\n"
+ "packuswb %%mm5, %%mm5\n"
+ "movd 4(%%esi), %%mm6\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm3\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm5\n"
+ "movd 4(%%edi), %%mm7\n"
+ "punpcklwd %%mm5, %%mm5\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "punpckldq %%mm5, %%mm5\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm6\n"
+ "psubw %%mm5, %%mm4\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm0\n"
+ "psubw %%mm3, %%mm2\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm7\n"
+ "pmullw %%mm2, %%mm0\n"
+ "pmullw %%mm4, %%mm7\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm1\n"
+ "psubw %%mm3, %%mm2\n"
+ "psrlw $8, %%mm0\n"
+ "psrlw $8, %%mm7\n"
+ "paddw %%mm1, %%mm0\n"
+ "paddw %%mm6, %%mm7\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, (%%edi)\n"
+ "packuswb %%mm7, %%mm7\n"
+ "movd %%mm7, 4(%%edi)\n"
+ "add $8, %%esi\n"
+ "add $8, %%edi\n"
+ "dec %%ecx\n"
+ "jnz _blitAlpha_Loop2\n"
+ "mov %%esi, %1\n"
+ "mov %%edi, %0\n"
+
+ : "=m" (dest), "=m" (src)
+ : "0" (dest), "1" (src), "m" (xp)
+ : "%eax", "%ecx", "%esi", "%edi" );
+#endif
+ }
+ if (xp&1) *dest++ = Blenders::BLEND_ADJ2_MMX(*dest, *src++);
+ } // HAS_MMX
+ #endif // ifndef NO_MMX
+ }
+ else { // both
+ if (!HAS_MMX)
+ while (xp--) *dest++ = Blenders::BLEND_ADJ3(*dest, *src++, alpha);
+ #ifndef NO_MMX
+ else
+ {
+#ifdef WIN32
+ if (xp > 1) __asm
+ {
+ movd mm5, [alpha]
+ mov ecx, xp
+
+ packuswb mm5, mm5
+ shr ecx, 1
+
+ paddusw mm5, [SkinBitmap_mmx_one]
+
+ punpcklwd mm5, mm5
+ mov edi, dest
+
+ punpckldq mm5, mm5
+ mov esi, src
+
+ align 16
+ _blitAlpha_Loop3:
+
+ movd mm3, [esi] // VVVVVVVV
+ movd mm4, [esi+4] // VVVVVVVV
+
+ movd mm0, [edi]
+ psrld mm3, 24
+
+ movd mm1, [esi]
+ psrld mm4, 24
+
+ paddusw mm3, [SkinBitmap_mmx_one]
+ paddusw mm4, [SkinBitmap_mmx_one]
+
+ movd mm7, [edi+4]
+ punpcklwd mm3, mm3
+
+ movd mm6, [esi+4]
+ punpcklwd mm4, mm4
+
+ punpckldq mm3, mm3
+ punpckldq mm4, mm4
+
+ pmullw mm3, mm5
+ pmullw mm4, mm5
+
+ punpcklbw mm7, [SkinBitmap_mmx_zero]
+ punpcklbw mm6, [SkinBitmap_mmx_zero]
+
+ movq mm2, [SkinBitmap_mmx_revn2]
+ psrlw mm3, 8
+
+ psrlw mm4, 8
+
+ punpcklbw mm0, [SkinBitmap_mmx_zero]
+ punpcklbw mm1, [SkinBitmap_mmx_zero]
+
+ psubw mm2, mm3
+ pmullw mm0, mm2
+
+ pmullw mm1, mm5
+ add esi, 8
+
+ movq mm2, [SkinBitmap_mmx_revn2]
+ pmullw mm6, mm5
+
+ paddusw mm0, mm1
+ psubw mm2, mm4
+
+ pmullw mm7, mm2
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+ paddusw mm7, mm6
+
+ movd [edi], mm0
+ psrlw mm7, 8
+
+ packuswb mm7, mm7
+
+ movd [edi+4], mm7
+
+ add edi, 8
+
+ dec ecx
+ jnz _blitAlpha_Loop3
+ mov src, esi
+ mov dest, edi
+#else
+ if ( xp > 1 ) {
+ __asm__ volatile (
+ "movd %5, %%mm5\n"
+ "mov %4, %%ecx\n"
+ "packuswb %%mm5, %%mm5 \n"
+ "shr $1, %%ecx\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm5\n"
+ "punpcklwd %%mm5, %%mm5\n"
+ "mov %0, %%edi\n"
+ "punpckldq %%mm5, %%mm5\n"
+ "mov %1, %%esi\n"
+ ".align 16\n"
+ "_blitAlpha_Loop3:\n"
+ "movd (%%esi), %%mm3\n"
+ "movd 4(%%esi), %%mm4\n"
+ "movd (%%edi), %%mm0\n"
+ "psrld $24, %%mm3\n"
+ "movd (%%esi), %%mm1\n"
+ "psrld $24, %%mm4\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm3\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm4\n"
+ "movd 4(%%edi), %%mm7\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "movd 4(%%esi), %%mm6\n"
+ "punpcklwd %%mm4, %%mm4\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "punpckldq %%mm4, %%mm4\n"
+ "pmullw %%mm5, %%mm3\n"
+ "pmullw %%mm5, %%mm4\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm7\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm6\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm2\n"
+ "psrlw $8, %%mm3\n"
+ "psrlw $8, %%mm4\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm0\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm1\n"
+ "psubw %%mm3, %%mm2\n"
+ "pmullw %%mm2, %%mm0\n"
+ "pmullw %%mm5, %%mm1\n"
+ "add $8, %%esi\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm2\n"
+ "pmullw %%mm5, %%mm6\n"
+ "paddusw %%mm1, %%mm0\n"
+ "psubw %%mm4, %%mm2\n"
+ "pmullw %%mm2, %%mm7\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "paddusw %%mm6, %%mm7\n"
+ "movd %%mm0, (%%edi)\n"
+ "psrlw $8, %%mm7\n"
+ "packuswb %%mm7, %%mm7\n"
+ "movd %%mm7, 4(%%edi)\n"
+ "add $8, %%edi\n"
+ "dec %%ecx\n"
+ "jnz _blitAlpha_Loop3\n"
+ "mov %%esi, %1\n"
+ "mov %%edi, %0\n"
+
+ : "=m" (dest), "=m" (src)
+ : "0" (dest), "1" (src), "m" (xp), "m" (alpha)
+ : "%eax", "%ecx", "%esi", "%edi" );
+#endif
+ }
+ if (xp&1) *dest++ = Blenders::BLEND_ADJ3_MMX(*dest, *src++, alpha);
+ } // HAS_MMX
+ #endif // ifndef NO_MMX
+ }
+ }
+#ifndef NO_MMX
+ Blenders::BLEND_MMX_END();
+#endif
+ // write bits back to dib.
+
+ if (usingBlitCanvas) {
+ blitToRectCanvas.blit(0, 0, &clone, destrect.left, destrect.top, cwidth, cheight);
+ }
+}
+
+#ifdef WIN32
+#pragma warning(pop)
+#endif
+
+void SkinBitmap::stretch(ifc_canvas *canvas, int x, int y, int w, int h) {
+ RECT src, dst;
+ src.left=0;
+ src.top=0;
+ src.right=getWidth();
+ src.bottom=getHeight();
+ dst.left=x;
+ dst.right=x+w;
+ dst.top=y;
+ dst.bottom=y+h;
+ stretchToRectAlpha(canvas,&src,&dst,255);
+}
+
+void SkinBitmap::stretchToRect(ifc_canvas *canvas, RECT *r) {
+ stretch(canvas, r->left, r->top, r->right - r->left, r->bottom - r->top);
+}
+
+void SkinBitmap::stretchRectToRect(ifc_canvas *canvas, RECT *src, RECT *dst) {
+ stretchToRectAlpha(canvas,src,dst,255);
+}
+
+
+void SkinBitmap::stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha) {
+ RECT re;
+ re.left=0; re.top=0;
+ re.right=getWidth(); re.bottom=getHeight();
+ stretchToRectAlpha(canvas,&re,r,alpha);
+}
+
+void SkinBitmap::blitAlpha(ifc_canvas *canvas, int x, int y, int alpha)
+{
+ RECT dst,src;
+ dst.left=x;
+ dst.top=y;
+ src.left=0;
+ src.top=0;
+ src.bottom=getHeight();
+ src.right=getWidth();
+ blitToRect(canvas,&src,&dst,alpha);
+}
+
+#ifdef WIN32
+#pragma warning(push)
+#pragma warning(disable : 4799)
+#endif
+
+template <class C>
+class Stretcher {
+public:
+ static void _stretchToRectAlpha(SkinBitmap *bitmap, int ys, int ye, int xe, int xs, int xstart, int yv, void *dib, int pitch, int dxv, int dyv, int alpha) {
+ int bitmap_x = bitmap->getX();
+ int bitmap_y = bitmap->getY();
+ int bmpheight = bitmap->getHeight();
+ int fullimage_w = bitmap->getFullWidth();
+ void *bits = bitmap->getBits();
+ int xp=xe-xs;
+ for (int yp = ys; yp < ye; yp ++) {
+ int t=yv>>16;
+ if (t < 0) t=0;
+ if (t >= bmpheight) t=bmpheight-1;
+ int *psrc=((int*)bits) + (t+bitmap_y)*fullimage_w + bitmap_x;
+ int *dest=((int*)dib) + pitch*yp + xs;
+
+ C::stretch(xp, psrc, dest, xstart, dxv, alpha);
+
+ yv+=dyv;
+ }
+ }
+};
+
+// no alpha, just stretch
+class Stretch {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+ while (xp--) { //JFtodo: assembly optimize - these first two modes aren't used that much anyway
+ *dest++ = psrc[xv>>16];
+ xv+=dxv;
+ }
+ }
+};
+
+// no alpha channel, just a global alpha val
+class StretchGlobal {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+ while (xp--) { //JFTODO: make MMX optimized version
+ *dest++ = Blenders::BLEND_ADJ1(psrc[xv>>16], *dest, alpha);
+ xv+=dxv;
+ }
+ }
+};
+
+// alpha channel, no global alpha val
+class StretchChannel {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+ while (xp--) {
+ *dest++ = Blenders::BLEND_ADJ2(*dest, psrc[xv>>16]);
+ xv+=dxv;
+ }
+ }
+};
+
+class StretchGlobalChannel {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+ while (xp--) {
+ *dest++ = Blenders::BLEND_ADJ3(*dest, psrc[xv>>16], alpha);
+ xv+=dxv;
+ }
+ }
+};
+
+
+#ifndef NO_MMX
+
+// no alpha channel, just a global alpha val
+class StretchGlobalMMX {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+ while (xp--) { //JFTODO: make MMX optimized version
+ *dest++ = Blenders::BLEND_ADJ1_MMX(psrc[xv>>16], *dest, alpha);
+ xv+=dxv;
+ }
+ }
+};
+
+
+// alpha channel, no global alpha val
+class StretchChannelMMX {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+#ifdef WIN32
+ if (xp>1) __asm
+ {
+ mov ecx, xp
+ mov edi, dest
+
+ shr ecx, 1
+ mov esi, psrc
+
+ mov edx, xv
+ mov ebx, dxv
+
+ align 16
+ _stretchAlpha_Loop2:
+
+ mov eax, edx
+ movd mm0, [edi]
+
+ movq mm4, [SkinBitmap_mmx_revn2]
+ shr eax, 16
+
+ movq mm2, [SkinBitmap_mmx_revn2]
+ punpcklbw mm0, [SkinBitmap_mmx_zero]
+
+ movd mm3, [esi+eax*4]
+ movd mm1, [esi+eax*4]
+
+ lea eax, [edx+ebx]
+ shr eax, 16
+
+ movd mm7, [edi+4]
+ psrld mm3, 24
+
+ packuswb mm3, mm3 // 0000HHVV
+ movd mm5, [esi+eax*4]
+
+ movd mm6, [esi+eax*4]
+ psrld mm5, 24
+
+ paddusw mm3, [SkinBitmap_mmx_one]
+ punpcklbw mm6, [SkinBitmap_mmx_zero]
+
+ packuswb mm5, mm5 // 0000HHVV
+ lea edx, [edx+ebx*2]
+
+ paddusw mm5, [SkinBitmap_mmx_one]
+ punpcklwd mm3, mm3 // HHVVHHVV
+
+ punpcklwd mm5, mm5 // HHVVHHVV
+ add edi, 8
+
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+
+ punpckldq mm5, mm5 // HHVVHHVV HHVVHHVV
+
+ psubw mm4, mm5
+
+ psubw mm2, mm3
+
+ punpcklbw mm7, [SkinBitmap_mmx_zero]
+ pmullw mm0, mm2
+
+ pmullw mm7, mm4
+ punpcklbw mm1, [SkinBitmap_mmx_zero]
+
+ psubw mm2, mm3
+
+ psrlw mm0, 8
+ psrlw mm7, 8
+ paddw mm0, mm1
+
+ paddw mm7, mm6
+ packuswb mm0, mm0
+
+ movd [edi-8], mm0
+ packuswb mm7, mm7
+
+ movd [edi-4], mm7
+
+ dec ecx
+ jnz _stretchAlpha_Loop2
+ mov dest, edi
+ mov xv, edx
+ }
+#else
+ if (xp>1)
+ {
+ __asm__ volatile (
+ "mov %5, %%ecx\n"
+ "mov %0, %%edi\n"
+ "shr $1, %%ecx\n"
+ "mov %1, %%esi\n"
+ "mov %2, %%edx\n"
+ "mov %7, %%ebx\n"
+ ".align 16\n"
+ "_stretchAlpha_Loop2:\n"
+ "mov %%edx, %%eax\n"
+ "movd (%%edi), %%mm0\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm4\n"
+ "shr $16, %%eax\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm2\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm0\n"
+ "movd (%%esi,%%eax,4), %%mm3\n"
+ "movd (%%esi,%%eax,4), %%mm1\n"
+ "lea (%%edx,%%ebx), %%eax\n"
+ "shr $16, %%eax\n"
+ "movd 4(%%edi), %%mm7\n"
+ "psrld $24, %%mm3\n"
+ "packuswb %%mm3, %%mm3\n"
+ "movd (%%esi,%%eax,4), %%mm5\n"
+ "movd (%%esi,%%eax,4), %%mm6\n"
+ "psrld $24, %%mm5\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm3\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm6\n"
+ "packuswb %%mm5, %%mm5\n"
+ "lea (%%edx,%%ebx,2), %%edx\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm5\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "punpcklwd %%mm5, %%mm5\n"
+ "add $8, %%edi\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "punpckldq %%mm5, %%mm5\n"
+ "psubw %%mm5, %%mm4\n"
+ "psubw %%mm3, %%mm2\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm7\n"
+ "pmullw %%mm2, %%mm0\n"
+ "pmullw %%mm4, %%mm7\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm1\n"
+ "psubw %%mm3, %%mm2\n"
+ "psrlw $8, %%mm0\n"
+ "psrlw $8, %%mm7\n"
+ "paddw %%mm1, %%mm0\n"
+ "paddw %%mm6, %%mm7\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, -8(%%edi)\n"
+ "packuswb %%mm7, %%mm7\n"
+ "movd %%mm7, -4(%%edi)\n"
+ "dec %%ecx\n"
+ "jnz _stretchAlpha_Loop2\n"
+ "mov %%edi, %0\n"
+ "mov %%edx, %2\n"
+
+ : "=m" (dest), "=m" (psrc), "=m" (xv)
+ : "0" (dest), "1" (psrc), "m" (xp),
+ "2" (xv), "m" (dxv), "m" (alpha)
+ : "%eax", "%ebx", "%ecx", "%edx",
+ "%esi", "%edi" );
+
+ }
+#endif
+
+ if (xp&1) *dest++ = Blenders::BLEND_ADJ2_MMX(*dest, psrc[xv>>16]);
+ }
+};
+
+
+class StretchGlobalChannelMMX {
+public:
+ static void stretch(int xp, int *psrc, int *dest, int xv, int dxv, int alpha) {
+#ifdef WIN32
+ if (xp>1) __asm
+ {
+ movd mm5, [alpha]
+ mov ecx, xp
+
+ packuswb mm5, mm5
+ shr ecx, 1
+
+ paddusw mm5, [SkinBitmap_mmx_one]
+
+ punpcklwd mm5, mm5
+ mov edi, dest
+
+ punpckldq mm5, mm5
+ mov esi, psrc
+
+ mov edx, xv
+ mov ebx, dxv
+
+ align 16
+ _stretchAlpha_Loop3:
+ movd mm0, [edi]
+ mov eax, edx
+
+ movd mm7, [edi+4]
+ shr eax, 16
+
+ movd mm1, [esi+eax*4]
+ movd mm3, [esi+eax*4] // VVVVVVVV
+
+ lea eax, [edx+ebx]
+ psrld mm3, 24
+
+ paddusw mm3, [SkinBitmap_mmx_one]
+
+ punpcklwd mm3, mm3
+ shr eax, 16
+
+ punpckldq mm3, mm3
+
+ pmullw mm3, mm5
+
+ movd mm4, [esi+eax*4] // VVVVVVVV
+ movd mm6, [esi+eax*4]
+
+ movq mm2, [SkinBitmap_mmx_revn2]
+ psrld mm4, 24
+
+ paddusw mm4, [SkinBitmap_mmx_one]
+ punpcklbw mm7, [SkinBitmap_mmx_zero]
+
+ punpcklwd mm4, mm4
+ lea edx, [edx+ebx*2]
+
+ punpckldq mm4, mm4
+ add edi, 8
+
+ punpcklbw mm6, [SkinBitmap_mmx_zero]
+ pmullw mm4, mm5
+
+ psrlw mm3, 8
+
+ punpcklbw mm0, [SkinBitmap_mmx_zero]
+
+ punpcklbw mm1, [SkinBitmap_mmx_zero]
+ psubw mm2, mm3
+
+ pmullw mm0, mm2
+ pmullw mm1, mm5
+
+ pmullw mm6, mm5
+ psrlw mm4, 8
+
+ movq mm2, [SkinBitmap_mmx_revn2]
+ paddusw mm0, mm1
+ psubw mm2, mm4
+
+ pmullw mm7, mm2
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+ paddusw mm7, mm6
+
+ movd [edi-8], mm0
+ psrlw mm7, 8
+
+ packuswb mm7, mm7
+
+ movd [edi-4], mm7
+
+ dec ecx
+ jnz _stretchAlpha_Loop3
+ mov xv, edx
+ mov dest, edi
+ }
+#else
+ if (xp>1)
+ {
+ __asm__ volatile (
+ "movd %8, %%mm5\n"
+ "mov %5, %%ecx\n"
+ "packuswb %%mm5, %%mm5 \n"
+ "shr $1, %%ecx\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm5\n"
+ "punpcklwd %%mm5, %%mm5\n"
+ "mov %0, %%edi\n"
+ "punpckldq %%mm5, %%mm5\n"
+ "mov %1, %%esi\n"
+ "mov %6, %%edx\n"
+ "mov %7, %%ebx\n"
+ ".align 16\n"
+ "_stretchAlpha_Loop3:\n"
+ "movd (%%edi), %%mm0\n"
+ "mov %%edx, %%eax\n"
+ "movd 4(%%edi), %%mm7\n"
+ "shr $16, %%eax\n"
+ "movd (%%esi,%%eax,4), %%mm1\n"
+ "movd (%%esi,%%eax,4), %%mm3\n"
+ "lea (%%edx,%%ebx), %%eax\n"
+ "psrld $24, %%mm3\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm3\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "shr $16, %%eax\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "pmullw %%mm5, %%mm3\n"
+ "movd (%%esi,%%eax,4), %%mm4\n"
+ "movd (%%esi,%%eax,4), %%mm6\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm2\n"
+ "psrld $24, %%mm4\n"
+ "paddusw (SkinBitmap_mmx_one), %%mm4\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm7\n"
+ "punpcklwd %%mm4, %%mm4\n"
+ "lea (%%edx,%%ebx,2), %%edx\n"
+ "punpckldq %%mm4, %%mm4\n"
+ "add $8, %%edi\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm6\n"
+ "pmullw %%mm5, %%mm4\n"
+ "psrlw $8, %%mm3\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm0\n"
+ "punpcklbw (SkinBitmap_mmx_zero), %%mm1\n"
+ "psubw %%mm3, %%mm2\n"
+ "pmullw %%mm2, %%mm0\n"
+ "pmullw %%mm5, %%mm1\n"
+ "pmullw %%mm5, %%mm6\n"
+ "psrlw $8, %%mm4\n"
+ "movq (SkinBitmap_mmx_revn2), %%mm2\n"
+ "paddusw %%mm1, %%mm0\n"
+ "psubw %%mm4, %%mm2\n"
+ "pmullw %%mm2, %%mm7\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "paddusw %%mm6, %%mm7\n"
+ "movd %%mm0, -8(%%edi)\n"
+ "psrlw $8, %%mm7\n"
+ "packuswb %%mm7, %%mm7\n"
+ "movd %%mm7, -4(%%edi)\n"
+ "dec %%ecx\n"
+ "jnz _stretchAlpha_Loop3\n"
+ "mov %%edi, %0\n"
+ "mov %%edx, %2\n"
+
+ : "=m" (dest), "=m" (psrc), "=m" (xv)
+ : "0" (dest), "1" (psrc), "m" (xp),
+ "m" (xv), "m" (dxv), "m" (alpha)
+ : "%eax", "%ebx", "%ecx", "%edx",
+ "%esi", "%edi" );
+
+ }
+#endif
+
+ if (xp&1) *dest++ = Blenders::BLEND_ADJ3_MMX(*dest, psrc[xv>>16], alpha);
+ }
+};
+#endif
+
+
+class __Stretch : public Stretcher<Stretch> {};
+class __StretchGlobal : public Stretcher<StretchGlobal> {};
+class __StretchChannel : public Stretcher<StretchChannel> {};
+class __StretchGlobalChannel : public Stretcher<StretchGlobalChannel> {};
+
+#ifndef NO_MMX
+class __StretchGlobalMMX : public Stretcher<StretchGlobalMMX> {};
+class __StretchChannelMMX : public Stretcher<StretchChannelMMX> {};
+class __StretchGlobalChannelMMX : public Stretcher<StretchGlobalChannelMMX> {};
+#endif
+
+#ifdef WIN32
+#pragma warning(pop)
+#endif
+
+
+void SkinBitmap::stretchToRectAlpha(ifc_canvas *canvas, RECT *_src, RECT *_dst, int alpha)
+{
+ if (alpha <= 0) return;
+ if (alpha > 255) alpha = 255;
+
+ RECT src=*_src;
+ RECT dst=*_dst;
+
+ if ((src.right-src.left) == (dst.right-dst.left) &&
+ (src.bottom-src.top) == (dst.bottom-dst.top))
+ {
+ blitToRect(canvas,_src,_dst,alpha);
+ return;
+ }
+ //FG> this is a hack, we should support subpixels instead
+ if (src.left == src.right) {
+ if (src.right < getWidth())
+ src.right++;
+ else
+ src.left--;
+ }
+ if (src.top== src.bottom) {
+ if (src.bottom < getHeight())
+ src.bottom++;
+ else
+ src.top--;
+ }
+
+ if (src.left >= src.right || src.top >= src.bottom) return;
+ if (dst.left >= dst.right || dst.top >= dst.bottom) return;
+
+ void *dib=canvas->getBits();
+ HDC hdc=canvas->getHDC();
+ bool usingBlitCanvas = false;
+ BaseCloneCanvas clone(canvas);
+ int cwidth, cheight, pitch;
+
+ int dyv=((src.bottom-src.top)<<16)/(dst.bottom-dst.top);
+ int dxv=((src.right-src.left)<<16)/(dst.right-dst.left);
+ int yv=(src.top<<16);
+ int xstart=(src.left<<16);
+
+ RECT c;
+ int ctype=canvas->getClipBox(&c);
+ if (c.top > dst.top)
+ {
+ yv+=(c.top-dst.top)*dyv;
+ dst.top=c.top;
+ }
+ if (c.left > dst.left)
+ {
+ xstart+=(c.left-dst.left)*dxv;
+ dst.left=c.left;
+ }
+ if (c.bottom < dst.bottom) dst.bottom=c.bottom;
+ if (c.right < dst.right) dst.right=c.right;
+
+ if (dst.right <= dst.left || dst.bottom <= dst.top) return;
+
+ int xs,xe,ys,ye;
+
+#ifdef NO_SIMPLEFASTMODE
+ dib=NULL;
+#endif
+ if (!dib || canvas->getDim(NULL,&cheight,&cwidth) || !cwidth || cheight < 1 || ctype == COMPLEXREGION)
+ {
+ cwidth=dst.right-dst.left;
+ cheight=dst.bottom-dst.top;
+ if (cwidth > cacheWidth || cheight > cacheHeight)
+ {
+ cacheWidth=MAX(cacheWidth, cwidth);
+ cacheHeight=MAX(cacheHeight, cheight);
+ blitToRectCanvas.DestructiveResize(cacheWidth, cacheHeight);
+ }
+
+ dib = blitToRectCanvas.getBits();
+ if ( has_alpha || alpha < 255 )
+ clone.blit( dst.left, dst.top, &blitToRectCanvas, 0, 0, cwidth, cheight );
+
+ xs=0;
+ ys=0;
+ xe=cwidth;
+ ye=cheight;
+ pitch=cacheWidth;
+ usingBlitCanvas=true;
+ }
+ else
+ {
+ xs=dst.left;
+ xe=dst.right;
+ ys=dst.top;
+ ye=dst.bottom;
+ cwidth/=4;
+ pitch=cwidth;
+ }
+
+ // stretch and blend bitmap to dib
+
+ if (xstart < 0) xstart=0;
+
+ if (xs<xe) {
+ if (!has_alpha) { // doesn't have alpha channel
+ if (alpha == 255) { // no global alpha
+ __Stretch::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ } else { // has global alpha
+#ifndef NO_MMX
+ if (HAS_MMX) {
+ __StretchGlobalMMX::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ } else
+#endif
+ {
+ __StretchGlobal::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ }
+ }
+ } else { // has alpha channel
+ // FUCKO: JF> BRENNAN FIX THESE BITCHES :)
+ if (alpha == 255) { // no global alpha
+#ifndef NO_MMX
+ if (HAS_MMX) {
+ __StretchChannelMMX::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ } else
+#endif
+ {
+ __StretchChannel::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ }
+ } else { // has global alpha
+#ifndef NO_MMX
+ if (HAS_MMX) {
+ __StretchGlobalChannelMMX::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ } else
+#endif
+ {
+ __StretchGlobalChannel::_stretchToRectAlpha(this, ys, ye, xe, xs, xstart, yv, dib, pitch, dxv, dyv, alpha);
+ }
+ }
+ }
+ }
+
+#ifndef NO_MMX
+ Blenders::BLEND_MMX_END();
+#endif
+ // write bits back to dib.
+
+ if (usingBlitCanvas) {
+ blitToRectCanvas.blit(0, 0, &clone, dst.left, dst.top, cwidth, cheight);
+ }
+}
+
+COLORREF SkinBitmap::getPixel(int x, int y) {
+ ASSERT(bits != NULL);
+ if (x < 0 || y < 0 || x >= getFullWidth()-getX() || y>= getFullHeight()-getY()) return (COLORREF)0;
+ return (COLORREF)(((int*)bits)[x+getX()+(y+getY())*getFullWidth()]);
+}
+
+void *SkinBitmap::getBits() {
+ return bits;
+}
+
+int SkinBitmap::isInvalid() {
+ return last_failed;
+}
+
+void SkinBitmap::setHasAlpha(int ha) {
+ has_alpha=ha;
+}
+
+const wchar_t *SkinBitmap::getBitmapName() {
+ return bitmapname;
+}
+
diff --git a/Src/Wasabi/api/wnd/bitmap.h b/Src/Wasabi/api/wnd/bitmap.h
new file mode 100644
index 00000000..742e8e37
--- /dev/null
+++ b/Src/Wasabi/api/wnd/bitmap.h
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+#include "platform/win32/bitmap.h"
+#elif defined(__APPLE__)
+#include "platform/osx/osx_bitmap_cgimage.h"
+#else
+#error port me
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/blending.cpp b/Src/Wasabi/api/wnd/blending.cpp
new file mode 100644
index 00000000..6bd19397
--- /dev/null
+++ b/Src/Wasabi/api/wnd/blending.cpp
@@ -0,0 +1,56 @@
+#include <precomp.h>
+#include "blending.h"
+#include <bfc/std.h>
+
+#if !defined(WIN32) && !defined(LINUX)
+#error port me!
+#endif
+
+class BlenderInit
+{
+public:
+ BlenderInit() { Blenders::init(); }
+};
+static BlenderInit blender_init;
+
+void Blenders::init()
+{
+ if (!alphatable[127][127])
+ {
+ int i, j;
+ for (j = 0;j < 256;j++)
+ for (i = 0;i < 256;i++)
+ alphatable[i][j] = (i * (j + 1)) >> 8;
+#ifndef NO_MMX
+ DWORD retval1, retval2;
+#ifdef WIN32
+ __try {
+ _asm {
+ mov eax, 1 // set up CPUID to return processor version and features
+ // 0 = vendor string, 1 = version info, 2 = cache info
+ _emit 0x0f // code bytes = 0fh, 0a2h
+ _emit 0xa2
+ mov retval1, eax
+ mov retval2, edx
+ }
+ } __except(EXCEPTION_EXECUTE_HANDLER) { retval1 = retval2 = 0;}
+#else
+ __asm__ volatile ( "movl $1, %%eax\n"
+ ".byte 15, 162\n"
+ "movl %%eax, %0\n"
+ "movl %%edx, %1\n"
+ : "=m" (retval1), "=m" (retval2)
+ : // No inputs...
+ : "%eax", "%edx" );
+#endif
+ mmx_available = retval1 && (retval2 & 0x800000);
+#endif //ndef NO_MMX
+
+ }
+}
+
+#ifndef NO_MMX
+int Blenders::mmx_available = 0;
+#endif
+
+unsigned char Blenders::alphatable[256][256];
diff --git a/Src/Wasabi/api/wnd/blending.h b/Src/Wasabi/api/wnd/blending.h
new file mode 100644
index 00000000..c7148c5b
--- /dev/null
+++ b/Src/Wasabi/api/wnd/blending.h
@@ -0,0 +1,536 @@
+#ifndef _BLENDING_H_
+#define _BLENDING_H_
+
+//#include <bfc/common.h>
+#include <bfc/platform/types.h>
+class Blenders
+{
+public:
+ static void init();
+ static unsigned int inline BLEND_ADJ1(unsigned int a, unsigned int b, int alpha);
+ static unsigned int inline BLEND_ADJ2(unsigned int a, unsigned int b);
+ static unsigned int inline BLEND_ADJ3(unsigned int a, unsigned int b, int alpha);
+ static unsigned int inline BLEND_MUL(unsigned int a, int v);
+ static unsigned int inline BLEND_AVG(unsigned int a, unsigned int b);
+ static unsigned int inline BLEND4(unsigned int *p1, unsigned int w, int xp, int yp);
+
+#ifndef NO_MMX
+ static int inline MMX_AVAILABLE() { return mmx_available; }
+ static unsigned int inline BLEND_ADJ1_MMX(unsigned int a, unsigned int b, int alpha);
+ static unsigned int inline BLEND_ADJ2_MMX(unsigned int a, unsigned int b);
+ static unsigned int inline BLEND_ADJ3_MMX(unsigned int a, unsigned int b, int alpha);
+ static unsigned int inline BLEND_MUL_MMX(unsigned int a, int v);
+ static unsigned int inline BLEND_AVG_MMX(unsigned int a, unsigned int b);
+ static unsigned int inline BLEND4_MMX(unsigned int *p1, unsigned int w, int xp, int yp);
+ static void inline BLEND_MMX_END()
+ {
+#ifdef WIN32
+ if (mmx_available) __asm emms;
+#endif
+#ifdef LINUX
+if (mmx_available) __asm__ volatile ( "emms" : : );
+#endif
+
+ }
+#endif
+
+//private:
+ static uint8_t alphatable[256][256];
+#ifndef NO_MMX
+ static int mmx_available;
+#endif
+};
+
+
+// NON MMX
+
+// average blend of a and b.
+unsigned int inline Blenders::BLEND_AVG(unsigned int a, unsigned int b)
+{
+ return ((a >> 1)&~((1 << 7) | (1 << 15) | (1 << 23))) + ((b >> 1)&~((1 << 7) | (1 << 15) | (1 << 23)));
+}
+
+
+// multiplies 32 bit color A by scalar V (0-255)
+unsigned int inline Blenders::BLEND_MUL(unsigned int a, int v)
+{
+ register int t;
+ t = Blenders::alphatable[a & 0xFF][v];
+ t |= Blenders::alphatable[(a & 0xFF00) >> 8][v] << 8;
+ t |= Blenders::alphatable[(a & 0xFF0000) >> 16][v] << 16;
+ t |= Blenders::alphatable[(a & 0xFF000000) >> 24][v] << 24;
+ return t;
+}
+
+
+// V is scalar (0-255), (1.0-V)*b + V*a
+unsigned int inline Blenders::BLEND_ADJ1(unsigned int a, unsigned int b, int v)
+{
+ register int t;
+ t = Blenders::alphatable[b & 0xFF][0xFF - v] + Blenders::alphatable[a & 0xFF][v];
+ t |= (Blenders::alphatable[(b & 0xFF00) >> 8][0xFF - v] + Blenders::alphatable[(a & 0xFF00) >> 8][v]) << 8;
+ t |= (Blenders::alphatable[(b & 0xFF0000) >> 16][0xFF - v] + Blenders::alphatable[(a & 0xFF0000) >> 16][v]) << 16;
+ t |= (Blenders::alphatable[(b & 0xFF000000) >> 24][0xFF - v] + Blenders::alphatable[(a & 0xFF000000) >> 24][v]) << 24;
+ return t;
+}
+
+// returns a*(1.0-Alpha(b)) + b
+unsigned int inline Blenders::BLEND_ADJ2(unsigned int a, unsigned int b)
+{
+ register int t, z;
+ int v = 0xff - ((b >> 24) & 0xff);
+ t = Blenders::alphatable[a & 0xFF][v] + (b & 0xFF);
+ if (t > 0xFF) t = 0xff;
+ z = (Blenders::alphatable[(a & 0xFF00) >> 8][v] << 8) + (b & 0xFF00);
+ if (z > 0xFF00) z = 0xff00;
+ t |= z;
+ z = (Blenders::alphatable[(a & 0xFF0000) >> 16][v] << 16) + ((b & 0xFF0000));
+ if (z > 0xFF0000) z = 0xff0000;
+ t |= z;
+ z = (Blenders::alphatable[(a & 0xFF000000) >> 24][v]) + ((b & 0xFF000000) >> 24);
+ if (z > 0xFF) z = 0xff;
+ return t | (z << 24);
+}
+
+// returns a*(1-Alpha(b)*W) + b*W, clamped (W is scalar 0-0xff).
+unsigned int inline Blenders::BLEND_ADJ3(unsigned int a, unsigned int b, int w)
+{
+ register int t, z;
+ int v = 0xff - Blenders::alphatable[(b >> 24) & 0xff][w];
+
+ t = Blenders::alphatable[a & 0xFF][v] + Blenders::alphatable[b & 0xFF][w];
+ if (t > 0xFF) t = 0xFF;
+ z = Blenders::alphatable[(a & 0xFF00) >> 8][v] + Blenders::alphatable[(b & 0xFF00) >> 8][w];
+ if (z > 0xFF) z = 0xFF;
+ t |= z << 8;
+ z = Blenders::alphatable[(a & 0xFF0000) >> 16][v] + Blenders::alphatable[(b & 0xFF0000) >> 16][w];
+ if (z > 0xFF) z = 0xFF;
+ t |= z << 16;
+ z = Blenders::alphatable[(a & 0xFF000000) >> 24][v] + Blenders::alphatable[(b & 0xFF000000) >> 24][w];
+ if (z > 0xFF) z = 0xFF;
+ return t | (z << 24);
+}
+
+unsigned int __inline Blenders::BLEND4(unsigned int *p1, unsigned int w, int xp, int yp)
+{
+ register int t;
+ uint8_t a1, a2, a3, a4;
+ xp = (xp >> 8) & 0xff;
+ yp = (yp >> 8) & 0xff;
+ a1 = alphatable[255 - xp][255 - yp];
+ a2 = alphatable[xp][255 - yp];
+ a3 = alphatable[255 - xp][yp];
+ a4 = alphatable[xp][yp];
+ t = alphatable[p1[0] & 0xff][a1] + alphatable[p1[1] & 0xff][a2] + alphatable[p1[w] & 0xff][a3] + alphatable[p1[w + 1] & 0xff][a4];
+ t |= (alphatable[(p1[0] >> 8) & 0xff][a1] + alphatable[(p1[1] >> 8) & 0xff][a2] + alphatable[(p1[w] >> 8) & 0xff][a3] + alphatable[(p1[w + 1] >> 8) & 0xff][a4]) << 8;
+ t |= (alphatable[(p1[0] >> 16) & 0xff][a1] + alphatable[(p1[1] >> 16) & 0xff][a2] + alphatable[(p1[w] >> 16) & 0xff][a3] + alphatable[(p1[w + 1] >> 16) & 0xff][a4]) << 16;
+ t |= (alphatable[(p1[0] >> 24) & 0xff][a1] + alphatable[(p1[1] >> 24) & 0xff][a2] + alphatable[(p1[w] >> 24) & 0xff][a3] + alphatable[(p1[w + 1] >> 24) & 0xff][a4]) << 24;
+ return t;
+}
+
+
+
+
+#ifndef NO_MMX
+
+
+#ifdef WIN32
+#pragma warning( push, 1 )
+#pragma warning(disable: 4799)
+#endif
+
+#ifdef WIN32
+#define MMX_CONST const
+#else
+#define MMX_CONST
+#endif
+
+static unsigned int MMX_CONST Blenders__mmx_revn2[2] = {0x01000100, 0x01000100};
+static unsigned int MMX_CONST Blenders__mmx_zero[2];
+static unsigned int MMX_CONST Blenders__mmx_one[2] = {1, 0};
+
+#undef MMX_CONST
+
+/// MMX
+
+// average blend of a and b.
+unsigned int inline Blenders::BLEND_AVG_MMX(unsigned int a, unsigned int b)
+{
+ return ((a >> 1)&~((1 << 7) | (1 << 15) | (1 << 23))) + ((b >> 1)&~((1 << 7) | (1 << 15) | (1 << 23)));
+}
+
+// multiplies 32 bit color A by scalar V (0-255)
+unsigned int inline Blenders::BLEND_MUL_MMX(unsigned int a, int v)
+{
+#ifdef WIN32
+ __asm
+ {
+ movd mm3, [v] // VVVVVVVV
+
+ movd mm0, [a]
+ packuswb mm3, mm3 // 0000HHVV
+
+ punpcklbw mm0, [Blenders__mmx_zero]
+ punpcklwd mm3, mm3 // HHVVHHVV
+
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+
+ pmullw mm0, mm3
+
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+
+ movd eax, mm0
+ }
+#else
+ __asm__ volatile (
+ "movd %0, %%mm3\n"
+ "movd %1, %%mm0\n"
+ "packuswb %%mm3, %%mm3\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm0\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "pmullw %%mm3, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, %%eax\n"
+ :
+ : "m" (v), "m" (a)
+ : "%mm0", "%mm3" );
+#endif
+}
+
+
+// V is scalar (0-255), (1.0-V)*b + V*a
+unsigned int inline Blenders::BLEND_ADJ1_MMX(unsigned int a, unsigned int b, int v)
+{
+#ifdef WIN32
+ __asm
+ {
+ movd mm3, [v] // VVVVVVVV
+
+ movd mm0, [a]
+ packuswb mm3, mm3 // 0000HHVV
+
+ movd mm1, [b]
+ paddusw mm3, [Blenders__mmx_one]
+
+ movq mm4, [Blenders__mmx_revn2]
+ punpcklwd mm3, mm3 // HHVVHHVV
+
+ punpcklbw mm0, [Blenders__mmx_zero]
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+
+ punpcklbw mm1, [Blenders__mmx_zero]
+ psubw mm4, mm3
+
+ pmullw mm0, mm3
+ pmullw mm1, mm4
+
+ paddw mm0, mm1
+
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+
+ movd eax, mm0
+ }
+#else
+ __asm__ volatile (
+ "movd %0, %%mm3\n"
+ "movd %1, %%mm0\n"
+ "packuswb %%mm3, %%mm3\n"
+ "movd %2, %%mm1\n"
+ "paddusw (Blenders__mmx_one), %%mm3\n"
+ "movq (Blenders__mmx_revn2), %%mm4\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm0\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm1\n"
+ "psubw %%mm3, %%mm4\n"
+ "pmullw %%mm3, %%mm0\n"
+ "pmullw %%mm4, %%mm1\n"
+ "paddw %%mm1, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, %%eax\n"
+ :
+ : "m" (v), "m" (a), "m" (b)
+ : "%mm0", "%mm1", "%mm3", "%mm4" );
+#endif
+}
+
+// returns a*(1.0-Alpha(b)) + b
+unsigned int inline Blenders::BLEND_ADJ2_MMX(unsigned int a, unsigned int b)
+{
+#ifdef WIN32
+ __asm
+ {
+ movd mm3, [b] // VVVVVVVV
+ movq mm4, [Blenders__mmx_revn2]
+
+ movd mm0, [a]
+ psrld mm3, 24
+
+ movd mm1, [b]
+ paddusw mm3, [Blenders__mmx_one]
+
+ punpcklwd mm3, mm3 // HHVVHHVV
+ punpcklbw mm0, [Blenders__mmx_zero]
+
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+ punpcklbw mm1, [Blenders__mmx_zero]
+
+ psubw mm4, mm3
+
+ pmullw mm0, mm4
+ // stall
+
+ // stall
+
+ // stall
+
+ psrlw mm0, 8
+ // stall
+
+ paddw mm0, mm1
+ // stall
+
+ packuswb mm0, mm0
+ // stall
+
+ movd eax, mm0
+ }
+#else
+ __asm__ volatile (
+ "movd %1, %%mm3\n"
+ "movq (Blenders__mmx_revn2), %%mm4\n"
+ "movd %0, %%mm0\n"
+ "psrld $24, %%mm3\n"
+ "movd %1, %%mm1\n"
+ "paddusw (Blenders__mmx_one), %%mm3\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm0\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm1\n"
+ "psubw %%mm3, %%mm4\n"
+ "pmullw %%mm4, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "paddw %%mm1, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, %%eax\n"
+ :
+ : "m" (a), "m" (b)
+ : "%esi", "%mm0", "%mm1", "%mm3", "%mm4" );
+#endif
+}
+
+// returns a*(1-Alpha(b)*W) + b*W, clamped (W is scalar 0-0xff).
+unsigned int inline Blenders::BLEND_ADJ3_MMX(unsigned int a, unsigned int b, int w)
+{
+#ifdef WIN32
+ __asm
+ {
+ movd mm3, [b] // VVVVVVVV
+ movd mm5, [w]
+
+ movd mm0, [a]
+ psrld mm3, 24
+
+ movd mm1, [b]
+ paddusw mm3, [Blenders__mmx_one]
+
+ movq mm4, [Blenders__mmx_revn2]
+ pmullw mm3, mm5
+
+ packuswb mm5, mm5
+ punpcklbw mm0, [Blenders__mmx_zero]
+
+ punpcklwd mm5, mm5
+ punpcklbw mm1, [Blenders__mmx_zero]
+
+ psrlw mm3, 8
+ punpckldq mm5, mm5
+
+ paddusw mm3, [Blenders__mmx_one]
+
+ punpcklwd mm3, mm3 // HHVVHHVV
+
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+
+
+ psubw mm4, mm3
+
+ pmullw mm0, mm4
+ pmullw mm1, mm5
+
+ paddusw mm0, mm1
+
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+
+ movd eax, mm0
+ }
+#else
+ __asm__ volatile (
+ "movd %2, %%mm3\n"
+ "movd %0, %%mm5\n"
+ "movd %1, %%mm0\n"
+ "psrld $24, %%mm3\n"
+ "movd %2, %%mm1\n"
+ "paddusw (Blenders__mmx_one), %%mm3\n"
+ "movq (Blenders__mmx_revn2), %%mm4\n"
+ "pmullw %%mm5, %%mm3\n"
+ "packuswb %%mm5, %%mm5 \n"
+ "punpcklbw (Blenders__mmx_zero), %%mm0\n"
+ "punpcklwd %%mm5, %%mm5\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm1\n"
+ "psrlw $8, %%mm3\n"
+ "punpckldq %%mm5, %%mm5\n"
+ "paddusw (Blenders__mmx_one), %%mm3\n"
+ "punpcklwd %%mm3, %%mm3\n"
+ "punpckldq %%mm3, %%mm3\n"
+ "psubw %%mm3, %%mm4\n"
+ "pmullw %%mm4, %%mm0\n"
+ "pmullw %%mm5, %%mm1\n"
+ "paddusw %%mm1, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, %%eax\n"
+
+ :
+ : "m" (w), "m" (a), "m" (b)
+ : "%mm0", "%mm1", "%mm4", "%mm3", "%mm5" );
+#endif
+}
+
+// does bilinear filtering. p1 is upper left pixel, w is width of framebuffer
+// xp and yp's low 16 bits are used for the subpixel positioning.
+unsigned int inline Blenders::BLEND4_MMX(unsigned int *p1, unsigned int w, int xp, int yp)
+{
+#ifdef WIN32
+ __asm
+ {
+ movd mm6, xp
+ mov eax, p1
+
+ movd mm7, yp
+ mov esi, w
+
+ movq mm4, Blenders__mmx_revn2
+ psrlw mm6, 8
+
+ movq mm5, Blenders__mmx_revn2
+ psrlw mm7, 8
+
+ movd mm0, [eax]
+ punpcklwd mm6, mm6
+
+ movd mm1, [eax + 4]
+ punpcklwd mm7, mm7
+
+ movd mm2, [eax + esi*4]
+ punpckldq mm6, mm6
+
+ movd mm3, [eax + esi*4 + 4]
+ punpckldq mm7, mm7
+
+ punpcklbw mm0, [Blenders__mmx_zero]
+ psubw mm4, mm6
+
+ punpcklbw mm1, [Blenders__mmx_zero]
+ pmullw mm0, mm4
+
+ punpcklbw mm2, [Blenders__mmx_zero]
+ pmullw mm1, mm6
+
+ punpcklbw mm3, [Blenders__mmx_zero]
+ psubw mm5, mm7
+
+ pmullw mm2, mm4
+ pmullw mm3, mm6
+
+ paddw mm0, mm1
+ // stall (mm0)
+
+ psrlw mm0, 8
+ // stall (waiting for mm3/mm2)
+
+ paddw mm2, mm3
+ pmullw mm0, mm5
+
+ psrlw mm2, 8
+ // stall (mm2)
+
+ pmullw mm2, mm7
+ // stall
+
+ // stall (mm2)
+
+ paddw mm0, mm2
+ // stall
+
+ psrlw mm0, 8
+ // stall
+
+ packuswb mm0, mm0
+ // stall
+
+ movd eax, mm0
+ }
+#else
+ __asm__ volatile (
+ "movd %2, %%mm6\n"
+ "mov %0, %%eax\n"
+ "movd %3, %%mm7\n"
+ "mov %1, %%esi\n"
+ "movq (Blenders__mmx_revn2), %%mm4\n"
+ "psrlw $8, %%mm6\n"
+ "movq (Blenders__mmx_revn2), %%mm5\n"
+ "psrlw $8, %%mm7\n"
+ "movd (%%eax), %%mm0\n"
+ "punpcklwd %%mm6,%%mm6\n"
+ "movd 4(%%eax), %%mm1\n"
+ "punpcklwd %%mm7,%%mm7\n"
+ "movd (%%eax,%%esi,4), %%mm2\n"
+ "punpckldq %%mm6,%%mm6\n"
+ "movd 4(%%eax,%%esi,4), %%mm3\n"
+ "punpckldq %%mm7,%%mm7\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm0\n"
+ "psubw %%mm6, %%mm4\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm1\n"
+ "pmullw %%mm4, %%mm0\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm2\n"
+ "pmullw %%mm6, %%mm1\n"
+ "punpcklbw (Blenders__mmx_zero), %%mm3\n"
+ "psubw %%mm7, %%mm5\n"
+ "pmullw %%mm4, %%mm2\n"
+ "pmullw %%mm6, %%mm3\n"
+ "paddw %%mm1, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "paddw %%mm3, %%mm2\n"
+ "pmullw %%mm5, %%mm0\n"
+ "psrlw $8, %%mm2\n"
+ "pmullw %%mm7, %%mm2\n"
+ "paddw %%mm2, %%mm0\n"
+ "psrlw $8, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "movd %%mm0, %%eax\n"
+
+ :
+ : "m" (p1), "m" (w), "m" (xp), "m" (yp)
+ : "%mm0", "%mm1", "%mm4", "%mm3", "%mm5" );
+
+#endif
+}
+
+#ifdef WIN32
+#pragma warning( pop )
+#endif
+
+#endif // ndef NO_MMX
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/bltcanvas.h b/Src/Wasabi/api/wnd/bltcanvas.h
new file mode 100644
index 00000000..ee1343ac
--- /dev/null
+++ b/Src/Wasabi/api/wnd/bltcanvas.h
@@ -0,0 +1,5 @@
+#ifdef _WIN32
+#include <api/wnd/platform/win32/bltcanvas.h>
+#elif defined(__APPLE__)
+#include <api/wnd/platform/osx/bltcanvas.h>
+#endif
diff --git a/Src/Wasabi/api/wnd/bucketitem.h b/Src/Wasabi/api/wnd/bucketitem.h
new file mode 100644
index 00000000..4f0455d1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/bucketitem.h
@@ -0,0 +1,76 @@
+#ifndef __BUCKETITEM_H
+#define __BUCKETITEM_H
+
+#include <bfc/common.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <bfc/depend.h>
+#include <api/wnd/notifmsg.h>
+
+template <class T> class BucketItemT : public T {
+ public:
+ BucketItemT(GUID g=INVALID_GUID, const wchar_t *text=NULL) : guid_target(g), target_txt(text) {
+ setBorders(0);
+ setHInstanceColorGroup(L"Thinger icons");
+ }
+
+ virtual ~BucketItemT() {
+ }
+
+ virtual void setBucketText(const wchar_t *txt) {
+ notifyParent(ChildNotify::COMPONENTBUCKET_SETTEXT, reinterpret_cast<intptr_t>(txt), 0);
+ }
+ virtual void onLeftPush(int x, int y) {
+ T::onLeftPush(x, y);
+ if (guid_target != INVALID_GUID) {
+ RECT r;
+ getClientRect(&r);
+ clientToScreen(&r);
+ int newstatus = WASABI_API_WNDMGR->skinwnd_toggleByGuid(guid_target);
+ setActivatedButton(newstatus);
+ }
+ }
+
+ virtual int onShowWindow(GUID g, const wchar_t *groupid) {
+ if (g == guid_target) setActivatedButton(1);
+ return 1;
+ }
+
+ virtual int onHideWindow(GUID g, const wchar_t *groupid) {
+ if (g == guid_target) setActivatedButton(0);
+ return 1;
+ }
+
+ virtual void onEnterArea() {
+ T::onEnterArea();
+ if (!target_txt.isempty()) setBucketText(target_txt);
+ }
+
+ virtual void onLeaveArea() {
+ T::onLeaveArea();
+ if (!target_txt.isempty()) setBucketText(NULL);
+ }
+
+ void setAutoOpen(GUID g) {
+ guid_target = g;
+ }
+
+ void setAutoText(const wchar_t *txt) {
+ target_txt = txt;
+ }
+
+ private:
+ GUID guid_target;
+ StringW target_txt;
+};
+
+#define BUCKETITEM_PARENT ButtonWnd
+class BucketItem : public BucketItemT<BUCKETITEM_PARENT> {
+ public:
+ BucketItem(GUID g=INVALID_GUID, const wchar_t *text=NULL) : BucketItemT<ButtonWnd> (g, text) {}
+ virtual ~BucketItem() {}
+};
+
+
+#endif // __BUCKETITEM_H
+
diff --git a/Src/Wasabi/api/wnd/canvas.cpp b/Src/Wasabi/api/wnd/canvas.cpp
new file mode 100644
index 00000000..d7123dfa
--- /dev/null
+++ b/Src/Wasabi/api/wnd/canvas.cpp
@@ -0,0 +1,3 @@
+#include "precomp.h"
+
+#error moved to platform/win32!
diff --git a/Src/Wasabi/api/wnd/canvas.h b/Src/Wasabi/api/wnd/canvas.h
new file mode 100644
index 00000000..50e7d8c6
--- /dev/null
+++ b/Src/Wasabi/api/wnd/canvas.h
@@ -0,0 +1,5 @@
+#ifdef _WIN32
+#include <api/wnd/platform/win32/canvas.h>
+#elif defined(__APPLE__)
+#include <api/wnd/platform/osx/canvas.h>
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/contextmenu.cpp b/Src/Wasabi/api/wnd/contextmenu.cpp
new file mode 100644
index 00000000..25a17aeb
--- /dev/null
+++ b/Src/Wasabi/api/wnd/contextmenu.cpp
@@ -0,0 +1,170 @@
+#include <precomp.h>
+
+#include "contextmenu.h"
+#include <api/service/svcs/svc_contextcmd.h>
+#include <bfc/string/StringW.h>
+
+#define DD_CONTEXTMENUENTRY "ContextMenuEntry v1"
+
+class ContextMenuEntry
+{
+public:
+ ContextMenuEntry(DragItem *_item, svc_contextCmd *_svc, int _pos, const wchar_t *txt, int _sortval, int _addorder) :
+ svc(_svc), item(_item), pos(_pos), text(txt), sortval(_sortval), addorder(_addorder) { }
+
+ svc_contextCmd *svc;
+ DragItem *item;
+ int pos;
+ StringW text, submenu_text;
+ int sortval;
+ int addorder;
+};
+
+class ContextMenuEntryCompare
+{
+public:
+ static int compareItem(void *p1, void* p2)
+ {
+ ContextMenuEntry *e1 = static_cast<ContextMenuEntry*>(p1);
+ ContextMenuEntry *e2 = static_cast<ContextMenuEntry*>(p2);
+ int ret = CMP3(e1->sortval, e2->sortval);
+ if (ret == 0) ret = CMP3(e1->addorder, e2->addorder);
+ return ret;
+ }
+};
+
+ContextMenu::ContextMenu(ifc_window *sourceWnd, DragItem *_item, bool autopop, const wchar_t *_menu_path)
+ : PopupMenu(sourceWnd), item(_item), menu_path(_menu_path)
+{
+ populate();
+ if (autopop) popAtMouse();
+}
+
+ContextMenu::ContextMenu(ifc_window *sourceWnd, int x, int y, DragItem *_item, bool autopop, const wchar_t *_menu_path)
+ : PopupMenu(sourceWnd), item(_item), menu_path(_menu_path)
+{
+ populate();
+ if (autopop) popAtXY(x, y);
+}
+
+ContextMenu::ContextMenu(DragItem *_item, const wchar_t *_menu_path)
+ : item(_item), menu_path(_menu_path)
+{
+ populate();
+}
+
+ContextMenu::~ContextMenu()
+{
+ entries.deleteAll();
+
+ // release all services
+ for (int i = 0; i < svclist.getNumItems(); i++)
+ SvcEnum::release(svclist.enumItem(i));
+}
+
+void ContextMenu::addDragItem(DragItem *_item, const wchar_t *_menu_path)
+{
+ menu_path = _menu_path;
+ item = _item;
+ populate();
+}
+
+void ContextMenu::populate()
+{
+ if (item == NULL) return ;
+
+ ContextCmdEnum cce(item, menu_path);
+ svc_contextCmd *svc;
+ int i, j, addorder = 0;
+
+ // make a list of all context cmd services that match the menu path
+ for (i = 0; (svc = cce.getNext()) != NULL; i++)
+ {
+ for (j = 0; ; j++)
+ {
+ const wchar_t *text = svc->getCommand(item, j);
+ if (text == NULL) break;
+ if (!wcscmp(text, L"~~~SEP~~~")) text = NULL; // sorry, magic value
+ ContextMenuEntry *entry = new ContextMenuEntry(item, svc, j, text, svc->getSortVal(item, j), addorder++);
+ entries.addItem(entry);
+ }
+ // save the service * to release later
+ svclist.addItem(svc);
+ }
+
+ // sorting is implicit but just making sure
+ entries.sort();
+
+ PtrList<StringW> submenu_list;
+
+#ifdef WASABI_COMPILE_COMPONENTS
+ GUID prev = INVALID_GUID;
+#endif
+ // populate the menu from the list
+ int n = entries.getNumItems();
+ for (i = 0; i < n; i++)
+ {
+ ContextMenuEntry *entry = entries.enumItem(i);
+ if (entry->text.isempty())
+ {
+ addSeparator();
+ }
+ else
+ {
+ svc_contextCmd *svc = entry->svc;
+#ifdef WASABI_COMPILE_COMPONENTS
+ GUID g = WASABI_API_SVC->service_getOwningComponent(svc);
+ if (g != prev && prev != INVALID_GUID && i < n - 1)
+ addSeparator();
+ prev = g;
+#endif
+ if (!svc->getSubMenu(item, menu_path))
+ {
+ int checked = entry->svc->getChecked(item, entry->pos);
+ int enabled = entry->svc->getEnabled(item, entry->pos);
+ addCommand(entry->text, reinterpret_cast<intptr_t>(entry), checked, !enabled);
+ }
+ else
+ {
+ entry->submenu_text = svc->getSubMenuText(menu_path);
+ if (!entry->submenu_text.isempty())
+ {
+ for (j = 0; j < submenu_list.getNumItems(); j++)
+ if (!WCSICMP(*submenu_list[j], entry->submenu_text)) break;
+ if (j >= submenu_list.getNumItems())
+ {
+ submenu_list.addItem(new StringW(entry->submenu_text));
+ addSubMenuCallback(entry->submenu_text, this, reinterpret_cast<intptr_t>(entry));
+ }
+ }
+ }
+ }
+ }
+ submenu_list.deleteAll();
+}
+
+void ContextMenu::onPostPop(intptr_t result)
+{
+ //if (result == -1 || result == -2 || result == -3) return; //FUCKO need real enums
+ if (result < 0) return ;
+ ASSERT(result != 0xcccccccc);
+ ContextMenuEntry *entry = reinterpret_cast<ContextMenuEntry*>(result);
+ if (entry == NULL) return ;
+ entry->svc->onCommand(entry->item, entry->pos);
+}
+
+PopupMenu *ContextMenu::popupMenuCallback(PopupMenu *parent, intptr_t param)
+{
+ ContextMenuEntry *entry = reinterpret_cast<ContextMenuEntry*>(param);
+ StringW path = menu_path;
+ if (!path.isempty())
+ path.cat(L"/");
+ path.cat(entry->submenu_text);
+ ContextMenu *ret = new ContextMenu(entry->item, path);
+ if (ret->getNumCommands() <= 0)
+ {
+ delete ret;
+ ret = NULL;
+ }
+ return ret;
+}
diff --git a/Src/Wasabi/api/wnd/contextmenu.h b/Src/Wasabi/api/wnd/contextmenu.h
new file mode 100644
index 00000000..61d32b91
--- /dev/null
+++ b/Src/Wasabi/api/wnd/contextmenu.h
@@ -0,0 +1,42 @@
+#ifndef _CONTEXTMENU_H
+#define _CONTEXTMENU_H
+
+#include <api/wnd/popup.h>
+#include <bfc/common.h>
+
+class DragItem;
+class ContextMenuEntry;
+class ContextMenuEntryCompare;
+class svc_contextCmd;
+
+class ContextMenu : private PopupMenu, private PopupMenuCallback
+{
+public:
+ ContextMenu(ifc_window *sourceWnd, DragItem *item, bool autopop=TRUE, const wchar_t *menu_path=NULL);
+ ContextMenu(ifc_window *sourceWnd, int x, int y, DragItem *item, bool autopop=TRUE, const wchar_t *menu_path=NULL);
+ virtual ~ContextMenu();
+
+ void addDragItem(DragItem *item, const wchar_t *menu_path=NULL);
+
+ using PopupMenu::popAtXY;
+ using PopupMenu::popAtMouse;
+ using PopupMenu::addCommand;
+ using PopupMenu::addSeparator;
+ using PopupMenu::getNumCommands;
+
+protected:
+ ContextMenu(DragItem *item, const wchar_t *menu_path);
+
+private:
+ virtual void onPostPop(intptr_t result);
+
+ void populate();
+ virtual PopupMenu *popupMenuCallback(PopupMenu *parent, intptr_t param);
+
+ DragItem *item;
+ StringW menu_path;
+ PtrList<svc_contextCmd> svclist;
+ PtrListQuickSorted<ContextMenuEntry, ContextMenuEntryCompare> entries;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/cursor.cpp b/Src/Wasabi/api/wnd/cursor.cpp
new file mode 100644
index 00000000..6e9618fc
--- /dev/null
+++ b/Src/Wasabi/api/wnd/cursor.cpp
@@ -0,0 +1,48 @@
+#include <precomp.h>
+
+#include "cursor.h"
+
+#define CBCLASS CursorI
+START_DISPATCH;
+ CB(CURSOR_GETOSHANDLE, getOSHandle);
+END_DISPATCH;
+
+#ifdef WASABI_COMPILE_SKIN
+
+SkinCursor::SkinCursor(const wchar_t *elementid) {
+ name = elementid;
+ cursor = NULL;
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI *>(this));
+}
+
+SkinCursor::SkinCursor() {
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI *>(this));
+ cursor = NULL;
+}
+
+SkinCursor::~SkinCursor() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI *>(this));
+}
+
+OSCURSORHANDLE SkinCursor::getOSHandle() {
+ if (cursor == NULL && !name.isempty()) {
+ cursor = WASABI_API_SKIN->cursor_request(name);
+ }
+ return cursor;
+}
+
+int SkinCursor::skincb_onReset() {
+ reset();
+ return 1;
+}
+
+void SkinCursor::reset() {
+ cursor = NULL;
+}
+
+void SkinCursor::setCursorElementId(const wchar_t *id) {
+ name = id;
+ reset();
+}
+
+#endif
diff --git a/Src/Wasabi/api/wnd/cursor.h b/Src/Wasabi/api/wnd/cursor.h
new file mode 100644
index 00000000..cd5d5ef2
--- /dev/null
+++ b/Src/Wasabi/api/wnd/cursor.h
@@ -0,0 +1,62 @@
+#ifndef __CURSOR_H
+#define __CURSOR_H
+#ifdef _WIN32 // PORT ME
+#include <bfc/dispatch.h>
+#include <api/syscb/callbacks/skincb.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/StringW.h>
+
+class Cursor : public Dispatchable
+{
+ public:
+ OSCURSORHANDLE getOSHandle();
+
+ enum {
+ CURSOR_GETOSHANDLE = 0,
+ };
+
+};
+
+inline OSCURSORHANDLE Cursor::getOSHandle() {
+ return _call(CURSOR_GETOSHANDLE, (OSCURSORHANDLE)NULL);
+}
+
+class CursorI : public Cursor {
+
+ public:
+
+ CursorI() {}
+ virtual ~CursorI() {}
+
+ virtual OSCURSORHANDLE getOSHandle()=0;
+
+ protected:
+
+ RECVS_DISPATCH;
+
+};
+
+#ifdef WASABI_COMPILE_SKIN
+
+class SkinCursor : public CursorI, public SkinCallbackI {
+
+ public:
+
+ SkinCursor();
+ SkinCursor(const wchar_t *elementid);
+ virtual ~SkinCursor();
+
+ virtual void setCursorElementId(const wchar_t *id);
+ virtual int skincb_onReset();
+ virtual OSCURSORHANDLE getOSHandle();
+ virtual void reset();
+
+ private:
+
+ StringW name;
+ OSCURSORHANDLE cursor;
+};
+
+#endif
+#endif
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/cwndtrack.h b/Src/Wasabi/api/wnd/cwndtrack.h
new file mode 100644
index 00000000..fa50f32f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/cwndtrack.h
@@ -0,0 +1,11 @@
+#ifndef _CWNDTRACK_H
+#define _CWNDTRACK_H
+
+#define TOP 1
+#define LEFT 2
+#define RIGHT 4
+#define BOTTOM 8
+#define NOINTERSECT 16
+#define KEEPSIZE 32
+
+#endif
diff --git a/Src/Wasabi/api/wnd/deactivatemgr.cpp b/Src/Wasabi/api/wnd/deactivatemgr.cpp
new file mode 100644
index 00000000..f011db52
--- /dev/null
+++ b/Src/Wasabi/api/wnd/deactivatemgr.cpp
@@ -0,0 +1,55 @@
+#include <precomp.h>
+#include "deactivatemgr.h"
+
+#define FAKE_PTR (ifc_window *)-1
+#define BYPASS_DEACTIVATE_ATOM "BYPASS_DEACTIVATE_MGR"
+
+int AppDeactivationMgr::is_deactivation_allowed(ifc_window *w) {
+#ifdef WIN32
+ if (FindAtomA(BYPASS_DEACTIVATE_ATOM) != NULL) return 1; // so people don't _need_ an api pointer to bypass us, however, if you can please call api->appdeactivation_setbypass
+#else
+ DebugString( "portme -- AppDeactivationMgr::is_deactivation_allowed\n");
+#endif
+ return list.getNumItems() == 0;
+}
+
+void AppDeactivationMgr::push_disallow(ifc_window *w) {
+ if (w == NULL)
+ w = FAKE_PTR;
+ list.addItem(w);
+}
+
+void AppDeactivationMgr::pop_disallow(ifc_window *w) {
+ if (w == NULL)
+ w = FAKE_PTR;
+ if (list.getNumItems() == 0) {
+ return;
+ }
+ while (list.getNumItems()>0) {
+ int p = list.searchItem(w);
+ if (p >= 0)
+ list.removeByPos(p);
+ else break;
+ }
+}
+
+void AppDeactivationMgr::setbypass(int i) {
+#ifdef WIN32
+ if (i) {
+ ATOM a = FindAtomA(BYPASS_DEACTIVATE_ATOM);
+ if (a != NULL) return;
+ AddAtomA(BYPASS_DEACTIVATE_ATOM);
+ } else {
+ ATOM a = FindAtomA(BYPASS_DEACTIVATE_ATOM);
+ if (a != NULL) {
+ DeleteAtom(a);
+ return;
+ }
+ }
+#else
+ DebugString( "portme -- AppDeactivationMgr::setbypass\n" );
+#endif
+}
+
+PtrList<ifc_window> AppDeactivationMgr::list;
+
diff --git a/Src/Wasabi/api/wnd/deactivatemgr.h b/Src/Wasabi/api/wnd/deactivatemgr.h
new file mode 100644
index 00000000..6e1e8c59
--- /dev/null
+++ b/Src/Wasabi/api/wnd/deactivatemgr.h
@@ -0,0 +1,22 @@
+#ifndef __APPDEACTIVATIONMGR_H
+#define __APPDEACTIVATIONMGR_H
+
+#include <bfc/ptrlist.h>
+
+class ifc_window;
+
+class AppDeactivationMgr {
+
+ public:
+
+ static int is_deactivation_allowed(ifc_window *w);
+ static void push_disallow(ifc_window *w);
+ static void pop_disallow(ifc_window *w);
+ static void setbypass(int i);
+
+ private:
+ static PtrList<ifc_window> list;
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/di.cpp b/Src/Wasabi/api/wnd/di.cpp
new file mode 100644
index 00000000..d7ff3631
--- /dev/null
+++ b/Src/Wasabi/api/wnd/di.cpp
@@ -0,0 +1,46 @@
+#include "precomp.h"
+#include "drag.h"
+#include <api/wnd/api_window.h>
+
+DI::DI(ifc_window *rw)
+ {
+ if (rw == NULL) di = NULL;
+ else di = rw->getDragInterface();
+ }
+ int DI::dragEnter(ifc_window *sourceWnd)
+ {
+ return di ? di->dragEnter(sourceWnd) : 0;
+ }
+ int DI::dragOver(int x, int y, ifc_window *sourceWnd)
+ {
+ return di ? di->dragOver(x, y, sourceWnd) : 0;
+ }
+ int DI::dragSetSticky(ifc_window *wnd, int left, int right, int up, int down)
+ {
+ return di ? di->dragSetSticky(wnd, left, right, up, down) : 0;
+ }
+ int DI::dragLeave(ifc_window *sourceWnd)
+ {
+ return di ? di->dragLeave(sourceWnd) : 0;
+ }
+ int DI::dragDrop(ifc_window *sourceWnd, int x, int y)
+ {
+ return di ? di->dragDrop(sourceWnd, x, y) : 0;
+ }
+
+ const wchar_t *DI::dragGetSuggestedDropTitle(void)
+ {
+ return di ? di->dragGetSuggestedDropTitle() : NULL;
+ }
+ int DI::dragCheckData(const wchar_t *type, int *nitems )
+ {
+ return di ? di->dragCheckData(type, nitems) : 0;
+ }
+ void *DI::dragGetData(int slot, int itemnum)
+ {
+ return di ? di->dragGetData(slot, itemnum) : NULL;
+ }
+ int DI::dragCheckOption(int option)
+ {
+ return di ? di->dragCheckOption(option) : NULL;
+ }
diff --git a/Src/Wasabi/api/wnd/drag.h b/Src/Wasabi/api/wnd/drag.h
new file mode 100644
index 00000000..7680b55d
--- /dev/null
+++ b/Src/Wasabi/api/wnd/drag.h
@@ -0,0 +1,75 @@
+#ifndef __WASABI_DRAG_H
+#define __WASABI_DRAG_H
+
+class ifc_window;
+
+#include <bfc/wasabi_std.h>
+
+class NOVTABLE DragInterface
+{
+public:
+ // (called on dest) when dragged item enters the winder
+ virtual int dragEnter(ifc_window *sourceWnd) = 0;
+ // (called on dest) during the winder
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd) = 0;
+ // (called on src)
+ virtual int dragSetSticky(ifc_window *wnd, int left, int right, int up, int down) = 0;
+ // (called on dest) when dragged item leaves the winder
+ virtual int dragLeave(ifc_window *sourceWnd) = 0;
+ // (called on dest) here is where we actually drop it
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y) = 0;
+
+ // must be called from within dragDrop(); (receiver)
+ virtual const wchar_t *dragGetSuggestedDropTitle(void) = 0;
+ // must be called from within your dragEnter, Over, Leave, or Drop
+ // return the slot # if you support this form of the data, -1 otherwise
+ // nitems can be NULL if you're just checking validity
+ virtual int dragCheckData(const wchar_t *type, int *nitems = NULL) = 0;
+ // fetches a specific pointer that was stored
+ virtual void *dragGetData(int slot, int itemnum) = 0;
+ virtual int dragCheckOption(int option) = 0;
+};
+
+class DragInterfaceI : public DragInterface
+{
+public:
+ // (called on dest) when dragged item enters the winder
+ virtual int dragEnter(ifc_window *sourceWnd) { return 0; }
+ // (called on dest) during the winder
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd) { return 0; }
+ // (called on src)
+ virtual int dragSetSticky(ifc_window *wnd, int left, int right, int up, int down) { return 0; }
+ // (called on dest) when dragged item leaves the winder
+ virtual int dragLeave(ifc_window *sourceWnd) { return 0; }
+ // (called on dest) here is where we actually drop it
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y) { return 0; }
+
+ // must be called from within dragDrop(); (receiver)
+ virtual const wchar_t *dragGetSuggestedDropTitle(void) { return NULL; }
+ // must be called from within your dragEnter, Over, Leave, or Drop
+ // return the slot # if you support this form of the data, -1 otherwise
+ // nitems can be NULL if you're just checking validity
+ virtual int dragCheckData(const wchar_t *type, int *nitems = NULL) { return 0; }
+ // fetches a specific pointer that was stored
+ virtual void *dragGetData(int slot, int itemnum) { return 0; }
+ virtual int dragCheckOption(int option) { return 0; }
+};
+
+class DI
+{
+public:
+ DI(ifc_window *rw);
+ int dragEnter(ifc_window *sourceWnd);
+ int dragOver(int x, int y, ifc_window *sourceWnd);
+ int dragSetSticky(ifc_window *wnd, int left, int right, int up, int down);
+ int dragLeave(ifc_window *sourceWnd);
+ int dragDrop(ifc_window *sourceWnd, int x, int y);
+ const wchar_t *dragGetSuggestedDropTitle(void);
+ int dragCheckData(const wchar_t *type, int *nitems = NULL);
+ void *dragGetData(int slot, int itemnum);
+ int dragCheckOption(int option);
+private:
+ DragInterface *di;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/dragitem.h b/Src/Wasabi/api/wnd/dragitem.h
new file mode 100644
index 00000000..c0236e24
--- /dev/null
+++ b/Src/Wasabi/api/wnd/dragitem.h
@@ -0,0 +1,23 @@
+#ifndef _DRAGITEM_H
+#define _DRAGITEM_H
+
+#include <bfc/dispatch.h>
+
+// has 1 or more pointers to a named data type
+class NOVTABLE DragItem : public Dispatchable
+{
+public:
+ const wchar_t *getDatatype() { return _call(GETDATATYPE, L""); }
+ int getNumData() { return _call(GETNUMDATA, 0); }
+ void *getDatum(int pos = 0) { return _call(GETDATUM, (void*)NULL, pos); }
+
+protected:
+ DISPATCH_CODES
+ {
+ GETDATATYPE = 100,
+ GETNUMDATA = 200,
+ GETDATUM = 300
+ };
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/dragitemi.cpp b/Src/Wasabi/api/wnd/dragitemi.cpp
new file mode 100644
index 00000000..75abde26
--- /dev/null
+++ b/Src/Wasabi/api/wnd/dragitemi.cpp
@@ -0,0 +1,36 @@
+#include <precomp.h>
+#include "dragitemi.h"
+
+DragItemI::DragItemI(const wchar_t *_datatype, void *_data) :
+ datatype(_datatype)
+{
+ if (_data != NULL) addVoidDatum(_data);
+}
+
+void DragItemI::addVoidDatum(void *newdatum)
+{
+ datalist.addItem(reinterpret_cast<char *>(newdatum));
+}
+
+const wchar_t *DragItemI::getDatatype()
+{
+ return datatype;
+};
+
+int DragItemI::getNumData()
+{
+ return datalist.getNumItems();
+}
+
+void *DragItemI::getDatum(int pos)
+{
+ return reinterpret_cast<void *>(datalist[pos]);
+}
+
+#define CBCLASS DragItemI
+START_DISPATCH;
+CB(GETDATATYPE, getDatatype);
+CB(GETNUMDATA, getNumData);
+CB(GETDATUM, getDatum);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/wnd/dragitemi.h b/Src/Wasabi/api/wnd/dragitemi.h
new file mode 100644
index 00000000..41198533
--- /dev/null
+++ b/Src/Wasabi/api/wnd/dragitemi.h
@@ -0,0 +1,58 @@
+#ifndef _DRAGITEMI_H
+#define _DRAGITEMI_H
+
+#include "dragitem.h"
+#include <bfc/common.h>
+#include <bfc/string/stringW.h>
+#include <bfc/ptrlist.h>
+
+class DragItemI : public DragItem
+{
+public:
+ DragItemI(const wchar_t *datatype, void *datum = NULL);
+ virtual ~DragItemI() {}
+
+ void addVoidDatum(void *newdatum); // up to you to cast it right
+
+ const wchar_t *getDatatype();
+ int getNumData();
+ void *getDatum(int pos = 0);
+
+private:
+ RECVS_DISPATCH;
+
+ StringW datatype;
+ PtrList<char> datalist;
+};
+
+template <class T>
+class DragItemT : public DragItemI
+{
+public:
+ DragItemT(T *item = NULL) : DragItemI(T::dragitem_getDatatype(), item) {}
+ static inline DragItemI *create(T *item) { return new DragItemT<T>(item); }
+
+ void addDatum(T *newdatum)
+ {
+ addVoidDatum(static_cast<void *>(newdatum));
+ }
+};
+
+template <class T>
+class DragItemCast
+{
+public:
+ DragItemCast(DragItem *_item, int _pos = 0) : item(_item), pos(_pos) {}
+ operator T *()
+ {
+ if (item == NULL || !STREQL(T::dragitem_getDatatype(), item->getDatatype()))
+ return NULL;
+ else
+ return static_cast<T*>(item->getDatum(pos));
+ }
+private:
+ DragItem *item;
+ int pos;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/fakedrag.h b/Src/Wasabi/api/wnd/fakedrag.h
new file mode 100644
index 00000000..4262f8b8
--- /dev/null
+++ b/Src/Wasabi/api/wnd/fakedrag.h
@@ -0,0 +1,12 @@
+#ifndef _FAKEDRAG_H
+#define _FAKEDRAG_H
+
+#include <api/wnd/basewnd.h>
+
+class FakeDragWnd : public BaseWnd {
+public:
+ FakeDragWnd() { dragging = 1; }
+ ~FakeDragWnd() { dragging = 0; }
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/findobjectcb.cpp b/Src/Wasabi/api/wnd/findobjectcb.cpp
new file mode 100644
index 00000000..b7b46ef6
--- /dev/null
+++ b/Src/Wasabi/api/wnd/findobjectcb.cpp
@@ -0,0 +1,8 @@
+#include "precomp.h"
+#include "findobjectcb.h"
+
+#define CBCLASS _FindObjectCallback
+START_DISPATCH;
+ CB(FINDOBJECTCB_MATCHOBJECT, findobjectcb_matchObject);
+END_DISPATCH;
+
diff --git a/Src/Wasabi/api/wnd/findobjectcb.h b/Src/Wasabi/api/wnd/findobjectcb.h
new file mode 100644
index 00000000..b0ce7f90
--- /dev/null
+++ b/Src/Wasabi/api/wnd/findobjectcb.h
@@ -0,0 +1,44 @@
+#ifndef __FINDOBJECTCALLBACK_H
+#define __FINDOBJECTCALLBACK_H
+
+#include <bfc/dispatch.h>
+#include <bfc/common.h>
+
+class ifc_window;
+
+class FindObjectCallback : public Dispatchable {
+
+ public:
+
+ int findobjectcb_matchObject(ifc_window *object);
+
+ enum {
+ FINDOBJECTCB_MATCHOBJECT = 0,
+ };
+
+};
+
+inline int FindObjectCallback::findobjectcb_matchObject(ifc_window *object) {
+ return _call(FINDOBJECTCB_MATCHOBJECT, 0, object);
+}
+
+
+class _FindObjectCallback : public FindObjectCallback {
+ public:
+ virtual int findobjectcb_matchObject(ifc_window *object)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+
+class FindObjectCallbackI : public _FindObjectCallback {
+ public:
+
+ FindObjectCallbackI() {}
+ virtual ~FindObjectCallbackI() {}
+
+ virtual int findobjectcb_matchObject(ifc_window *object)=0;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/fontdef.h b/Src/Wasabi/api/wnd/fontdef.h
new file mode 100644
index 00000000..add5ca5e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/fontdef.h
@@ -0,0 +1,15 @@
+#ifndef __FONTDEF_H
+#define __FONTDEF_H
+
+#define WA_FONT_TEXTOUT_NORMAL 0
+#define WA_FONT_TEXTOUT_RECT 1
+#define WA_FONT_TEXTOUT_ELLIPSED 2
+#define WA_FONT_TEXTOUT_WRAPPED 3
+#define WA_FONT_TEXTOUT_WRAPPEDPATHED 4
+#define WA_FONT_TEXTOUT_CENTERED 5
+
+#define WA_FONT_GETINFO_WIDTH 0
+#define WA_FONT_GETINFO_HEIGHT 1
+#define WA_FONT_GETINFO_WIDTHHEIGHT 2
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/ifc_bitmap.h b/Src/Wasabi/api/wnd/ifc_bitmap.h
new file mode 100644
index 00000000..560d13a4
--- /dev/null
+++ b/Src/Wasabi/api/wnd/ifc_bitmap.h
@@ -0,0 +1,51 @@
+#ifndef NULLSOFT_WASABI_IFC_BITMAP_H
+#define NULLSOFT_WASABI_IFC_BITMAP_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include <bfc/platform/platform.h>
+
+#warning move this typedef to bfc/platform/platform.h
+#ifdef _WIN32
+typedef HBITMAP OSBITMAPHANDLE;
+#elif defined(__APPLE__)
+typedef CGImageRef OSBITMAPHANDLE;
+#else
+#error port me
+#endif
+
+class ifc_bitmap : public Dispatchable
+{
+protected:
+ ifc_bitmap() {}
+ ~ifc_bitmap() {}
+public:
+ OSBITMAPHANDLE GetBitmap();
+ uint8_t *GetBits();
+ void UpdateBits(uint8_t *bits); // call to signify that you've modified the underlying bits.
+
+ DISPATCH_CODES
+ {
+ IFC_BITMAP_GETBITMAP = 10,
+ IFC_BITMAP_GETBITS = 20,
+ IFC_BITMAP_UPDATEBITS = 30,
+ };
+};
+
+
+inline OSBITMAPHANDLE ifc_bitmap::GetBitmap()
+{
+ return _call(IFC_BITMAP_GETBITMAP, (OSBITMAPHANDLE)0);
+}
+
+inline uint8_t *ifc_bitmap::GetBits()
+{
+ return _call(IFC_BITMAP_GETBITS, (uint8_t *)0);
+}
+
+inline void ifc_bitmap::UpdateBits(uint8_t *bits)
+{
+ _voidcall(IFC_BITMAP_UPDATEBITS, bits);
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/keyboard.cpp b/Src/Wasabi/api/wnd/keyboard.cpp
new file mode 100644
index 00000000..8c06d861
--- /dev/null
+++ b/Src/Wasabi/api/wnd/keyboard.cpp
@@ -0,0 +1,570 @@
+#include <precomp.h>
+#include "keyboard.h"
+#include <api/locales/localesmgr.h>
+//#include <api/wac/main.h> // CUT !!!
+#include <api/script/objects/systemobj.h>
+#include <api/wnd/wndtrack.h>
+
+#ifdef WASABI_COMPILE_SCRIPT
+#include <api/script/vcpu.h>
+#endif
+
+#if !defined(WIN32) && !defined(LINUX)
+#error port me
+#endif
+
+Keyboard::vkEntry Keyboard::vkEntries[]={
+#ifdef WIN32
+ //1, "lbutton", // fg> we don't want mouse messages in keyboard events, no.
+ //2, "rbutton",
+ 3, L"cancel",
+ //4, L"mbutton",
+ 8, L"backspace",
+ 9, L"tab",
+ 0xc, L"clear",
+ 0xd, L"return",
+ 0x10, L"shift",
+ 0x11, L"ctrl",
+ 0x12, L"alt",
+ 0x13, L"pause",
+ 0x14, L"capslock",
+ 0x1b, L"esc",
+ 0x20, L"space",
+ 0x21, L"pgup",
+ 0x22, L"pgdn",
+ 0x23, L"end",
+ 0x24, L"home",
+ 0x25, L"left",
+ 0x26, L"up",
+ 0x27, L"right",
+ 0x28, L"down",
+ 0x29, L"select",
+ 0x2b, L"execute",
+ 0x2c, L"prtscr",
+ 0x2d, L"insert",
+ 0x2e, L"del",
+ 0x2f, L"help",
+ 0x5b, L"lwin",
+ 0x5c, L"rwin",
+ 0x5d, L"mwin",
+ 0x60, L"n0",
+ 0x61, L"n1",
+ 0x62, L"n2",
+ 0x63, L"n3",
+ 0x64, L"n4",
+ 0x65, L"n5",
+ 0x66, L"n6",
+ 0x67, L"n7",
+ 0x68, L"n8",
+ 0x69, L"n9",
+ 0x6a, L"numpad_multiply",
+ 0x6b, L"numpad_add",
+ 0x6c, L"separator",
+ 0x6d, L"numpad_substract",
+ 0x6e, L"numpad_point",
+ 0x6f, L"numpad_divide",
+ 0x70, L"f1",
+ 0x71, L"f2",
+ 0x72, L"f3",
+ 0x73, L"f4",
+ 0x74, L"f5",
+ 0x75, L"f6",
+ 0x76, L"f7",
+ 0x77, L"f8",
+ 0x78, L"f9",
+ 0x79, L"f10",
+ 0x7a, L"f11",
+ 0x7b, L"f12",
+ 0x90, L"numlock",
+ 0x91, L"scroll",
+ 0xbb, L"equal",
+ 0xbd, L"minus",
+ 0xbf, L"slash",
+// 0xdb, L"minus", // seems to be the french code? --BU
+ 0xf6, L"attn",
+ 0xfe, L"clear",
+#endif
+#ifdef LINUX
+ {XK_space, L"space"},
+ {XK_Cancel, L"cancel"},
+ {XK_BackSpace, L"backspace"},
+ {XK_Tab, L"tab"},
+ {XK_Clear, L"clear"},
+ {XK_Return, L"return"},
+ {XK_Shift_L, L"shift"},
+ {XK_Shift_R, L"shift"},
+ {XK_Control_L, L"ctrl"},
+ {XK_Control_R, L"ctrl"},
+ {XK_Alt_L, L"alt"},
+ {XK_Alt_R, L"alt"},
+ {XK_Pause, L"pause"},
+ {XK_Caps_Lock, L"capslock"},
+ {XK_Escape, L"esc"},
+ {XK_Page_Up, L"pgup"},
+ {XK_KP_Page_Up, L"pgup"},
+ {XK_Page_Down, L"pgdn"},
+ {XK_KP_Page_Down, L"pgdn"},
+ {XK_End, L"end"},
+ {XK_KP_End, L"end"},
+ {XK_Home, L"home"},
+ {XK_KP_Home, L"home"},
+ {XK_Left, L"left"},
+ {XK_KP_Left, L"left"},
+ {XK_Up, L"up"},
+ {XK_KP_Up, L"up"},
+ {XK_Right, L"right"},
+ {XK_KP_Right, L"right"},
+ {XK_Down, L"down"},
+ {XK_KP_Down, L"down"},
+ {XK_Select, L"select"},
+ {XK_Execute, L"execute"},
+ {XK_Print, L"prtscr"},
+ {XK_Insert, L"insert"},
+ {XK_KP_Insert, L"insert"},
+ {XK_Delete, L"del"},
+ {XK_KP_Delete, L"del"},
+ {XK_Help, L"help"},
+ {XK_KP_0, L"n0"},
+ {XK_KP_1, L"n1"},
+ {XK_KP_2, L"n2"},
+ {XK_KP_3, L"n3"},
+ {XK_KP_4, L"n4"},
+ {XK_KP_5, L"n5"},
+ {XK_KP_6, L"n6"},
+ {XK_KP_7, L"n7"},
+ {XK_KP_8, L"n8"},
+ {XK_KP_9, L"n9"},
+ {XK_KP_Multiply, L"numpad_multiply"},
+ {XK_KP_Add, L"numpad_add"},
+ {XK_KP_Separator, L"separator"},
+ {XK_KP_Subtract, L"numpad_substract"},
+ {XK_KP_Decimal, L"numpad_point"},
+ {XK_KP_Divide, L"numpad_divide"},
+ {XK_F1, L"f1"},
+ {XK_F2, L"f2"},
+ {XK_F3, L"f3"},
+ {XK_F4, L"f4"},
+ {XK_F5, L"f5"},
+ {XK_F6, L"f6"},
+ {XK_F7, L"f7"},
+ {XK_F8, L"f8"},
+ {XK_F9, L"f9"},
+ {XK_F10, L"f10"},
+ {XK_F11, L"f11"},
+ {XK_F12, L"f12"},
+ {XK_Scroll_Lock, L"scroll"},
+#ifdef XK_3270
+ {XK_3270_Attn, L"attn"}, // I don't know what this is...
+#endif
+ {XK_Clear, L"clear"},
+#endif
+};
+//PORTME
+
+wchar_t *Keyboard::getVkName(int vkey)
+{
+ if(vkey>=0x41 && vkey<=0x5A) { // letters
+ static wchar_t key[2];
+ key[0]=vkey+0x20;
+ key[1]=0;
+ return key;
+ }
+ if(vkey>=0x30 && vkey<=0x39) { // numbers
+ static wchar_t key[2];
+ key[0]=vkey;
+ key[1]=0;
+ return key;
+ }
+ for(int i=0;i<(sizeof(vkEntries)/sizeof(vkEntry));i++) {
+ if(vkEntries[i].vk==vkey) return vkEntries[i].trans;
+ }
+#ifdef _DEBUG
+ //DebugString("undefined vk key pressed! (0x%x) :(\n",vkey);
+#endif
+ return NULL;
+}
+
+
+int Keyboard::forwardKbdMessage(ifc_window *from, int msg, int wp, int lp)
+{
+ OSWINDOWHANDLE wnd_to = WASABI_API_WND->main_getRootWnd()->gethWnd();
+ // note to self:
+ // this is necessary for winamp2's TranslateAccelerator call to work, it seems that this function will
+ // use the mouse capture wnd to determine the keyboard focus, oh thank you microsoft, because of you
+ // a script has to use "complete;" to be able to detect shift+ctrl+alt + click on a toggle button,
+ // otherwise pressing a key will throw the capture away, and the button will think the mouse is gone.
+ // this means that we can't be stealth doing that, we have to prevent anybody else getting shift+ctrl+alt
+ // isn't that nice ?
+ // we still avoid doing that if a mouse button is down, this will allow key+drags with capture
+ #ifdef WIN32
+ if (!(GetAsyncKeyState(VK_LBUTTON)&(1 << 31)) && !(GetAsyncKeyState(VK_RBUTTON)&(1 << 31)) && !(GetAsyncKeyState(VK_MBUTTON)&(1 << 31))) {
+ SetCapture(NULL);
+ }
+
+
+ #endif
+
+ #ifdef GET_KBDFORWARD_WND
+ ifc_window *dp = from->getDesktopParent();
+ if (dp) {
+ Layout *l = static_cast<Layout *>(dp->getInterface(layoutGuid));
+ if (l) {
+ Container *c = l->getParentContainer();
+ if (c) {
+ GUID g = c->getDefaultContent();
+ GET_KBDFORWARD_WND(g, wnd_to);
+ }
+ }
+ }
+ #endif
+
+ if (infw) return 0;
+ // if (from && from->gethWnd() == wnd_to) return 1;
+ infw = 1;
+
+ /* MSG winmsg;
+ winmsg.message = msg;
+ winmsg.hwnd = from->gethWnd();
+ winmsg.wParam = wp;
+ winmsg.lParam = lp;*/
+
+ int r = 0;
+ // int r = WASABI_API_APP->app_translateAccelerators(&winmsg);
+ infw = 0;
+
+ return r;
+}
+
+int Keyboard::onForwardOnChar(ifc_window *from, unsigned int c, int kd)
+{
+ if (WASABI_API_WND->isKeyboardLocked()) return 1;
+ return forwardKbdMessage(from, WM_CHAR, (WPARAM)c, (LPARAM)kd);
+}
+
+int MEMCMPC(void *m, char c, int size) {
+ char *p = (char*)m;
+ for (int i=0;i<size;i++) {
+ if (*p != c) return 1;
+ }
+ return 0;
+}
+
+int Keyboard::onForwardOnKeyDown(ifc_window *from, int k, int kd, int nomsg)
+{
+ if (WASABI_API_WND->isKeyboardLocked()) return 1;
+ if (infw) return 0;
+ if (k >= MAX_KEY) return 0;
+ lastwasreset = 0;
+ pressedKeys[k]=1;
+ syncKeyTable();
+ wchar_t s[64]={0,};
+ int first=1;
+#ifdef LINUX
+ for (int i=MAX_KEY-1; i >= 0; i--) {
+#else
+ for (int i=0;i<MAX_KEY;i++) {
+#endif
+ if (pressedKeys[i]) {
+ wchar_t *n = getVkName(i);
+ if (n) {
+ if (!first) wcscat(s, L"+");
+ else first=0;
+ wcscat(s,n);
+ }
+ }
+ }
+ ifc_window *wnd = from;
+ if(s[0]) {
+#ifdef _DEBUG
+ DebugString("keyboard: key pressed: %s\n",s);
+#endif
+#ifdef WASABI_COMPILE_LOCALES
+ const wchar_t *action;
+#endif
+ int found=0;
+ while(wnd!=NULL) {
+ for(int i=0;i<accSecEntries.getNumItems();i++) {
+ AccSec *ase = accSecEntries[i];
+ if(ase->global || ase->wnd==wnd) {
+#ifdef WASABI_COMPILE_LOCALES
+ if (action=LocalesManager::translateAccelerator(ase->name, s))
+ {
+ if(ase->wnd==wnd) found = 1;
+ wnd->onAcceleratorEvent(action);
+#ifdef _DEBUG
+ DebugString("keyboard: accelerator found\n");
+#endif
+ continue;
+ }
+#else
+ wnd->onAcceleratorEvent(s);
+#endif
+ }
+ }
+ wnd=wnd->getParent();
+ }
+ if (found) return 1;
+
+ if (NULL != from)
+ {
+ const wchar_t *accelSec = from->getId();
+ if (accelSec && *accelSec)
+ {
+ #ifdef WASABI_COMPILE_LOCALES
+ if(action=LocalesManager::translateAccelerator(accelSec, s))
+ {
+ int r = 0;
+ #ifdef WASABI_COMPILE_SCRIPT
+ r = SystemObject::onAccelerator(action, accelSec, s);
+ #endif
+ #ifdef WASABI_COMPILE_ACTIONS
+ if (r == 0)
+ {
+ int act=SkinParser::getAction(action);
+ if(act) Main::doAction(act);
+ }
+ #endif
+ #ifdef _DEBUG
+ DebugString("keyboard: accelerator found\n");
+ #endif
+ return 1;
+ }
+ #endif
+ }
+
+ }
+#ifdef WASABI_COMPILE_LOCALES
+ if(action=LocalesManager::translateAccelerator(L"general", s))
+ {
+ int r = 0;
+#ifdef WASABI_COMPILE_SCRIPT
+ r = SystemObject::onAccelerator(action, L"general", s);
+#endif
+#ifdef WASABI_COMPILE_ACTIONS
+ if (r == 0) {
+ int act=SkinParser::getAction(action);
+ if(act) Main::doAction(act);
+ }
+#endif
+#ifdef _DEBUG
+ DebugString("keyboard: accelerator found\n");
+#endif
+ return 1;
+ }
+#endif
+#ifdef _DEBUG
+ DebugString("keyboard: accelerator not found\n");
+#endif
+#ifdef WASABI_COMPILE_SCRIPT
+ DebugStringW(L"keyboard: sending \"%s\" to script\n", s);
+ SystemObject::onKeyDown(s);
+ if (VCPU::getComplete()) {
+ DebugStringW(L"keyboard: %s trapped by script\n", s);
+ return 1;
+ }
+#endif
+ if (pressedKeys[VK_CONTROL] && pressedKeys[VK_TAB])
+ {
+ int next = pressedKeys[VK_SHIFT] ? -1 : 1;
+ HWND w = GetForegroundWindow();
+ if (w == NULL) {
+ WASABI_API_WND->main_getRootWnd()->setFocus();
+ return 1;
+ }
+ ifc_window *cur = windowTracker->rootWndFromHwnd(w); // TODO: API_WNDMGR->
+ if (cur != NULL) {
+ ifc_window *nextwnd = windowTracker->getNextDesktopWindow(cur, next);
+ if (nextwnd) nextwnd->setFocus();
+ return 1;
+ }
+ WASABI_API_WND->main_getRootWnd()->setFocus();
+ return 1;
+ }
+ if (from && pressedKeys[VK_CONTROL] && pressedKeys[VK_F4]) {
+ ifc_window *dp = from->getDesktopParent();
+ if (dp) {
+ Layout *l = static_cast<Layout *>(dp->getInterface(layoutGuid));
+ if (l) {
+ Container *c = l->getParentContainer();
+ if (c) {
+ if (c->isMainContainer())
+ c->setVisible(!c->isVisible());
+ else
+ c->close();
+ return 1;
+ }
+ }
+ }
+ }
+ if (pressedKeys[0x5D]) {
+#if defined(WA3COMPATIBILITY)
+ Main::appContextMenu(from, TRUE, 0);
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ extern void appContextMenu(ifc_window *wnd);
+ appContextMenu(windowTracker->rootWndFromHwnd(GetForegroundWindow()));
+#endif
+ }
+ if (s[0] && from) return forwardKbdMessage(from, WM_KEYDOWN, (WPARAM)k, (LPARAM)kd);
+ }
+ return 0;
+}
+
+void Keyboard::syncKeyTable() {
+ for (int i=0;i<MAX_KEY;i++) {
+ //if (pressedKeys[i] && !(GetAsyncKeyState(i) & (1 << 31))) pressedKeys[i] = 0;
+ if (pressedKeys[i] && !Std::keyDown(i)) pressedKeys[i] = 0;
+ }
+}
+
+int Keyboard::onForwardOnKeyUp(ifc_window *from, int k, int kd) {
+ if (WASABI_API_WND->isKeyboardLocked()) return 1;
+ if (infw) return 0;
+ if (k >= MAX_KEY) return 0;
+ /*int hadkey = */MEMCMPC(pressedKeys, 0, sizeof(pressedKeys));
+ pressedKeys[k]=0;
+ syncKeyTable();
+ wchar_t s[64]={0,};
+ int first=1;
+#ifdef LINUX
+ for (int i=MAX_KEY-1; i >= 0; i--) {
+#else
+ for (int i=0;i<MAX_KEY;i++) {
+#endif
+ if (pressedKeys[i]) {
+ wchar_t *n = getVkName(i);
+ if (n) {
+ if (!first) wcscat(s, L"+");
+ else first=0;
+ wcscat(s,n);
+ }
+ }
+ }
+ if (!*s) {
+ if (!lastwasreset)
+ {
+ lastwasreset = 1;
+#ifdef WASABI_COMPILE_SCRIPT
+ DebugStringW(L"keyboard: sending \"%s\" to script\n", s);
+ SystemObject::onKeyDown(s);
+ if (VCPU::getComplete()) {
+ DebugStringW(L"keyboard: %s trapped by script\n", s);
+ return 1;
+ }
+#endif
+ }
+ }
+ return forwardKbdMessage(from, WM_KEYUP, (WPARAM)k, (LPARAM)kd);
+}
+
+int Keyboard::onForwardOnSysKeyDown(ifc_window *from, int k, int kd) {
+ if (WASABI_API_WND->isKeyboardLocked()) return 1;
+ if (infw) return 0;
+ if(kd&(1<<29)) pressedKeys[0x12]=1;
+ int r = onForwardOnKeyDown(from, k, 1);
+ if (r == 0) {
+ if (from && forwardKbdMessage(from, WM_SYSKEYDOWN, (WPARAM)k, (LPARAM)kd)) return 1;
+ }
+ return r;
+}
+
+int Keyboard::onForwardOnSysKeyUp(ifc_window *from, int k, int kd)
+{
+ if (WASABI_API_WND->isKeyboardLocked()) return 1;
+ if (infw) return 0;
+ if(kd&(1<<29)) pressedKeys[0x12]=0;
+ pressedKeys[k]=0;
+ int r = onForwardOnKeyUp(from, k, 1);
+ if (r == 0) {
+ if (forwardKbdMessage(from, WM_SYSKEYUP, (WPARAM)k, (WPARAM)kd)) return 1;
+ }
+ return r;
+}
+
+
+int Keyboard::onForwardOnKillFocus() {
+ // FG> I don't think this is necessary anymore because onkeydown always resyncs the pressedKeys table
+ // and supressing this allows scripts to trap ctrl/alt/shit + clicks (otherwise the click would reset
+ // the modifiers by way of an automatic focus)
+ //MEMSET(pressedKeys,0,sizeof(pressedKeys));
+ return 0;
+}
+
+void Keyboard::registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int global)
+{
+ accSecEntries.addItem(new AccSec(name,wnd,global));
+ viewer.viewItem(wnd);
+}
+
+int Keyboard::interceptOnChar(unsigned int c) {
+ if (hookers.getNumItems() > 0) {
+ return hookers.getLast()->onChar(c);
+ }
+ return 0;
+}
+
+int Keyboard::interceptOnKeyDown(int k){
+ if (hookers.getNumItems() > 0) {
+ return hookers.getLast()->onKeyDown(k);
+ }
+ return 0;
+}
+
+int Keyboard::interceptOnKeyUp(int k){
+ if (hookers.getNumItems() > 0) {
+ return hookers.getLast()->onKeyUp(k);
+ }
+ return 0;
+}
+
+int Keyboard::interceptOnSysKeyDown(int k, int kd){
+ if (hookers.getNumItems() > 0) {
+ return hookers.getLast()->onSysKeyDown(k, kd);
+ }
+ return 0;
+}
+
+int Keyboard::interceptOnSysKeyUp(int k, int kd){
+ if (hookers.getNumItems() > 0) {
+ return hookers.getLast()->onSysKeyUp(k, kd);
+ }
+ return 0;
+}
+
+void Keyboard::hookKeyboard(ifc_window *hooker) {
+ hookers.addItem(hooker);
+ DebugString("hookKeyboard = %d\n", hookers.getNumItems());
+}
+
+void Keyboard::unhookKeyboard(ifc_window *hooker) {
+ hookers.removeItem(hooker);
+ DebugString("unhookKeyboard = %d\n", hookers.getNumItems());
+}
+
+void Keyboard::reset() {
+ if (lastwasreset) return;
+ DebugString("keyboard reset\n");
+ MEMZERO(pressedKeys, sizeof(pressedKeys));
+ if (!lastwasreset) {
+ lastwasreset = 1;
+#ifdef WASABI_COMPILE_SCRIPT
+ DebugString("keyboard: sending \"\" to script\n");
+ SystemObject::onKeyDown(L"");
+#endif
+ }
+}
+
+int AccSecViewer::viewer_onItemDeleted(ifc_window *item) {
+ for(int i=0;i<Keyboard::accSecEntries.getNumItems();i++)
+ if(Keyboard::accSecEntries[i]->wnd==item) {
+ Keyboard::accSecEntries.removeByPos(i);
+ i--;
+ }
+ return 1;
+}
+
+wchar_t Keyboard::pressedKeys[MAX_KEY]={0,};
+PtrList<AccSec> Keyboard::accSecEntries;
+AccSecViewer Keyboard::viewer;
+PtrList<ifc_window> Keyboard::hookers;
+int Keyboard::infw = 0;
+int Keyboard::lastwasreset = 0;
diff --git a/Src/Wasabi/api/wnd/keyboard.h b/Src/Wasabi/api/wnd/keyboard.h
new file mode 100644
index 00000000..1aa4034c
--- /dev/null
+++ b/Src/Wasabi/api/wnd/keyboard.h
@@ -0,0 +1,77 @@
+#ifndef __KEYBOARD_H
+#define __KEYBOARD_H
+
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+#include <bfc/depview.h>
+
+#ifdef WIN32
+#define MAX_KEY 256
+#else
+#define MAX_KEY 65536
+#endif
+
+class ifc_window;
+
+class AccSec {
+public:
+ AccSec(const wchar_t *pname, ifc_window *pwnd, int pglobal=0) : name(pname), wnd(pwnd), global(pglobal) { }
+ StringW name;
+ ifc_window *wnd;
+ int global;
+};
+
+#include <api/wnd/api_window.h>
+class AccSecViewer : public DependentViewerTPtr<ifc_window> {
+public:
+ void viewItem(ifc_window *i) { viewer_addViewItem(i); }
+ virtual int viewer_onItemDeleted(ifc_window *item);
+};
+
+class Keyboard {
+
+public:
+
+ static int onForwardOnChar(ifc_window *from, unsigned int c, int kd);
+ static int onForwardOnKeyDown(ifc_window *from, int k, int kd, int nomsg=0);
+ static int onForwardOnKeyUp(ifc_window *from, int k, int kd);
+ static int onForwardOnSysKeyDown(ifc_window *from, int k, int kd);
+ static int onForwardOnSysKeyUp(ifc_window *from, int k, int kd);
+ static int onForwardOnKillFocus();
+
+ static int interceptOnChar(unsigned int c);
+ static int interceptOnKeyDown(int k);
+ static int interceptOnKeyUp(int k);
+ static int interceptOnSysKeyDown(int k, int kd);
+ static int interceptOnSysKeyUp(int k, int kd);
+
+ static void hookKeyboard(ifc_window *hooker);
+ static void unhookKeyboard(ifc_window *hooker);
+
+ static void reset();
+
+ static void registerAcceleratorSection(const wchar_t *name, ifc_window *wnd, int pglobal);
+
+ static PtrList<AccSec> accSecEntries;
+
+private:
+ static int forwardKbdMessage(ifc_window *from, int msg, int wp, int lp);
+ static wchar_t *getVkName(int vkey);
+ static void syncKeyTable();
+
+ // special keys
+ typedef struct {
+ int vk;
+ wchar_t *trans;
+ } vkEntry;
+ static vkEntry vkEntries[];
+
+ static wchar_t pressedKeys[MAX_KEY];
+
+ static AccSecViewer viewer;
+ static PtrList<ifc_window> hookers;
+ static int infw;
+ static int lastwasreset;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/minibrowser.cpp b/Src/Wasabi/api/wnd/minibrowser.cpp
new file mode 100644
index 00000000..fdcd7f85
--- /dev/null
+++ b/Src/Wasabi/api/wnd/minibrowser.cpp
@@ -0,0 +1,28 @@
+#include "precomp.h"
+#include "minibrowser.h"
+
+#define CBCLASS MiniBrowserCallbackI
+START_DISPATCH;
+ CB(MINIBROWSER_ONBEFORENAVIGATE, minibrowsercb_onBeforeNavigate);
+ VCB(MINIBROWSER_ONDOCUMENTCOMPLETE, minibrowsercb_onDocumentComplete);
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS MiniBrowserI
+START_DISPATCH;
+ CB(MINIBROWSER_GETROOTWND, minibrowser_getRootWnd);
+ CB(MINIBROWSER_NAVIGATEURL, minibrowser_navigateUrl);
+ CB(MINIBROWSER_BACK, minibrowser_back);
+ CB(MINIBROWSER_FORWARD, minibrowser_forward);
+ CB(MINIBROWSER_HOME, minibrowser_home);
+ CB(MINIBROWSER_REFRESH, minibrowser_refresh);
+ CB(MINIBROWSER_STOP, minibrowser_stop);
+ VCB(MINIBROWSER_SETTARGETNAME, minibrowser_setTargetName);
+ CB(MINIBROWSER_GETTARGETNAME, minibrowser_getTargetName);
+ CB(MINIBROWSER_GETCURRENTURL, minibrowser_getCurrentUrl);
+ VCB(MINIBROWSER_ADDCB, minibrowser_addCB);
+ VCB(MINIBROWSER_SETHOME, minibrowser_setHome);
+ VCB(MINIBROWSER_SETSCROLLFLAG, minibrowser_setScrollbarsFlag);
+END_DISPATCH;
+#undef CBCLASS
+
diff --git a/Src/Wasabi/api/wnd/minibrowser.h b/Src/Wasabi/api/wnd/minibrowser.h
new file mode 100644
index 00000000..b96b1577
--- /dev/null
+++ b/Src/Wasabi/api/wnd/minibrowser.h
@@ -0,0 +1 @@
+#include <api/skin/widgets/mb/minibrowser.h>
diff --git a/Src/Wasabi/api/wnd/notifmsg.h b/Src/Wasabi/api/wnd/notifmsg.h
new file mode 100644
index 00000000..be1cb05b
--- /dev/null
+++ b/Src/Wasabi/api/wnd/notifmsg.h
@@ -0,0 +1,109 @@
+#ifndef _NOTIFMSG_H
+#define _NOTIFMSG_H
+
+//!## Messages for BaseWnd::childNotify
+
+// these are in their own header file to keep from having to muck with
+// basewnd.h all the time to add a new global message
+
+namespace ChildNotify {
+enum {
+//
+// Common messages any control may need to send
+ NOP = 0, // not used. do not use.
+
+ // When child window is in its destructor
+ DELETED = 100, // no params
+
+ // Focus stuff
+ GOTFOCUS = 200, // no params
+ KILLFOCUS = 210, // no params
+ NAMECHANGED = 220, // no params
+
+ // for transient child windows
+ RETURN_CODE = 300, // param1 = the code
+ // NOTE: Currently only used by editwnd.cpp, but open for custom use by developers
+
+ // child wants parent to hide/show it
+ HIDEYHIDEY = 400, // no params
+ UNHIDEYHIDEY = 410, // no params
+
+// class-specific stuff
+
+ // ButtonWnd, buttwnd.h
+ BUTTON_LEFTPUSH = 10000, // no params
+ BUTTON_RIGHTPUSH = 10010, // no params
+ BUTTON_LEFTDOUBLECLICK = 10020, // no params
+ BUTTON_RIGHTDOUBLECLICK = 10030, // no params
+
+ CLICKWND_LEFTDOWN = 10100, // x/y
+ CLICKWND_LEFTUP = 10101, // x/y
+ CLICKWND_RIGHTDOWN = 10102, // x/y
+ CLICKWND_RIGHTUP = 10103, // x/y
+
+ // EditWnd, editwnd.h
+ EDITWND_DATA_MODIFIED = 11000, // user edit - no params
+ EDITWND_DATA_MODIFIED_ONIDLE = 11005, // user edit - no params (on idle)
+ EDITWND_CANCEL_PRESSED = 11010, // esc pressed - no params
+ EDITWND_ENTER_PRESSED = 11020, // enter pressed - no params
+ EDITWND_KEY_PRESSED = 11030, // any key pressed - param1 = the key
+
+ // DropList, droplist.h
+ DROPLIST_SEL_CHANGED = 12000, // param1 = new pos
+
+ // ListWnd, listwnd.h
+ LISTWND_SELCHANGED = 13000, // sent on any change - no params
+ LISTWND_ITEMSELCHANGED = 13010, // sent for each item - param1 = the item index, param2 = its selected state
+ LISTWND_DBLCLK = 13100, // param1 = the item index
+ LISTWND_POPUPMENU = 13200, // param1 = the x coord, param2 = the y coord
+
+ // FrameWnd, framewnd.h
+ FRAMEWND_QUERY_SLIDE_MODE = 14000, // no params - return slide mode
+ FRAMEWND_SET_SLIDE_MODE = 14010, // param1 = the new slide mode
+ FRAMEWND_WINDOWSHADE_CAPABLE = 14020, // no params - return width of shade
+ FRAMEWND_WINDOWSHADE_ENABLE = 14030, // param1 = new enabled state
+// Cut? this is unused.
+// FRAMEWND_WINDOWSHADE_DISABLE = 14040,
+ FRAMEWND_SETTITLEWIDTH = 14050, // param1 = the pullbar position
+
+ // ServiceWnd, servicewnd.h
+ SVCWND_LBUTTONDOWN = 15000, // param1 = the x coord, param2 = the y coord
+ SVCWND_RBUTTONDOWN = 15010, // param1 = the x coord, param2 = the y coord
+ SVCWND_LBUTTONUP = 15020, // param1 = the x coord, param2 = the y coord
+ SVCWND_RBUTTONUP = 15030, // param1 = the x coord, param2 = the y coord
+ SVCWND_LBUTTONDBLCLK = 15040, // param1 = the x coord, param2 = the y coord
+ SVCWND_RBUTTONDBLCLK = 15050, // param1 = the x coord, param2 = the y coord
+ SVCWND_MOUSEMOVE = 15060, // param1 = the x coord, param2 = the y coord
+
+ // Slider, slider.h
+ SLIDER_INTERIM_POSITION = 16000, // param1 = the slider position
+ SLIDER_FINAL_POSITION = 16010, // param1 = the slider position
+
+ // BucketItem, bucketitem.h
+ COMPONENTBUCKET_SETTEXT = 17000, // param1 = pointer to the text
+
+ // CheckWnd, checkwnd.h
+ CHECKWND_CLICK = 18000, // param1 = the new checkstate
+
+ // ScrollBar, scrollbar.h
+ SCROLLBAR_SETPOSITION = 19000, // param1 = the new position
+ SCROLLBAR_SETFINALPOSITION = 19010, // called when scrolling is completed - no params
+
+ // RadioGroup, radiogroup.h
+ RADIOGROUP_STATECHANGE = 20000, // param1 = the object selected, param2 = the object deselected
+
+ // grouptogglebutton
+ GROUPCLICKTGBUTTON_TOGGLE = 20100, // when the button is toggled, param1 = status
+ GROUPCLICKTGBUTTON_CLICKED = 20101, // when the button is clicked regardless of toggling
+
+ // misc
+ AUTOWHCHANGED = 20200, // sent by an object whose resource's auto w/h has changed (ie Text changed text, Layer changed image, etc)
+ GROUPRELOAD = 20300, // sent by abstractwndholder when its content is reloaded
+
+ // popup
+ POPUP_SUBMENUCLOSE = 21000, // sent by a submenu to its parent popup menu when it should close (esc/left key pressed)
+};
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/paintcb.cpp b/Src/Wasabi/api/wnd/paintcb.cpp
new file mode 100644
index 00000000..974ba998
--- /dev/null
+++ b/Src/Wasabi/api/wnd/paintcb.cpp
@@ -0,0 +1,52 @@
+#include "precomp.h"
+#include "paintcb.h"
+#include "api_window.h"
+
+#define CBCLASS PaintCallbackInfoI
+START_DISPATCH;
+ CB(PAINTCBINFO_GETCANVAS, getCanvas);
+ CB(PAINTCBINFO_GETREGION, getRegion);
+END_DISPATCH;
+
+PaintCallback::PaintCallback(ifc_window *w) {
+ monitorWindow(w);
+}
+
+PaintCallback::~PaintCallback() {
+ if (wnd != NULL) viewer_delViewItem(wnd);
+}
+
+void PaintCallback::monitorWindow(ifc_window *w) {
+ if (wnd != NULL) {
+ viewer_delViewItem(wnd);
+ wnd = NULL;
+ }
+ if (w != NULL) {
+ viewer_addViewItem(w);
+ wnd = w;
+ }
+}
+
+int PaintCallback::viewer_onItemDeleted(ifc_window *item) {
+ ASSERT(item == wnd);//jic
+ onWindowDeleted(wnd);
+ wnd = NULL;
+ return 1;
+}
+
+int PaintCallback::viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen) {
+ PaintCallbackInfo *info = reinterpret_cast<PaintCallbackInfo *>(ptr);
+ switch (event) {
+ case ifc_window::Event_ONPAINT:
+ if (param == BEFOREPAINT)
+ onBeforePaint(info);
+ else
+ onAfterPaint(info);
+ break;
+ case ifc_window::Event_ONINVALIDATE:
+ onInvalidation(info);
+ break;
+ }
+ return 1;
+}
+
diff --git a/Src/Wasabi/api/wnd/paintcb.h b/Src/Wasabi/api/wnd/paintcb.h
new file mode 100644
index 00000000..acb6fc6e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/paintcb.h
@@ -0,0 +1,73 @@
+#ifndef _PAINTCB_H
+#define _PAINTCB_H
+
+#include <bfc/depview.h>
+#include <bfc/dispatch.h>
+#include <api/wnd/api_window.h>
+
+class Canvas;
+class api_region;
+
+class PaintCallbackInfo : public Dispatchable {
+ public:
+ Canvas *getCanvas();
+ api_region *getRegion();
+
+ enum {
+ PAINTCBINFO_GETCANVAS = 10,
+ PAINTCBINFO_GETREGION = 20,
+ };
+
+};
+
+inline Canvas *PaintCallbackInfo::getCanvas() {
+ return _call(PAINTCBINFO_GETCANVAS, (Canvas *)NULL);
+}
+
+inline api_region *PaintCallbackInfo::getRegion() {
+ return _call(PAINTCBINFO_GETREGION, (api_region *)NULL);
+}
+
+class PaintCallbackInfoI : public PaintCallbackInfo {
+ public:
+ PaintCallbackInfoI(Canvas *_canvas, api_region *_region) : canvas(_canvas), region(_region) {}
+ virtual ~PaintCallbackInfoI() {}
+
+ virtual Canvas *getCanvas() { return canvas; }
+ virtual api_region *getRegion() { return region; }
+
+ private:
+
+ Canvas *canvas;
+ api_region *region;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+class PaintCallback : DependentViewerTPtr<ifc_window> {
+public:
+ PaintCallback() { wnd = NULL; };
+ PaintCallback(ifc_window *w);
+ virtual ~PaintCallback();
+
+ virtual void monitorWindow(ifc_window *w);
+ virtual int viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen);
+ virtual int viewer_onItemDeleted(ifc_window *item);
+
+ // override those
+ virtual void onBeforePaint(PaintCallbackInfo *info) { }
+ virtual void onAfterPaint(PaintCallbackInfo *info) { }
+ virtual void onWindowDeleted(ifc_window *w)=0; // warning, pointer invalid
+ virtual void onInvalidation(PaintCallbackInfo *info) { }
+
+ enum {
+ BEFOREPAINT = 10,
+ AFTERPAINT = 20,
+ };
+
+private:
+ ifc_window *wnd;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/paintset.cpp b/Src/Wasabi/api/wnd/paintset.cpp
new file mode 100644
index 00000000..b6ea8343
--- /dev/null
+++ b/Src/Wasabi/api/wnd/paintset.cpp
@@ -0,0 +1,603 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "paintset.h"
+
+using namespace Paintset;
+#include <tataki/canvas/bltcanvas.h>
+
+#include <tataki/bitmap/autobitmap.h>
+#include <tataki/color/skinclr.h>
+#include <api/font/font.h>
+#include <api/service/svcs/svc_font.h>
+
+#ifndef WASABI_COMPILE_IMGLDR
+#error This module requires image loading capabilities (WASABI_COMPILE_IMGLDR)
+#endif
+
+#define TITLE_PADDING 4 // SKINME
+
+#ifdef WASABI_COMPILE_SKIN
+static SkinColor title_fg(L"wasabi.component.title.foreground");
+static SkinColor title_border(L"wasabi.component.title.border");
+#endif
+
+class NOVTABLE PaintSet
+{
+protected:
+ PaintSet()
+ {}
+public:
+ virtual ~PaintSet()
+ {}
+
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha) = 0;
+};
+
+static PaintSet *sets[NUM_PAINTSETS];
+
+class PaintSetButtonDisabled : public PaintSet
+{
+public:
+ PaintSetButtonDisabled();
+
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
+
+private:
+ AutoSkinBitmap mid;
+};
+
+PaintSetButtonDisabled::PaintSetButtonDisabled()
+{
+ mid = L"wasabi.label.middle";
+}
+
+void PaintSetButtonDisabled::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
+{
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(canvasbase);
+ ASSERT(ret);
+
+ RECT r = *_r;
+
+ mid.stretchToRectAlpha(&canvas, &r, alpha);
+}
+
+//----
+
+class PaintSetButtonUp : public PaintSet
+{
+public:
+ PaintSetButtonUp();
+
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
+
+protected:
+ AutoSkinBitmap ul, u, ur;
+ AutoSkinBitmap l, mid, right;
+ AutoSkinBitmap ll, bot, lr;
+};
+
+PaintSetButtonUp::PaintSetButtonUp()
+{
+ ul = L"wasabi.button.top.left";
+ u = L"wasabi.button.top";
+ ur = L"wasabi.button.top.right";
+
+ l = L"wasabi.button.left";
+ mid = L"wasabi.button.middle";
+ right = L"wasabi.button.right";
+
+ ll = L"wasabi.button.bottom.left";
+ bot = L"wasabi.button.bottom";
+ lr = L"wasabi.button.bottom.right";
+}
+
+void PaintSetButtonUp::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
+{
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(canvasbase);
+ if (!ret) return;
+
+ RECT r = *_r, br;
+
+ // upper left
+ br.left = r.left;
+ br.top = r.top;
+ br.right = r.left + ul.getWidth();
+ br.bottom = r.top + ul.getHeight();
+ ul.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // top
+ br.left = br.right;
+ br.right = r.right - ur.getWidth();
+ u.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // upper right
+ br.left = br.right;
+ br.right = r.right;
+ ur.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // left
+ br.left = r.left;
+ br.right = r.left + l.getWidth();
+ br.top = r.top + ul.getHeight();
+ br.bottom = r.bottom - ll.getHeight();
+ l.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // middle
+ br.top = r.top + ul.getHeight();
+ br.bottom = r.bottom - ll.getHeight();
+ br.left = r.left + ul.getWidth();
+ br.right = r.right - ur.getWidth();
+ mid.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // right
+ br.left = r.right - right.getWidth();
+ br.right = r.right;
+ br.top = r.top + ur.getHeight();
+ br.bottom = r.bottom - lr.getHeight();
+ right.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // lower left
+ br.left = r.left;
+ br.right = r.left + ll.getWidth();
+ br.top = r.bottom - ll.getHeight();
+ br.bottom = r.bottom;
+ ll.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // bot
+ br.left = r.left + ll.getWidth();
+ br.right = r.right - lr.getWidth();
+ br.top = r.bottom - bot.getHeight();
+ br.bottom = r.bottom;
+ bot.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // lower right
+ br.left = r.right - lr.getWidth();
+ br.right = r.right;
+ br.top = r.bottom - lr.getHeight();
+ br.bottom = r.bottom;
+ lr.stretchToRectAlpha(&canvas, &br, alpha);
+}
+
+class PaintSetLabel : public PaintSetButtonUp
+{
+public:
+ PaintSetLabel()
+ {
+ ul = L"wasabi.label.top.left";
+ u = L"wasabi.label.top";
+ ur = L"wasabi.label.top.right";
+
+ l = L"wasabi.label.left";
+ mid = L"wasabi.label.middle";
+ right = L"wasabi.label.right";
+
+ ll = L"wasabi.label.bottom.left";
+ bot = L"wasabi.label.bottom";
+ lr = L"wasabi.label.bottom.right";
+ }
+};
+
+//----
+
+class PaintSetButtonDown : public PaintSet
+{
+public:
+ PaintSetButtonDown();
+
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
+
+private:
+ AutoSkinBitmap ul, u, ur;
+ AutoSkinBitmap l, mid, right;
+ AutoSkinBitmap ll, bot, lr;
+};
+
+PaintSetButtonDown::PaintSetButtonDown()
+{
+ ul = L"wasabi.button.pressed.top.left";
+ u = L"wasabi.button.pressed.top";
+ ur = L"wasabi.button.pressed.top.right";
+
+ l = L"wasabi.button.pressed.left";
+ mid = L"wasabi.button.pressed.middle";
+ right = L"wasabi.button.pressed.right";
+
+ ll = L"wasabi.button.pressed.bottom.left";
+ bot = L"wasabi.button.pressed.bottom";
+ lr = L"wasabi.button.pressed.bottom.right";
+}
+
+void PaintSetButtonDown::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
+{
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(canvasbase);
+ ASSERT(ret);
+
+ RECT r = *_r, br;
+
+ // upper left
+ br.left = r.left;
+ br.top = r.top;
+ br.right = r.left + ul.getWidth();
+ br.bottom = r.top + ul.getHeight();
+ ul.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // top
+ br.left = br.right;
+ br.right = r.right - ur.getWidth();
+ u.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // upper right
+ br.left = br.right;
+ br.right = r.right;
+ ur.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // left
+ br.left = r.left;
+ br.right = r.left + l.getWidth();
+ br.top = r.top + ul.getHeight();
+ br.bottom = r.bottom - ll.getHeight();
+ l.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // middle
+ br.top = r.top + ul.getHeight();
+ br.bottom = r.bottom - ll.getHeight();
+ br.left = r.left + ul.getWidth();
+ br.right = r.right - ur.getWidth();
+ mid.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // right
+ br.left = r.right - right.getWidth();
+ br.right = r.right;
+ br.top = r.top + ur.getHeight();
+ br.bottom = r.bottom - lr.getHeight();
+ right.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // lower left
+ br.left = r.left;
+ br.right = r.left + ll.getWidth();
+ br.top = r.bottom - ll.getHeight();
+ br.bottom = r.bottom;
+ ll.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // bot
+ br.left = r.left + ll.getWidth();
+ br.right = r.right - lr.getWidth();
+ br.top = r.bottom - bot.getHeight();
+ br.bottom = r.bottom;
+ bot.stretchToRectAlpha(&canvas, &br, alpha);
+
+ // lower right
+ br.left = r.right - lr.getWidth();
+ br.right = r.right;
+ br.top = r.bottom - lr.getHeight();
+ br.bottom = r.bottom;
+ lr.stretchToRectAlpha(&canvas, &br, alpha);
+}
+//--
+
+class PaintSetAppFrame : public PaintSet
+{
+public:
+ PaintSetAppFrame();
+ virtual ~PaintSetAppFrame();
+
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
+
+private:
+ SkinBitmap *ul, *up, *ur;
+ SkinBitmap *left, *right;
+ SkinBitmap *ll, *bot, *lr;
+};
+
+PaintSetAppFrame::PaintSetAppFrame()
+{
+ ul = new SkinBitmap(L"studio.border.upperLeft");
+ up = new SkinBitmap(L"studio.border.top");
+ ur = new SkinBitmap(L"studio.border.upperRight");
+
+ left = new SkinBitmap(L"studio.border.left");
+ right = new SkinBitmap(L"studio.border.right");
+
+ ll = new SkinBitmap(L"studio.border.lowerLeft");
+ bot = new SkinBitmap(L"studio.border.bottom");
+ lr = new SkinBitmap(L"studio.border.lowerRight");
+}
+
+PaintSetAppFrame::~PaintSetAppFrame()
+{
+ delete ul; delete up; delete ur;
+ delete left; delete right;
+ delete ll; delete bot; delete lr;
+}
+
+void PaintSetAppFrame::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
+{
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(canvasbase);
+ ASSERT(ret);
+
+ RECT r = *_r;
+ RECT br;
+
+ // upper left
+ br = r;
+ br.right = br.left + 2;
+ br.bottom = br.top + 2;
+ ul->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // top
+ br = r;
+ br.left += 2;
+ br.right -= 2;
+ br.bottom = br.top + 2;
+ up->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // upper right
+ br = r;
+ br.left = br.right - 2;
+ br.bottom = br.top + 2;
+ ur->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // left
+ br = r;
+ br.right = br.left + 2;
+ br.top += 2;
+ br.bottom -= 2;
+ left->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // right
+ br = r;
+ br.left = br.right - 2;
+ br.top += 2;
+ br.bottom -= 2;
+ right->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // lower left
+ br = r;
+ br.right = br.left + 2;
+ br.top = br.bottom - 2;
+ ll->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // bottom
+ br = r;
+ br.left += 2;
+ br.right -= 2;
+ br.top = br.bottom - 2;
+ bot->stretchToRectAlpha(&canvas, &br, alpha);
+
+ // lower right
+ br = r;
+ br.left = br.right - 2;
+ br.top = br.bottom - 2;
+ lr->stretchToRectAlpha(&canvas, &br, alpha);
+}
+
+// -----
+
+class PaintSetTitleStreak : public PaintSet
+{
+public:
+ PaintSetTitleStreak();
+
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha);
+
+private:
+ AutoSkinBitmap title_left, title_middle, title_right;
+};
+
+PaintSetTitleStreak::PaintSetTitleStreak()
+{
+ title_left = L"wasabi.titlebar.left.active";
+ title_middle = L"wasabi.titlebar.center.active";
+ title_right = L"wasabi.titlebar.right.active";
+}
+
+void PaintSetTitleStreak::render(ifc_canvas *canvasbase, const RECT *_r, int alpha)
+{
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(canvasbase);
+ if (!ret) return;
+
+ RECT r = *_r;
+
+ RECT lr = r;
+ lr.right = lr.left + title_left.getWidth();
+ lr.top += ((lr.bottom - lr.top) - title_left.getHeight()) / 2;
+ lr.bottom = lr.top + title_left.getHeight();
+ if (lr.right <= lr.left) return;
+ title_left.stretchToRectAlpha(&canvas, &lr, alpha);
+
+ RECT rr = r;
+ rr.left = rr.right - title_right.getWidth();
+ rr.top += ((rr.bottom - rr.top) - title_left.getHeight()) / 2;
+ rr.bottom = rr.top + title_left.getHeight();
+ if (rr.right <= rr.left) return;
+ title_right.stretchToRectAlpha(&canvas, &rr, alpha);
+
+ RECT cr = r;
+ cr.left = lr.right;
+ cr.right = rr.left;
+ cr.top += ((cr.bottom - cr.top) - title_left.getHeight()) / 2;
+ cr.bottom = cr.top + title_left.getHeight();
+ if (cr.right <= cr.left) return;
+ title_middle.stretchToRectAlpha(&canvas, &cr, alpha);
+}
+
+class PaintSetFocusRect : public PaintSet
+{
+public:
+ virtual void render(ifc_canvas *canvas, const RECT *r, int alpha)
+ {
+ BaseCloneCanvas c;
+ c.clone(canvas);
+ c.drawRect(r, 0, 0xFFFFFF, alpha);
+ }
+};
+
+// -----
+
+int paintset_present(int set)
+{
+ return paintset_renderPaintSet(set, NULL, NULL, 255, TRUE);
+}
+
+int paintset_renderPaintSet(int type, ifc_canvas *c, const RECT *r, int alpha, int checkonly)
+{
+ PaintSet *ret = NULL;
+ switch (type)
+ {
+ case BUTTONUP:
+ ret = sets[BUTTONUP];
+ if (ret == NULL) ret = new PaintSetButtonUp();
+ sets[BUTTONUP] = ret;
+ break;
+ case BUTTONDOWN:
+ ret = sets[BUTTONDOWN];
+ if (ret == NULL) ret = new PaintSetButtonDown();
+ sets[BUTTONDOWN] = ret;
+ break;
+ case TRAY:
+ ret = sets[BUTTONDOWN];
+ if (ret == NULL) ret = new PaintSetButtonDown();
+ sets[BUTTONDOWN] = ret;
+ break;
+ case APPFRAME:
+ ret = sets[APPFRAME];
+ if (ret == NULL) ret = new PaintSetAppFrame();
+ sets[APPFRAME] = ret;
+ break;
+ case BUTTONDISABLED:
+ ret = sets[BUTTONDISABLED];
+ if (ret == NULL) ret = new PaintSetButtonDisabled();
+ sets[BUTTONDISABLED] = ret;
+ break;
+ case TITLESTREAK:
+ ret = sets[TITLESTREAK];
+ if (ret == NULL) ret = new PaintSetTitleStreak();
+ sets[TITLESTREAK] = ret;
+ break;
+ case LABEL:
+ ret = sets[LABEL];
+ if (ret == NULL) ret = new PaintSetLabel();
+ sets[LABEL] = ret;
+ break;
+ case FOCUSRECT:
+ ret = sets[FOCUSRECT];
+ if (ret == NULL) ret = new PaintSetFocusRect();
+ sets[FOCUSRECT] = ret;
+ break;
+ }
+
+ if (ret != NULL)
+ {
+ if (!checkonly) ret->render(c, r, alpha);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifdef WASABI_COMPILE_FONTS
+
+#define VERTPAD 2
+#define AAFACTOR 2
+#define FONTNAME "studio.component.title"
+#define FONTNAMEW L"studio.component.title"
+
+void paintset_renderTitle(const wchar_t *title, ifc_canvas *canvasbase, const RECT *_r, int alpha, int dostreaks, int doborder)
+{
+ BaseCloneCanvas canvas;
+ int ret = canvas.clone(canvasbase);
+ if (!ret) return;
+
+ RECT r = *_r;
+ int w = r.right - r.left;
+ int h = (r.bottom - r.top) - VERTPAD;
+
+ svc_font *f = Font::requestSkinFont(FONTNAMEW);
+ if (f->isBitmap() || !doborder)
+ {
+ Wasabi::FontInfo fontInfo;
+ int tw, th;
+ fontInfo.pointSize = h;
+ fontInfo.face = FONTNAMEW;
+ fontInfo.color = title_fg;
+ canvas.getTextExtent(title, &tw, &th, &fontInfo);
+ w -= (tw + TITLE_PADDING * 2);
+ w /= 2;
+ int x = r.left + w + TITLE_PADDING;
+ int y = r.top + VERTPAD / 2;
+ canvas.textOut(x, y, title, &fontInfo);
+ }
+ else
+ {
+ Wasabi::FontInfo fontInfo;
+ int tw, th;
+ fontInfo.pointSize = h*AAFACTOR;
+ fontInfo.face = FONTNAMEW;
+ canvas.getTextExtent(title, &tw, &th, &fontInfo);
+ tw /= AAFACTOR;
+ th /= AAFACTOR;
+ tw += 2;
+ th += 2;
+
+ BltCanvas bc(tw*AAFACTOR, th*AAFACTOR + 1);
+ bc.fillBits(RGB(0, 0, 0)); // not skinned
+ fontInfo.opaque=false;
+ fontInfo.color = title_border;
+ bc.textOut(-AAFACTOR, AAFACTOR / 2, title, &fontInfo);
+ bc.textOut(AAFACTOR, AAFACTOR / 2, title, &fontInfo);
+ bc.textOut(AAFACTOR / 2, -AAFACTOR, title, &fontInfo);
+ bc.textOut(AAFACTOR / 2, AAFACTOR, title, &fontInfo);
+
+ fontInfo.color = title_fg;
+ bc.textOut(AAFACTOR / 2, AAFACTOR / 2, title, &fontInfo);
+
+ // mask it
+ bc.maskColor(RGB(0, 0, 0), RGB(0, 0, 0));
+ BltCanvas tc(tw, th);
+ bc.antiAliasTo(&tc, tw, th, AAFACTOR);
+
+
+ //int cw = tw + TITLE_PADDING * 2;
+ // if (cw > w || th > h) return;
+ w -= (tw + TITLE_PADDING * 2);
+ w /= 2;
+
+ int x = r.left + w + TITLE_PADDING;
+ int y = r.top + VERTPAD / 2;
+//FG>?? tc.vflip();
+ tc.blitAlpha(&canvas, x, y, alpha);
+
+ //SkinBitmap splef0(tc.getBitmap(), tc.getHDC(), TRUE, tc.getBits());
+// splef0.blitAlpha(&canvas, x, y, alpha);
+
+
+
+ }
+
+ if (dostreaks)
+ {
+ RECT pr = r;
+ pr.right = pr.left + w;
+ paintset_renderPaintSet(TITLESTREAK, &canvas, &pr, alpha);
+
+ pr.right = r.right;
+ pr.left = r.right - w;
+ paintset_renderPaintSet(TITLESTREAK, &canvas, &pr, alpha);
+ }
+}
+
+#endif
+
+void paintset_reset()
+{
+ for (int i = 0; i < NUM_PAINTSETS; i++)
+ {
+ delete sets[i];
+ sets[i] = NULL;
+ }
+}
+
diff --git a/Src/Wasabi/api/wnd/paintset.h b/Src/Wasabi/api/wnd/paintset.h
new file mode 100644
index 00000000..317a383b
--- /dev/null
+++ b/Src/Wasabi/api/wnd/paintset.h
@@ -0,0 +1,18 @@
+#ifndef _PAINTSET_H
+#define _PAINTSET_H
+
+#include <wasabicfg.h>
+
+#include <api/wnd/paintsets.h>
+#include <tataki/canvas/ifc_canvas.h>
+
+int paintset_present(int set);
+#ifdef WASABI_COMPILE_IMGLDR
+int paintset_renderPaintSet(int type, ifc_canvas *c, const RECT *r, int alpha=255, int checkonly=FALSE);
+#ifdef WASABI_COMPILE_FONTS
+void paintset_renderTitle(const wchar_t *title, ifc_canvas *canvas, const RECT *r, int alpha=255, int dostreaks=TRUE, int doborder=TRUE);
+#endif
+#endif
+void paintset_reset();
+
+#endif
diff --git a/Src/Wasabi/api/wnd/paintsets.h b/Src/Wasabi/api/wnd/paintsets.h
new file mode 100644
index 00000000..c1ed21d8
--- /dev/null
+++ b/Src/Wasabi/api/wnd/paintsets.h
@@ -0,0 +1,18 @@
+#ifndef _PAINTSETS_H
+#define _PAINTSETS_H
+
+namespace Paintset {
+ enum {
+ BUTTONUP,
+ BUTTONDOWN,
+ TRAY,
+ BUTTONDISABLED,
+ TITLESTREAK,
+ APPFRAME,
+ LABEL,
+ FOCUSRECT,
+ };
+ const int NUM_PAINTSETS = 8;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp
new file mode 100644
index 00000000..6cfeb126
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp
@@ -0,0 +1,51 @@
+#include "PaintCanvas.h"
+
+PaintCanvas::PaintCanvas()
+{
+ qdcontext=0;
+}
+
+bool PaintCanvas::beginPaint(BaseWnd *wnd)
+{
+ HIWindowRef macWnd = wnd->getOsWindowHandle();
+
+ qdcontext = GetWindowPort(macWnd);
+ QDBeginCGContext(qdcontext, &context);
+
+ return true;
+}
+
+PaintCanvas::~PaintCanvas()
+{
+ if (qdcontext)
+ QDEndCGContext(qdcontext, &context);
+}
+
+WndCanvas::WndCanvas()
+{
+ qdcontext=0;
+}
+
+WndCanvas::~WndCanvas()
+{
+ if (qdcontext)
+ QDEndCGContext(qdcontext, &context);
+}
+
+int WndCanvas::attachToClient(BaseWnd *basewnd)
+{
+ HIWindowRef macWnd = basewnd->getOsWindowHandle();
+
+ qdcontext = GetWindowPort(macWnd);
+ QDBeginCGContext(qdcontext, &context);
+ return 1;
+}
+
+
+TextInfoCanvas::TextInfoCanvas(BaseWnd */*unused*/)
+{
+}
+
+TextInfoCanvas::~TextInfoCanvas()
+{
+}
diff --git a/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h
new file mode 100644
index 00000000..f9091404
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h
@@ -0,0 +1,45 @@
+#ifndef NULLSOFT_WASABI_OSX_PAINTCANVAS_H
+#define NULLSOFT_WASABI_OSX_PAINTCANVAS_H
+
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/basewnd.h>
+
+class PaintCanvas : public Canvas
+{
+public:
+ PaintCanvas();
+ ~PaintCanvas();
+ bool beginPaint(BaseWnd *wnd);
+protected:
+ CGrafPtr qdcontext;
+};
+
+class PaintBltCanvas : public PaintCanvas
+{
+public:
+ bool beginPaintNC(BaseWnd *wnd)
+ {
+ return beginPaint(wnd);
+ }
+};
+#warning port PaintBltCanvas
+class WndCanvas : public Canvas
+{
+public:
+ WndCanvas();
+ virtual ~WndCanvas();
+
+ // address client area
+ int attachToClient(BaseWnd *basewnd);
+
+private:
+ CGrafPtr qdcontext;
+};
+
+class TextInfoCanvas : public Canvas
+{
+public:
+ TextInfoCanvas(BaseWnd *baseWnd);
+ virtual ~TextInfoCanvas();
+};
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/platform/osx/bltcanvas.h b/Src/Wasabi/api/wnd/platform/osx/bltcanvas.h
new file mode 100644
index 00000000..399deb71
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/bltcanvas.h
@@ -0,0 +1,26 @@
+#ifndef _BLTCANVAS_H
+#define _BLTCANVAS_H
+
+#include "canvas.h"
+
+class BltCanvas : public Canvas
+{
+public:
+ BltCanvas();
+ BltCanvas(int width, int height, OSWINDOWHANDLE wnd);
+
+ // override blit and stretchblit so we can use CGContextDrawLayerAtPoint/CGContextDrawLayerInRect
+ virtual void blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth);
+ void blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
+
+ virtual void stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth);
+ void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
+
+ void DestructiveResize(int w, int h, int nb_bpp = 32); // resizes the bitmap, destroying the contents
+ void fillBits(ARGB32 color);
+
+protected:
+ CGLayerRef layer;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/platform/osx/canvas.h b/Src/Wasabi/api/wnd/platform/osx/canvas.h
new file mode 100644
index 00000000..9a434026
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/canvas.h
@@ -0,0 +1,69 @@
+#ifndef NULLSOFT_WASABI_CANVAS_H
+#define NULLSOFT_WASABI_CANVAS_H
+
+#include <Carbon/Carbon.h>
+#include <tataki/canvas/ifc_canvas.h>
+#include <bfc/platform/platform.h>
+#include <api/service/svcs/svc_font.h> // for STDFONT_* stuff. should make a std_font thingy later
+#include <bfc/std.h> // for WASABI_DEFAULT_FONTNAMEW
+class BaseWnd;
+class api_region;
+
+class Canvas : public ifc_canvas
+{
+public:
+ Canvas() :context(0), wnd(0) {}
+ Canvas(CGContextRef _context) : context(_context), wnd(0) {}
+ Canvas(CGrafPtr _context);
+ HDC getHDC();
+ void fillRect(const RECT *r, RGB32 color);
+ void fillRgn(api_region *r, RGB32 color);
+ void setBaseWnd(BaseWnd *_wnd) { wnd=_wnd; }
+ void selectClipRgn(api_region *r);
+
+ virtual void blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth);
+ virtual void stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth);
+
+ void textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
+
+ static float getSystemFontScale() { return 1.0f; }
+
+ int getTextWidth(const wchar_t *text, const Wasabi::FontInfo *fontInfo);
+ int getTextHeight(const wchar_t *text, const Wasabi::FontInfo *fontInfo);
+ int getTextHeight(const Wasabi::FontInfo *fontInfo)
+ {
+ return getTextHeight(L"M", fontInfo);
+ }
+ void getTextExtent(const wchar_t *text, int *w, int *h, const Wasabi::FontInfo *fontInfo);
+ void textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
+ void textOut(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
+ void textOutEllipsed(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
+
+ void drawSysObject(const RECT *r, int sysobj, int alpha=255);
+protected:
+ RECVS_DISPATCH;
+
+ CGContextRef context;
+ BaseWnd *wnd; // TODO: not 100% sure we'll need this. win32 version has it so we'll keep it for now
+};
+
+class BaseCloneCanvas : public Canvas
+{
+public:
+ BaseCloneCanvas(ifc_canvas *cloner=NULL);
+ virtual ~BaseCloneCanvas();
+
+ int clone(ifc_canvas *cloner);
+};
+
+namespace DrawSysObj {
+ enum {
+ BUTTON, BUTTON_PUSHED, BUTTON_DISABLED,
+ OSBUTTON, OSBUTTON_PUSHED, OSBUTTON_DISABLED,
+ OSBUTTON_CLOSE, OSBUTTON_CLOSE_PUSHED, OSBUTTON_CLOSE_DISABLED,
+ OSBUTTON_MINIMIZE, OSBUTTON_MINIMIZE_PUSHED, OSBUTTON_MINIMIZE_DISABLED,
+ OSBUTTON_MAXIMIZE, OSBUTTON_MAXIMIZE_PUSHED, OSBUTTON_MAXIMIZE_DISABLED,
+ };
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp
new file mode 100644
index 00000000..fe9f3363
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp
@@ -0,0 +1,220 @@
+#include "osx_bitmap_cgimage.h"
+
+SkinBitmap::SkinBitmap(ARGB32 *_bits, int w, int h) : image(0)
+{
+ // TODO: allow a mechanism for SkinBitmap to take ownership of the data
+ bits = malloc(w*h*4);
+ if (bits)
+ {
+ memcpy(bits, _bits, w*h*4);
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ imageContext = CGBitmapContextCreate(bits, w, h, 8, w*4, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
+ image = CGBitmapContextCreateImage(imageContext);
+ CGColorSpaceRelease(colorSpace);
+ }
+}
+
+SkinBitmap::~SkinBitmap()
+{
+ CGImageRelease(image);
+#ifndef SKINBITMAP_USE_CGIMAGE
+ free(bits);
+ CGContextRelease(imageContext);
+#endif
+}
+
+#ifdef WASABI_COMPILE_IMGLDR
+SkinBitmap::SkinBitmap(const wchar_t *elementname, int _cached)
+{
+ ASSERT(elementname!= NULL);
+
+ bitmapname = elementname;
+ x_offset = -1;
+ y_offset = -1;
+ subimage_w = -1;
+ subimage_h = -1;
+ fullimage_w=fullimage_h=0;
+ ownbits=1;
+ fromskin = 0;
+ last_failed = 0;
+#ifdef WASABI_COMPILE_SKIN
+ bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(elementname, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ fromskin = (bits != NULL);
+#else
+ bits = NULL;
+#endif
+ if (bits == NULL)
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(elementname, &has_alpha, &fullimage_w, &fullimage_h);
+#ifdef WASABI_COMPILE_SKIN
+ if (bits == NULL)
+ {
+ bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(ERRORBMP, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ last_failed = 1;
+ }
+#endif
+ if (bits == NULL)
+ {
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(HARDERRORBMP, &has_alpha, &fullimage_w, &fullimage_h);
+ last_failed = 1;
+ }
+
+ // check that coordinates are correct
+ if(x_offset!=-1 && x_offset>fullimage_w) x_offset=fullimage_w-1;
+ if(y_offset!=-1 && y_offset>fullimage_h) y_offset=fullimage_h-1;
+ if(subimage_w!=-1 && (x_offset+subimage_w)>fullimage_w) subimage_w=fullimage_w-x_offset;
+ if(subimage_h!=-1 && (y_offset+subimage_h)>fullimage_h) subimage_h=fullimage_h-y_offset;
+
+ // ASSERTPR(bits != NULL, elementname);
+ if (bits == NULL) {
+ DebugString("element not found ! %s\n", elementname);
+ int n = 10*10;
+ bits = (ARGB32 *)WASABI_API_MEMMGR->sysMalloc(n * 4);
+
+
+ ARGB32 *p = bits;
+ while (n--)
+ *p++ = 0xFFFF00FF;
+ }
+}
+#endif
+
+
+int SkinBitmap::getWidth()
+{
+ if (!image)
+ return 0;
+
+ return CGImageGetWidth(image);
+}
+
+int SkinBitmap::getFullWidth()
+{
+ if (!image)
+ return 0;
+
+ return CGImageGetBytesPerRow(image)/4; // assumes 32bit pixel data
+}
+
+int SkinBitmap::getHeight()
+{
+ if (!image)
+ return 0;
+ return CGImageGetHeight(image);
+}
+
+void SkinBitmap::blit(ifc_canvas *canvas, int x, int y)
+{
+ if (!image)
+ return;
+
+ CGContextRef context = canvas->getHDC();
+ CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
+ CGContextDrawImage(context, rect, image);
+}
+
+void SkinBitmap::blitAlpha(ifc_canvas *canvas, int x, int y, int alpha)
+{
+ if (!image)
+ return;
+
+ float floatAlpha = alpha / 255.f;
+
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+// CGContextTranslateCTM(context, 0, r->bottom);
+// CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextSetAlpha(context, floatAlpha);
+ CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
+ CGContextDrawImage(context, rect, image);
+ CGContextRestoreGState(context);
+}
+
+void SkinBitmap::stretchToRect(ifc_canvas *canvas, RECT *r)
+{
+ if (!image)
+ return;
+
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+ CGContextTranslateCTM (context, 0, r->bottom);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
+ CGContextDrawImage(context, rect, image);
+
+ CGContextRestoreGState(context);
+}
+
+void SkinBitmap::stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha)
+{
+ if (!image)
+ return;
+
+ float floatAlpha = alpha / 255.f;
+
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+ CGContextTranslateCTM (context, 0, r->bottom);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextSetAlpha(context, floatAlpha);
+ CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
+ CGContextDrawImage(context, rect, image);
+ CGContextRestoreGState(context);
+}
+
+void SkinBitmap::stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha)
+{
+ if (!image)
+ return;
+
+ float floatAlpha = alpha / 255.f;
+
+ // make a new image ref clipped to the source rect
+ CGRect srcRect = CGRectMake(src->left, src->top, src->right-src->left, src->bottom-src->top);
+ CGImageRef clippedImage = CGImageCreateWithImageInRect(image, srcRect);
+
+ // blit onto canvas
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+ CGContextTranslateCTM(context, 0, dst->bottom);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextSetAlpha(context, floatAlpha);
+ CGRect rect = CGRectMake(dst->left, dst->top, dst->right-dst->left, dst->bottom-dst->top);
+ CGContextDrawImage(context, rect, clippedImage);
+ CGContextRestoreGState(context);
+
+ // release the reference to our clipped image
+ CGImageRelease(clippedImage);
+}
+
+uint8_t *SkinBitmap::getBits()
+{
+ return static_cast<uint8_t *>(CGBitmapContextGetData(imageContext));
+}
+
+void SkinBitmap::UpdateBits(uint8_t *bits)
+{
+ CGImageRelease(image);
+ image = CGBitmapContextCreateImage(imageContext);
+}
+
+ARGB32 SkinBitmap::getPixel(int x, int y)
+{
+ ARGB32 *array = (ARGB32 *)getBits();
+ return array[x + y*getFullWidth()];
+}
+
+#define CBCLASS SkinBitmap
+START_DISPATCH;
+CB(IFC_BITMAP_GETBITMAP, GetBitmap);
+CB(IFC_BITMAP_GETBITS, getBits);
+VCB(IFC_BITMAP_UPDATEBITS, UpdateBits);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h
new file mode 100644
index 00000000..5a30637e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h
@@ -0,0 +1,47 @@
+#ifndef NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H
+#define NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H
+
+#include <bfc/platform/platform.h>
+#include <tataki/canvas/ifc_canvas.h>
+#include <api/wnd/ifc_bitmap.h>
+
+/*
+ TODO:
+ need some kind of updateBits() so that the underlying image can be updated to reflect changes
+ */
+class SkinBitmap : public ifc_bitmap
+{
+public:
+ SkinBitmap(ARGB32 *bits, int w, int h); // added by benski, use if you have raw image bits
+ SkinBitmap(const wchar_t *elementname, int cached = 1);
+ ~SkinBitmap();
+ int getWidth();
+ int getHeight();
+ int getFullWidth(); // aka pitch
+
+ // blits
+ void blit(ifc_canvas *canvas, int x, int y);
+ void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha = 255);
+ // stretch blits
+ void stretchToRect(ifc_canvas *canvas, RECT *r);
+ void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha = 255);
+ void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
+// tiled blits
+ void blitTile(ifc_canvas *canvas, RECT *dest, int xoffs = 0, int yoffs = 0, int alpha = 255);
+
+ ARGB32 getPixel(int x, int y);
+public: // ifc_bitmap implementations
+ OSBITMAPHANDLE GetBitmap() { return image; }
+ uint8_t *getBits();
+ void UpdateBits(uint8_t *bits);
+
+private:
+ CGImageRef image;
+ CGContextRef imageContext;
+ void *bits;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp
new file mode 100644
index 00000000..43c2984b
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp
@@ -0,0 +1,95 @@
+#include <tataki/canvas/bltcanvas.h>
+
+inline float QuartzBlue(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[0] / 255.f;
+}
+
+inline float QuartzGreen(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[1] / 255.f;
+}
+
+inline float QuartzRed(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[2] / 255.f;
+}
+
+inline float QuartzAlpha(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[3] / 255.f;
+}
+
+BltCanvas::BltCanvas(int width, int height, OSWINDOWHANDLE wnd)
+{
+ CGrafPtr qdcontext = GetWindowPort(wnd);
+ CGContextRef temp;
+ QDBeginCGContext(qdcontext, &temp);
+ CGSize size = CGSizeMake(width, height);
+ layer = CGLayerCreateWithContext(temp, size, NULL);
+ context = CGLayerGetContext(layer);
+ QDEndCGContext(qdcontext, &temp);
+}
+
+void BltCanvas::blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
+{
+ CGPoint point = CGPointMake(dstx-srcx, dsty-srcy);
+ CGContextDrawLayerAtPoint(dest->getHDC(), point, layer);
+}
+
+void BltCanvas::blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha)
+{
+ CGContextRef dest = canvas->getHDC();
+ CGContextSaveGState(dest);
+ CGContextSetAlpha(dest, (float)alpha/255.f);
+ // TODO: deal with width properly
+ CGRect rect = CGRectMake(dst->left - src->left, dst->top - src->top, dst->right - dst->left, dst->bottom - dst->top);
+ CGContextDrawLayerInRect(dest, rect, layer);
+ CGContextRestoreGState(dest);
+}
+
+void BltCanvas::stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
+{
+ CGContextSaveGState(context);
+ CGContextTranslateCTM(context, srcx, srcy);
+ CGRect rect = CGRectMake(dstx, dsty, dstw, dsth);
+ CGContextDrawLayerInRect(dest->getHDC(), rect, layer);
+ CGContextRestoreGState(context);
+}
+
+void BltCanvas::stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha)
+{
+ CGContextRef dest = canvas->getHDC();
+ CGContextSaveGState(dest);
+ CGContextSetAlpha(dest, (float)alpha/255.f);
+// TODO: deal with width properly
+ CGRect rect = CGRectMake(dst->left - src->left, dst->top - src->top, dst->right - dst->left, dst->bottom - dst->top);
+ CGContextDrawLayerInRect(dest, rect, layer);
+ CGContextRestoreGState(dest);
+}
+
+void BltCanvas::DestructiveResize(int w, int h, int nb_bpp)
+{
+ CGSize size = CGSizeMake(w, h);
+ CGLayerRef newlayer = CGLayerCreateWithContext(context, size, NULL);
+ CGContextRelease(context);
+ CGLayerRelease(layer);
+ layer = newlayer;
+ context = CGLayerGetContext(layer);
+}
+
+void BltCanvas::fillBits(ARGB32 color)
+{
+ CGContextSetRGBFillColor(context,
+ QuartzRed(color), // red
+ QuartzGreen(color), // green
+ QuartzBlue(color), // blue
+ QuartzAlpha(color) // alpha
+ );
+
+ CGContextFillRect(context, CGRectInfinite);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp
new file mode 100644
index 00000000..093ab5e5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp
@@ -0,0 +1,275 @@
+#include <bfc/platform/types.h>
+#include <Carbon/Carbon.h>
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/basewnd.h>
+#include <tataki/region/api_region.h>
+
+
+
+/* various functions that might help out
+
+for drawSysObject:
+HIThemeDrawButton
+HIThemeDrawTitleBarWidget for minimize, maximize, exit
+*/
+
+inline float QuartzBlue(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[0] / 255.f;
+}
+
+inline float QuartzGreen(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[1] / 255.f;
+
+}
+
+inline float QuartzRed(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[2] / 255.f;
+
+}
+
+inline float QuartzAlpha(RGB32 color)
+{
+ unsigned char *pixel = (unsigned char *)&color;
+ return pixel[3] / 255.f;
+
+}
+
+Canvas::Canvas(CGrafPtr _context)
+{
+
+}
+
+void Canvas::fillRect(const RECT *r, ARGB32 color)
+{
+ CGContextSetRGBFillColor(context,
+ QuartzRed(color), // red
+ QuartzGreen(color), // green
+ QuartzBlue(color), // blue
+ QuartzAlpha(color) // alpha
+ );
+
+ HIRect rect = HIRectFromRECT(r);
+ CGContextFillRect(context, rect);
+}
+
+void Canvas::fillRgn(api_region *r, ARGB32 color)
+{
+ CGContextSetRGBFillColor(context,
+ QuartzRed(color), // red
+ QuartzGreen(color), // green
+ QuartzBlue(color), // blue
+ QuartzAlpha(color) // alpha
+ );
+
+ HIShapeRef shape = r->getOSHandle();
+ HIShapeReplacePathInCGContext(shape, context);
+ CGContextFillPath(context);
+}
+
+void Canvas::blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
+{
+ // clip dest
+ // Create CGImage from context
+ // CGContextDrawImage
+}
+
+HDC Canvas::getHDC()
+{
+ return context;
+}
+
+void Canvas::selectClipRgn(api_region *r)
+{
+ if (r)
+ {
+ HIShapeRef shape = r->getOSHandle();
+ HIShapeReplacePathInCGContext(shape, context);
+ CGContextClip(context);
+ }
+ else
+ {
+ CGContextClipToRect(context, CGRectInfinite);
+ }
+}
+
+void Canvas::stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
+{
+ // Create CGImage from context
+ // CGContextDrawImage
+}
+
+void Canvas::textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
+{
+ // TODO: turn this code into a svc_fontI, and use api_font here instead
+ size_t len = wcslen(txt);
+ UniChar *unistr = (UniChar *)malloc((len + 1) * sizeof(UniChar));
+ UniChar *copy = unistr;
+ while (*txt)
+ *copy++=*txt++;
+ *copy=0;
+
+ ATSUStyle style;
+ ATSUCreateStyle(&style);
+
+ CGContextSaveGState(context);
+ CGContextSetRGBFillColor(context,
+ QuartzRed(fontInfo->color), // red
+ QuartzGreen(fontInfo->color), // green
+ QuartzBlue(fontInfo->color), // blue
+ QuartzAlpha(fontInfo->color) // alpha
+ );
+
+ ATSUTextLayout layout;
+ ATSUCreateTextLayout(&layout);
+
+ ATSUSetTextPointerLocation(layout, unistr, kATSUFromTextBeginning, kATSUToTextEnd, len);
+
+ ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd);
+
+ Rect imageRect;
+ ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &imageRect);
+ y-=(imageRect.bottom - imageRect.top);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ ATSUAttributeTag tags[] = {kATSUCGContextTag};
+ ATSUAttributeValuePtr values[] = {&context};
+ ByteCount sizes[] = {sizeof(CGContextRef)};
+ ATSUSetLayoutControls(layout, 1, tags, sizes, values);
+ ATSUDrawText(layout, kATSUFromTextBeginning, kATSUToTextEnd, FloatToFixed(x), FloatToFixed(y));
+ ATSUDisposeTextLayout(layout);
+ ATSUDisposeStyle(style);
+ CGContextRestoreGState(context);
+ free(unistr);
+}
+
+void Canvas::drawSysObject(const RECT *r, int sysobj, int alpha)
+{
+#warning TODO
+ using namespace DrawSysObj;
+ switch(sysobj)
+ {
+ case OSBUTTON:
+ {
+ HIRect buttonRect = HIRectFromRECT(r);
+ HIThemeButtonDrawInfo buttonDrawInfo;
+ buttonDrawInfo.version=0;
+ buttonDrawInfo.state = kThemeStateActive;
+ buttonDrawInfo.kind = kThemePushButton;
+ buttonDrawInfo.value = kThemeButtonOn;
+ buttonDrawInfo.adornment = kThemeAdornmentNone;
+ buttonDrawInfo.animation.time.start = 0;
+ buttonDrawInfo.animation.time.current=0;
+ HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0);
+ }
+ break;
+ case OSBUTTON_PUSHED:
+ {
+ HIRect buttonRect = HIRectFromRECT(r);
+ HIThemeButtonDrawInfo buttonDrawInfo;
+ buttonDrawInfo.version=0;
+ buttonDrawInfo.state = kThemeStatePressed;
+ buttonDrawInfo.kind = kThemePushButton;
+ buttonDrawInfo.value = kThemeButtonOn;
+ buttonDrawInfo.adornment = kThemeAdornmentNone;
+ buttonDrawInfo.animation.time.start = 0;
+ buttonDrawInfo.animation.time.current=0;
+ HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0);
+ }
+ break;
+ case OSBUTTON_DISABLED:
+ {
+ HIRect buttonRect = HIRectFromRECT(r);
+ HIThemeButtonDrawInfo buttonDrawInfo;
+ buttonDrawInfo.version=0;
+ buttonDrawInfo.state = kThemeStateInactive;
+ buttonDrawInfo.kind = kThemePushButton;
+ buttonDrawInfo.value = kThemeButtonOn;
+ buttonDrawInfo.adornment = kThemeAdornmentNone;
+ buttonDrawInfo.animation.time.start = 0;
+ buttonDrawInfo.animation.time.current=0;
+ HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0);
+ }
+ break;
+ }
+}
+
+void Canvas::getTextExtent(const wchar_t *text, int *w, int *h, const Wasabi::FontInfo *fontInfo)
+{
+ // TODO: turn this code into a svc_fontI, and use api_font here instead
+ size_t len = wcslen(text);
+ UniChar *unistr = (UniChar *)malloc((len + 1) * sizeof(UniChar));
+ UniChar *copy = unistr;
+ while (*text)
+ *copy++=*text++;
+ *copy=0;
+
+ ATSUStyle style;
+ ATSUCreateStyle(&style);
+
+ ATSUTextLayout layout;
+ ATSUCreateTextLayout(&layout);
+
+ ATSUSetTextPointerLocation(layout, unistr, kATSUFromTextBeginning, kATSUToTextEnd, len);
+
+ ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd);
+
+ Rect imageRect;
+ ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &imageRect);
+ *h=(imageRect.bottom - imageRect.top);
+ *w = (imageRect.right - imageRect.left);
+
+ ATSUDisposeTextLayout(layout);
+ ATSUDisposeStyle(style);
+ free(unistr);
+}
+
+void Canvas::textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
+{
+ textOut(r->left, r->top, txt, fontInfo);
+}
+
+
+#define CBCLASS Canvas
+START_DISPATCH;
+CB(GETHDC, getHDC);
+END_DISPATCH;
+#undef CBCLASS
+
+BaseCloneCanvas::BaseCloneCanvas(ifc_canvas *cloner)
+{
+ if (cloner != NULL) clone(cloner);
+}
+
+int BaseCloneCanvas::clone(ifc_canvas *cloner)
+{
+ ASSERTPR(context == NULL, "can't clone twice");
+ context = cloner->getHDC();
+ CGContextRetain(context);
+// bits = cloner->getBits();
+// cloner->getDim(&width, &height, &pitch);
+ // srcwnd = cloner->getBaseWnd();
+// cloner->getOffsets(&xoffset, &yoffset);
+// setTextFont(cloner->getTextFont());
+// setTextSize(cloner->getTextSize());
+// setTextBold(cloner->getTextBold());
+// setTextOpaque(cloner->getTextOpaque());
+// setTextUnderline(cloner->getTextUnderline());
+// setTextItalic(cloner->getTextItalic());
+// setTextAlign(cloner->getTextAlign());
+// setTextColor(cloner->getTextColor());
+// setTextBkColor(cloner->getTextBkColor());
+ return (context != NULL);
+}
+
+BaseCloneCanvas::~BaseCloneCanvas()
+{
+ CGContextRelease(context);
+ context = NULL;
+}
+
diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp
new file mode 100644
index 00000000..348ba1de
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp
@@ -0,0 +1,217 @@
+#include <Carbon/Carbon.h>
+#include <tataki/region/region.h>
+#include <tataki/bitmap/bitmap.h>
+
+RegionI::RegionI() : rgn(0)
+{
+}
+
+RegionI::RegionI(const RECT *r) : rgn(0)
+{
+ setRect(r);
+}
+
+RegionI::RegionI(HIMutableShapeRef _rgn) : rgn(_rgn)
+{
+}
+
+RegionI::RegionI(HIShapeRef _rgn)
+{
+ rgn=HIShapeCreateMutableCopy(_rgn);
+}
+
+RegionI::~RegionI()
+{
+ if (rgn)
+ CFRelease(rgn);
+}
+
+RegionI::RegionI(RgnHandle qdrgn)
+{
+ HIShapeRef shape = HIShapeCreateWithQDRgn(qdrgn);
+ rgn = HIShapeCreateMutableCopy(shape);
+ CFRelease(shape);
+}
+
+RegionI::RegionI(SkinBitmap *bitmap)
+{
+ // TODO: we need to find a much better way to do this
+ RECT r;
+ r.left=0;
+ r.top=0;
+ r.right=bitmap->getWidth();
+ r.bottom=bitmap->getHeight();
+ setRect(&r);
+}
+
+
+OSREGIONHANDLE RegionI::getOSHandle()
+{
+ if (!rgn)
+ rgn = HIShapeCreateMutable();
+ return rgn;
+}
+
+api_region *RegionI::clone()
+{
+ if (!rgn)
+ return new RegionI();
+ else
+ return new RegionI(HIShapeCreateMutableCopy(rgn));
+}
+
+void RegionI::disposeClone(api_region *r)
+{
+ if (r) // yes we need to check for NULL here because r != static_cast<>(r)
+ delete static_cast<RegionI *>(r);
+}
+
+bool RegionI::ptInRegion(const POINT *pt)
+{
+ if (!rgn)
+ return false;
+ HIPoint hipt = HIPointFromPOINT(pt);
+ return !!HIShapeContainsPoint(rgn, &hipt);
+}
+
+void RegionI::offset(int x, int y)
+{
+ if (!rgn)
+ rgn = HIShapeCreateMutable();
+
+ HIShapeOffset(rgn, x, y);
+}
+
+void RegionI::getBox(RECT *r)
+{
+ if (!rgn) // TODO: we could manually set r to 0,0,0,0
+ rgn = HIShapeCreateMutable();
+
+ HIRect rect;
+ HIShapeGetBounds(rgn, &rect);
+ *r = RECTFromHIRect(&rect);
+}
+
+void RegionI::subtractRegion(const api_region *r)
+{
+ if (rgn)
+ {
+ api_region *reg = const_cast<api_region *>(r);
+ HIShapeRef sub = reg->getOSHandle();
+ HIShapeDifference(rgn,sub, rgn);
+ }
+}
+
+void RegionI::subtractRect(const RECT *r)
+{
+ if (rgn)
+ {
+ HIRect rect = HIRectFromRECT(r);
+ HIShapeRef sub = HIShapeCreateWithRect(&rect);
+ HIShapeDifference(rgn, sub, rgn);
+ }
+}
+
+void RegionI::addRect(const RECT *r)
+{
+ if (!rgn)
+ rgn = HIShapeCreateMutable();
+ HIRect rect = HIRectFromRECT(r);
+ HIShapeRef add = HIShapeCreateWithRect(&rect);
+ HIShapeUnion(rgn, add, rgn);
+}
+
+void RegionI::addRegion(const api_region *r)
+{
+ if (!rgn)
+ rgn = HIShapeCreateMutable();
+ api_region *reg = const_cast<api_region *>(r);
+ HIShapeRef add = reg->getOSHandle();
+ HIShapeUnion(rgn, add, rgn);
+}
+
+void RegionI::andRegion(const api_region *r)
+{
+ if (rgn) // intersection with empty region will always be empty
+ {
+ api_region *reg = const_cast<api_region *>(r);
+ HIShapeRef intersection = reg->getOSHandle();
+ HIShapeIntersect(rgn, intersection, rgn);
+ }
+}
+
+void RegionI::setRect(const RECT *r)
+{
+ if (rgn)
+ CFRelease(rgn);
+ HIRect rect = HIRectFromRECT(r);
+ HIShapeRef rectRgn = HIShapeCreateWithRect(&rect);
+ rgn = HIShapeCreateMutableCopy(rectRgn);
+ CFRelease(rectRgn);
+}
+
+void RegionI::empty()
+{
+ if (rgn)
+ CFRelease(rgn);
+ rgn=0;
+}
+
+int RegionI::isEmpty()
+{
+ if (!rgn)
+ return 1;
+ return !!HIShapeIsEmpty(rgn);
+}
+
+int RegionI::isRect()
+{
+ if (!rgn)
+ return 1;
+ return !!HIShapeIsRectangular(rgn);
+}
+
+int RegionI::intersectRgn(const api_region *r, api_region *intersection)
+{
+ intersection->empty();
+ intersection->addRegion(this);
+ intersection->andRegion(r);
+ return !intersection->isEmpty();
+}
+
+int RegionI::intersectRect(const RECT *r, api_region *intersection)
+{
+ intersection->setRect(r);
+ intersection->andRegion(this);
+ return !intersection->isEmpty();
+}
+
+#define CBCLASS RegionI
+START_DISPATCH;
+CB(REGION_GETOSHANDLE, getOSHandle);
+CB(REGION_CLONE, clone);
+VCB(REGION_DISPOSECLONE, disposeClone);
+CB(REGION_PTINREGION, ptInRegion);
+VCB(REGION_OFFSET, offset);
+VCB(REGION_GETBOX, getBox);
+VCB(REGION_SUBTRACTRGN, subtractRegion);
+VCB(REGION_SUBTRACTRECT, subtractRect);
+VCB(REGION_ADDRECT, addRect);
+VCB(REGION_ADD, addRegion);
+VCB(REGION_AND, andRegion);
+VCB(REGION_SETRECT, setRect);
+VCB(REGION_EMPTY, empty);
+CB(REGION_ISEMPTY, isEmpty);
+CB(REGION_ISRECT, isRect);
+CB(REGION_INTERSECTRGN, intersectRgn);
+CB(REGION_INTERSECTRECT, intersectRect);
+END_DISPATCH;
+#undef CBCLASS
+
+#define CBCLASS RegionServerI
+START_DISPATCH;
+VCB(REGIONSERVER_ADDREF, addRef);
+VCB(REGIONSERVER_DELREF, delRef);
+CB(REGIONSERVER_GETREGION, getRegion);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/platform/osx/region.h b/Src/Wasabi/api/wnd/platform/osx/region.h
new file mode 100644
index 00000000..9879b642
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/osx/region.h
@@ -0,0 +1,115 @@
+#ifndef __REGION_H
+#define __REGION_H
+
+#include <Carbon/Carbon.h>
+#include <bfc/platform/platform.h>
+#include <tataki/region/api_region.h>
+
+class SkinBitmap;
+
+class RegionI : public api_region
+{
+public:
+ RegionI();
+ RegionI(const RECT *r);
+ RegionI(RgnHandle qdrgn);
+ RegionI(HIShapeRef _rgn);
+ RegionI(SkinBitmap *bitmap);
+ ~RegionI();
+
+ // api_region
+ OSREGIONHANDLE getOSHandle();
+ api_region *clone();
+ void disposeClone(api_region *r);
+ bool ptInRegion(const POINT *pt);
+ void offset(int x, int y);
+ void getBox(RECT *r);
+ void subtractRegion(const api_region *r);
+ void subtractRect(const RECT *r);
+ void addRect(const RECT *r);
+ void addRegion(const api_region *r);
+ void andRegion(const api_region *r);
+ void setRect(const RECT *r);
+ void empty();
+ int isEmpty();
+ int equals(const api_region *r);
+ int enclosed(const api_region *r, api_region *outside = NULL);
+ int intersectRgn(const api_region *r, api_region *intersection);
+ int doesIntersectRgn(const api_region *r);
+ int intersectRect(const RECT *r, api_region *intersection);
+
+ int isRect();
+ void scale(double sx, double sy, bool round = 0);
+ void debug(int async = 0);
+ OSREGIONHANDLE makeWindowRegion(); // gives you a handle to a clone of the OSREGION object so you can insert it into a window's region with SetWindowRgn. ANY other use is prohibited
+
+ // this is how you can enumerate the subrects that compose to make up the
+ // entire region
+ int getNumRects();
+ int enumRect(int n, RECT *r);
+
+
+private:
+ RegionI(HIMutableShapeRef _rgn);
+ HIMutableShapeRef rgn;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+// TODO: we could take of advantage of HIShapeRef's built in reference counting to implement this
+class RegionServer : public Dispatchable {
+
+protected:
+ RegionServer() {}
+ virtual ~RegionServer() {}
+
+public:
+
+ void addRef(void *client);
+ void delRef(void *client);
+ api_region *getRegion();
+
+ enum {
+ REGIONSERVER_ADDREF = 500,
+ REGIONSERVER_DELREF = 550,
+ REGIONSERVER_GETREGION = 600,
+ };
+};
+
+inline void RegionServer::addRef(void *client) {
+ _voidcall(REGIONSERVER_ADDREF, (api_region *)NULL, client);
+}
+
+inline void RegionServer::delRef(void *client) {
+ _voidcall(REGIONSERVER_DELREF, client);
+}
+
+inline api_region * RegionServer::getRegion() {
+ return _call(REGIONSERVER_GETREGION, (api_region *)NULL);
+}
+
+class RegionServerI : public RegionServer {
+public :
+
+ RegionServerI() { numrefs = 0; }
+ virtual ~RegionServerI() {}
+
+ virtual void addRef(void *client) { numrefs++; }
+ virtual void delRef(void *client) { numrefs--; }
+ virtual api_region *getRegion()=0;
+
+ virtual int getNumRefs() { return numrefs; }
+
+protected:
+
+ RECVS_DISPATCH;
+
+private:
+
+ int numrefs;
+};
+#endif
+
+
diff --git a/Src/Wasabi/api/wnd/platform/win32/bitmap.h b/Src/Wasabi/api/wnd/platform/win32/bitmap.h
new file mode 100644
index 00000000..589f9a13
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/win32/bitmap.h
@@ -0,0 +1,81 @@
+//NONPORTABLE
+#ifndef _BITMAP_H
+#define _BITMAP_H
+
+//#include <wasabicfg.h>
+//#include <bfc/common.h>
+#include <bfc/string/string.h>
+#include <bfc/string/StringW.h>
+
+class ifc_canvas; // see canvas.h
+
+//#define NO_MMX
+
+class api_region;
+
+// a skinnable bitmap
+class SkinBitmap
+{
+public:
+#ifndef _NOSTUDIO
+#ifdef WASABI_COMPILE_IMGLDR
+#ifdef _WIN32
+ SkinBitmap(HINSTANCE hInst, int _id, const wchar_t *colorgroup = NULL); //NONPORTABLE
+#endif
+ SkinBitmap(const wchar_t *elementname, int cached = 1);
+#endif
+#endif
+ // SkinBitmap(SkinBitmap *source, int w, int h);
+ SkinBitmap(int w, int h, ARGB32 bgcolor = RGBA(255,255,255,255)); //untested --BU
+#ifdef _WIN32
+ SkinBitmap(HBITMAP bitmap);
+ SkinBitmap(HBITMAP bitmap, HDC dc, int has_alpha = 0, void *bits = NULL);
+#endif
+ SkinBitmap(ARGB32 *bits, int w, int h); // added by benski, use if you have raw image bits
+ ~SkinBitmap();
+
+int getWidth() const { return subimage_w == -1 ? fullimage_w : subimage_w; };
+int getHeight() const { return subimage_h == -1 ? fullimage_h : subimage_h; };
+ int getFullWidth() const { return fullimage_w; };
+ int getFullHeight() const { return fullimage_h; };
+int getX() const { return x_offset == -1 ? 0 : x_offset; };
+int getY() const { return y_offset == -1 ? 0 : y_offset; };
+ int getBpp() const { return 32; };
+ int getAlpha() const { return has_alpha; };
+ void setHasAlpha(int ha);
+ virtual void *getBits();
+ int isInvalid();
+
+ const wchar_t *getBitmapName();
+
+ void blit(ifc_canvas *canvas, int x, int y);
+ void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha = 255);
+ // blits a chunk of source into dest rect
+ void blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
+ void blitTile(ifc_canvas *canvas, RECT *dest, int xoffs = 0, int yoffs = 0, int alpha = 255);
+ void blitRectToTile(ifc_canvas *canvas, RECT *dest, RECT *src, int xoffs = 0, int yoffs = 0, int alpha = 255);
+ void stretch(ifc_canvas *canvas, int x, int y, int w, int h);
+ void stretchToRect(ifc_canvas *canvas, RECT *r);
+ void stretchRectToRect(ifc_canvas *canvas, RECT *src, RECT *dst);
+
+ void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha = 255);
+ void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
+ ARGB32 getPixel(int x, int y);
+
+private:
+#ifdef _WIN32
+ void bmpToBits(HBITMAP hbmp, HDC defaultDC = NULL);
+#endif
+
+ int has_alpha;
+
+ int x_offset, y_offset, subimage_w, subimage_h, fullimage_w, fullimage_h;
+
+ ARGB32 *bits;
+ int ownbits;
+ int last_failed;
+ StringW bitmapname;
+ int fromskin;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/platform/win32/canvas.h b/Src/Wasabi/api/wnd/platform/win32/canvas.h
new file mode 100644
index 00000000..e6dea753
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/win32/canvas.h
@@ -0,0 +1 @@
+#include <tataki/canvas/win/canvas.h>
diff --git a/Src/Wasabi/api/wnd/platform/win32/region.h b/Src/Wasabi/api/wnd/platform/win32/region.h
new file mode 100644
index 00000000..88491634
--- /dev/null
+++ b/Src/Wasabi/api/wnd/platform/win32/region.h
@@ -0,0 +1,135 @@
+#ifndef __REGION_H
+#define __REGION_H
+
+#include <api/wnd/bitmap.h>
+#include <bfc/dispatch.h>
+
+class BaseWnd;
+class Canvas;
+class api_region;
+class RegionServer;
+
+#include "api_region.h"
+
+class RegionI : public api_region
+{
+public:
+ RegionI();
+ RegionI(const RegionI *copy);
+ RegionI(const RECT *r);
+ RegionI(int l, int t, int r, int b);
+ RegionI(OSREGIONHANDLE region);
+ RegionI(SkinBitmap *bitmap, RECT *r=NULL, int xoffset=0, int yoffset=0, bool inverted=false, int dothreshold=0, __int8 threshold=0, int threversed=0, int minalpha=1);
+ RegionI(Canvas *c, RECT *defboundbox=NULL);
+ virtual ~RegionI();
+
+ api_region *clone();
+ void disposeClone(api_region *r);
+ bool ptInRegion(const POINT *pt);
+ void offset(int x, int y);
+ void getBox(RECT *r);
+ void subtractRegion(const api_region *reg);
+ void subtractRect(const RECT *r);
+ void addRect(const RECT *r);
+ void addRegion(const api_region *r);
+ void andRegion(const api_region *r);
+ void setRect(const RECT *r);
+ void empty();
+ int isEmpty();
+ int equals(const api_region *r);
+ int enclosed(const api_region *r, api_region *outside=NULL);
+ int intersectRgn(const api_region *r, api_region *intersection);
+ int doesIntersectRgn(const api_region *r);
+ int intersectRect(const RECT *r, api_region *intersection);
+ int doesIntersectRect(const RECT *r);
+ int isRect();
+ void scale(double sx, double sy, bool round=0);
+ void debug(int async=0);
+
+ // NONPORTABLE
+
+ OSREGIONHANDLE makeWindowRegion(); // gives you a handle to a clone of the OSREGION object so you can insert it into a window's region with SetWindowRgn. ANY other use is prohibited
+ OSREGIONHANDLE getOSHandle(); // avoid as much as you can, should be used only by WIN32-dependant classes
+
+ // END NONPORTABLE
+
+ int getNumRects();
+ int enumRect(int n, RECT *r);
+
+ OSREGIONHANDLE alphaToRegionRect(void *pbits32, int bmX, int bmY, int bmWidth, int bmHeight, int fullw, int fullh, int xoffset, int yoffset, bool portion, int _x, int _y, int _w, int _h, bool inverted, int dothreshold, unsigned __int8 threshold, int thinverse, int minalpha);
+
+private:
+
+ inline void init();
+ void optimize();
+ void deoptimize();
+
+ OSREGIONHANDLE hrgn;
+ OSREGIONHANDLE alphaToRegionRect(SkinBitmap *bitmap, int xoffset, int yoffset, bool portion, int _x, int _y, int _w, int _h, bool inverted=false, int dothreshold=0, unsigned __int8 threshold=0, int thinverse=0, int minalpha=1/* 1..255*/);
+ RECT overlay;
+ int clonecount;
+ RegionI *lastdebug;
+ RegionServer *srv;
+ RECT optrect;
+ int optimized;
+
+protected:
+
+ RECVS_DISPATCH;
+};
+
+class RegionServer : public Dispatchable {
+
+ protected:
+ RegionServer() {}
+ virtual ~RegionServer() {}
+
+ public:
+
+ void addRef(void *client);
+ void delRef(void *client);
+ api_region *getRegion();
+
+ enum {
+ REGIONSERVER_ADDREF = 500,
+ REGIONSERVER_DELREF = 550,
+ REGIONSERVER_GETREGION = 600,
+ };
+};
+
+inline void RegionServer::addRef(void *client) {
+ _voidcall(REGIONSERVER_ADDREF, (api_region *)NULL, client);
+}
+
+inline void RegionServer::delRef(void *client) {
+ _voidcall(REGIONSERVER_DELREF, client);
+}
+
+inline api_region * RegionServer::getRegion() {
+ return _call(REGIONSERVER_GETREGION, (api_region *)NULL);
+}
+
+class RegionServerI : public RegionServer {
+ public :
+
+ RegionServerI() { numrefs = 0; }
+ virtual ~RegionServerI() {}
+
+ virtual void addRef(void *client) { numrefs++; }
+ virtual void delRef(void *client) { numrefs--; }
+ virtual api_region *getRegion()=0;
+
+ virtual int getNumRefs() { return numrefs; }
+
+ protected:
+
+ RECVS_DISPATCH;
+
+ private:
+
+ int numrefs;
+};
+
+#endif
+
+
diff --git a/Src/Wasabi/api/wnd/popexitcb.cpp b/Src/Wasabi/api/wnd/popexitcb.cpp
new file mode 100644
index 00000000..45c9b8b2
--- /dev/null
+++ b/Src/Wasabi/api/wnd/popexitcb.cpp
@@ -0,0 +1,8 @@
+#include <precomp.h>
+#include "popexitcb.h"
+
+#define CBCLASS PopupExitCallbackI
+START_DISPATCH;
+ CB(POPUPEXIT_ONEXITPOPUP, popupexitcb_onExitPopup);
+ CB(POPUPEXIT_GETDEPENDENCYPTR, popupexit_getDependencyPtr);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/wnd/popexitcb.h b/Src/Wasabi/api/wnd/popexitcb.h
new file mode 100644
index 00000000..bbd9de0d
--- /dev/null
+++ b/Src/Wasabi/api/wnd/popexitcb.h
@@ -0,0 +1,40 @@
+#ifndef _POPUPCB_H
+#define _POPUPCB_H
+
+#include <bfc/common.h>
+#include <bfc/dispatch.h>
+
+class ifc_dependent;
+
+class PopupExitCallback : public Dispatchable {
+ public:
+
+ int popupexitcb_onExitPopup();
+ ifc_dependent *popupexit_getDependencyPtr();
+
+ enum {
+ POPUPEXIT_ONEXITPOPUP=100,
+ POPUPEXIT_GETDEPENDENCYPTR=110,
+ };
+};
+
+inline int PopupExitCallback::popupexitcb_onExitPopup() {
+ return _call(POPUPEXIT_ONEXITPOPUP, 0);
+}
+
+inline ifc_dependent *PopupExitCallback::popupexit_getDependencyPtr() {
+ return _call(POPUPEXIT_GETDEPENDENCYPTR, (ifc_dependent *)NULL);
+}
+
+class PopupExitCallbackI : public PopupExitCallback {
+ public:
+
+ virtual int popupexitcb_onExitPopup()=0;
+ virtual ifc_dependent *popupexit_getDependencyPtr()=0;
+
+ protected:
+
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/popexitchecker.cpp b/Src/Wasabi/api/wnd/popexitchecker.cpp
new file mode 100644
index 00000000..31ec91a6
--- /dev/null
+++ b/Src/Wasabi/api/wnd/popexitchecker.cpp
@@ -0,0 +1,79 @@
+#include <precomp.h>
+#include "popexitchecker.h"
+#include <api/wnd/popexitcb.h>
+#include <api/wnd/api_window.h>
+#include <api/syscb/callbacks/syscbi.h>
+#include <api/wnd/wndtrack.h>
+
+//PopupExitChecker *popupExitChecker;
+
+PopupExitChecker::PopupExitChecker() {
+}
+
+PopupExitChecker::~PopupExitChecker() {
+ watchers.deleteAll();
+}
+
+void PopupExitChecker::registerCallback(PopupExitCallback *cb, ifc_window *watched) {
+ ifc_dependent *a = cb->popupexit_getDependencyPtr();
+ ifc_dependent *b = watched->getDependencyPtr();
+ watchers.addItem(new PopupExitCallbackEntry(cb, watched, a, b));
+ viewer_addViewItem(a);
+ viewer_addViewItem(b);
+}
+
+int PopupExitChecker::check(ifc_window *w) {
+ int n=0;
+ foreach(watchers)
+ PopupExitCallbackEntry *e = watchers.getfor();
+ if (w != e->watched && !isGrandChildren(e->watched, w)) {
+ e->cb->popupexitcb_onExitPopup();
+ n++;
+ }
+ endfor;
+ return n > 0;
+}
+
+void PopupExitChecker::signal() {
+ foreach(watchers)
+ watchers.getfor()->cb->popupexitcb_onExitPopup();
+ endfor;
+}
+
+int PopupExitChecker::isGrandChildren(ifc_window *parent, ifc_window *child) {
+ int i;
+ for (i=0;i<parent->getNumRootWndChildren();i++) {
+ if (parent->enumRootWndChildren(i) == child) return 1;
+ }
+
+ for (i=0;i<parent->getNumRootWndChildren();i++) {
+ ifc_window *w = parent->enumRootWndChildren(i);
+ int r = 0;
+ if (w->getNumRootWndChildren() > 0) r = isGrandChildren(w, child);
+ if (r) return 1;
+ }
+ return 0;
+}
+
+int PopupExitChecker::viewer_onItemDeleted(ifc_dependent *item) {
+ for (int i=0;i<watchers.getNumItems();i++) {
+ PopupExitCallbackEntry *e = watchers.enumItem(i);
+ if (e->cbd == item || e->wd == item) {
+ watchers.removeByPos(i); i--;
+ delete e;
+ // no break, wnd can be watched by many people
+ }
+ }
+ return 0;
+}
+
+void PopupExitChecker::deregisterCallback(PopupExitCallback *cb) {
+ for (int i=0;i<watchers.getNumItems();i++) {
+ PopupExitCallbackEntry *e = watchers.enumItem(i);
+ if (e->cb == cb) {
+ watchers.removeByPos(i); i--;
+ delete e;
+ // no break, watcher can watch many windows, but wait, there cannot be 2 popups at once on a screen! who says so ?
+ }
+ }
+}
diff --git a/Src/Wasabi/api/wnd/popexitchecker.h b/Src/Wasabi/api/wnd/popexitchecker.h
new file mode 100644
index 00000000..861aa592
--- /dev/null
+++ b/Src/Wasabi/api/wnd/popexitchecker.h
@@ -0,0 +1,39 @@
+#ifndef __POPUPEXITCHECKER_H
+#define __POPUPEXITCHECKER_H
+
+#include <bfc/depend.h>
+#include <bfc/ptrlist.h>
+
+class ifc_window;
+class PopupExitCallback;
+
+class PopupExitCallbackEntry
+{
+public:
+ PopupExitCallbackEntry(PopupExitCallback *_cb, ifc_window *_watched, api_dependent *_cbd, api_dependent *_wd) : cb(_cb), watched(_watched), cbd(_cbd), wd(_wd) {}
+ virtual ~PopupExitCallbackEntry() {}
+
+ PopupExitCallback *cb;
+ ifc_window *watched;
+ api_dependent *cbd;
+ api_dependent *wd;
+};
+
+class PopupExitChecker : public DependentViewerI
+{
+public:
+ PopupExitChecker();
+ virtual ~PopupExitChecker();
+
+ void registerCallback(PopupExitCallback *cb, ifc_window *watched);
+ void deregisterCallback(PopupExitCallback *cb);
+#undef check
+ int check(ifc_window *w);
+ void signal();
+ int isGrandChildren(ifc_window *parent, ifc_window *child); // recursive
+ PtrList<PopupExitCallbackEntry> watchers;
+
+ virtual int viewer_onItemDeleted(api_dependent *item);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/popup.cpp b/Src/Wasabi/api/wnd/popup.cpp
new file mode 100644
index 00000000..1019fa91
--- /dev/null
+++ b/Src/Wasabi/api/wnd/popup.cpp
@@ -0,0 +1,1720 @@
+#include <precomp.h>
+#include <api/wnd/api_window.h>
+#include <api/locales/xlatstr.h>
+
+#ifndef WASABI_WANT_FF_POPUP
+
+#include "popup.h"
+#ifdef _WIN32
+#include "../../../Plugins/General/gen_ff/wa2frontend.h"
+extern HINSTANCE hInstance;
+#endif
+PopupMenu::PopupMenu()
+{
+ hmenu = NULL;
+ parent = NULL;
+}
+
+PopupMenu::PopupMenu(ifc_window *_parent)
+{
+ hmenu = NULL;
+ parent = _parent;
+}
+
+PopupMenu::PopupMenu(PopupMenu *_parent)
+{
+ hmenu = NULL;
+ parent = _parent->getParent();
+}
+
+PopupMenu::~PopupMenu()
+{
+ invalidateMenu();
+ entries.deleteAll();
+ sortedentries.removeAll();
+}
+
+void PopupMenu::addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled)
+{
+ invalidateMenu();
+ PopupMenuEntry *e = new PopupMenuEntry(text, -1, menu, 0, disabled);
+ entries.addItem(e);
+ sortedentries.addItem(e);
+}
+
+void PopupMenu::addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param)
+{
+ invalidateMenu();
+ PopupMenuEntry *e = new PopupMenuEntry(text, -1, NULL, 0, 0, cb, param);
+ entries.addItem(e);
+ sortedentries.addItem(e);
+}
+
+void PopupMenu::addCommand(const wchar_t *text, int command, int checked, int disabled, int addpos)
+{
+ invalidateMenu();
+ PopupMenuEntry *e = new PopupMenuEntry(text, command, NULL, checked, disabled);
+ entries.addItem(e);
+ sortedentries.addItem(e, addpos);
+}
+
+void PopupMenu::addSeparator(int addpos)
+{
+ invalidateMenu();
+ PopupMenuEntry *e = new PopupMenuEntry(NULL, -1, NULL, 0, 0);
+ entries.addItem(e);
+ sortedentries.addItem(e, addpos);
+};
+
+void PopupMenu::checkCommand(int cmd, int check)
+{
+ invalidateMenu();
+ PopupMenuEntry *e = sortedentries.findItem((const wchar_t *) & cmd);
+ if (e) e->setChecked(check);
+}
+
+void PopupMenu::disableCommand(int cmd, int disable)
+{
+ invalidateMenu();
+ PopupMenuEntry *e = sortedentries.findItem((const wchar_t *) & cmd);
+ if (e) e->setDisabled(disable);
+}
+
+int PopupMenu::popAtXY(int x, int y, int native)
+{
+ rebuildMenu();
+#ifdef _WIN32
+ if (!native)
+ return DoTrackPopup(getOSMenuHandle(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd())) - 1;
+ else
+ return TrackPopupMenuEx(getOSMenuHandle(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd()), NULL) - 1;
+#elif defined(__APPLE__)
+ return PopUpMenuSelect(getOSMenuHandle(), x, y, 0);
+#endif
+}
+
+int PopupMenu::popAnchored(int type)
+{ // dropped off the sourceWnd given above
+#ifdef _WIN32
+ int flag = 0;
+ switch (type)
+ {
+ case POPUP_ANCHOR_UL: flag |= TPM_LEFTALIGN | TPM_TOPALIGN; break;
+ case POPUP_ANCHOR_LL: flag |= TPM_LEFTALIGN | TPM_BOTTOMALIGN; break;
+ case POPUP_ANCHOR_UR: flag |= TPM_RIGHTALIGN | TPM_TOPALIGN; break;
+ case POPUP_ANCHOR_LR: flag |= TPM_RIGHTALIGN | TPM_BOTTOMALIGN; break;
+ }
+#endif
+ rebuildMenu();
+ int x, y;
+ Wasabi::Std::getMousePos(&x, &y);
+ #ifdef _WIN32
+ return DoTrackPopup(getOSMenuHandle(), flag | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd())) - 1;
+#elif defined(__APPLE__)
+ return PopUpMenuSelect(getOSMenuHandle(), x, y, 0);
+#endif
+}
+
+int PopupMenu::popAtMouse()
+{
+ rebuildMenu();
+ int x, y;
+ Wasabi::Std::getMousePos(&x, &y);
+#ifdef _WIN32
+ return DoTrackPopup(getOSMenuHandle(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd())) - 1;
+#elif defined(__APPLE__)
+ return PopUpMenuSelect(getOSMenuHandle(), x, y, 0);
+#endif
+}
+
+int PopupMenu::getNumCommands()
+{
+ return entries.getNumItems();
+}
+
+const wchar_t *PopupMenu::getCommandText(int command)
+{
+ PopupMenuEntry *e = sortedentries.findItem((const wchar_t *) &command);
+ if (e) return e->getText();
+ return NULL;
+}
+
+OSMENUHANDLE PopupMenu::getOSMenuHandle()
+{
+ rebuildMenu();
+ return hmenu;
+}
+
+void PopupMenu::rebuildMenu()
+{
+#ifdef WIN32
+ if (hmenu != NULL) return ;
+ hmenu = CreatePopupMenu();
+ int i = 0;
+ foreach(entries)
+ PopupMenuEntry *e = entries.getfor();
+ OSMENUHANDLE submenu = NULL;
+ if (e->getCallback())
+ {
+ PopupMenu *m = e->getCallback()->popupMenuCallback(this, e->getCallbackParam());
+ if (m) submenu = m->getOSMenuHandle();
+ }
+ else if (e->isSubmenu())
+ {
+ submenu = e->getSubmenu()->getOSMenuHandle();
+ }
+ InsertMenuW(hmenu, i++, MF_BYPOSITION | (e->getChecked() ? MF_CHECKED : MF_UNCHECKED) | (e->getDisabled() ? MF_GRAYED : 0) | (e->isSeparator() ? MF_SEPARATOR : (e->isSubmenu() ? MF_POPUP : 0) | (e->getText() ? MF_STRING : 0)), e->isSubmenu() ? (UINT_PTR)submenu : e->getCommand() + 1, e->getText());
+ endfor;
+#else
+ if (hmenu != NULL) return ;
+ CreateNewMenu(0, 0, &hmenu);
+
+ foreach(entries)
+ PopupMenuEntry *e = entries.getfor();
+ OSMENUHANDLE submenu = NULL;
+ if (e->getCallback())
+ {
+ PopupMenu *m = e->getCallback()->popupMenuCallback(this, e->getCallbackParam());
+ if (m) submenu = m->getOSMenuHandle();
+ }
+ else if (e->isSubmenu())
+ {
+ submenu = e->getSubmenu()->getOSMenuHandle();
+ }
+
+ const wchar_t *name = e->getText();
+ CFStringRef menuStr = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)name, wcslen(name)*sizeof(wchar_t), kCFStringEncodingUTF32, false);
+ MenuItemIndex newMenuItem;
+ MenuItemAttributes menuAttr = kMenuItemAttrIgnoreMeta;
+ if (e->getDisabled())
+ menuAttr|=kMenuItemAttrDisabled;
+ if (e->isSeparator())
+ menuAttr|=kMenuItemAttrSeparator;
+
+ AppendMenuItemTextWithCFString(hmenu, menuStr, menuAttr, e->getCommand(), &newMenuItem);
+ if (submenu)
+ SetMenuItemHierarchicalMenu(hmenu, newMenuItem, submenu);
+
+ if (e->getChecked())
+ CheckMenuItem(hmenu, newMenuItem, true);
+
+ CFRelease(menuStr);
+ endfor;
+#endif
+}
+
+void PopupMenu::invalidateMenu()
+{
+#ifdef WIN32
+ if (hmenu) DestroyMenu(hmenu);
+#elif defined(__APPLE__)
+ if (hmenu) DisposeMenu(hmenu);
+#endif
+ hmenu = NULL;
+}
+
+void PopupMenu::abort()
+{
+#ifdef WIN32
+ HWND w = (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd());
+
+ PostMessage(w, WM_LBUTTONDOWN, 0, 0xdeadc0de);
+ PostMessage(w, WM_LBUTTONUP, 0, 0xdeadc0de);
+
+#elif defined(__APPLE__)
+ CancelMenuTracking(hmenu, true, 0);
+#endif
+}
+
+#else // WASABI_WANT_FF_POPUP
+
+#include <bfc/api/api_wnd.h>
+#include <bfc/api/api_syscb.h>
+#include "popup.h"
+#include <bfc/notifmsg.h>
+
+#include <studio/assert.h>
+#include <studio/api.h>
+
+#include <bfc/wasabi_std.h>
+#include <common/xlatstr.h>
+#include <bfc/wnds/buttwnd.h>
+
+#include <bfc/util/pathparse.h>
+#include <bfc/attribs/cfgitem.h>
+
+#include <common/script/c_script/c_guiobject.h>
+#include <common/script/c_script/c_menubutton.h>
+#include <common/script/scriptguid.h>
+#include <common/menusurface.h>
+
+#ifndef WANT_NEW_POPUPMENU
+#define SELMARGIN 1
+
+// todo:
+// check marks
+// more?
+
+PopupMenu::PopupMenu(ifc_window *sourceWnd)
+{
+ ASSERT(sourceWnd != NULL);
+ setStartHidden(1);
+ setRenderRatio(1.0);
+ parentRootWnd = sourceWnd;
+ parentWnd = sourceWnd->getOsWindowHandle();
+ reverse_side = 0;
+ kbdhooked = 0;
+ keyctrl = 0;
+ toplevelmenu = 0;
+ chainmenu = NULL;
+ lastxy.x = lastxy.y = -1;
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+ init(sourceWnd->getOsModuleHandle(), parentWnd, TRUE);
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+}
+
+PopupMenu::PopupMenu()
+{
+ setStartHidden(1);
+ setRenderRatio(1.0);
+ parentRootWnd = NULL;
+ parentWnd = INVALIDOSWINDOWHANDLE;
+ chainmenu = NULL;
+ reverse_side = 0;
+ kbdhooked = 0;
+ toplevelmenu = 0;
+ keyctrl = 0;
+ lastxy.x = lastxy.y = -1;
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+ init(hInstance, WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE);
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+}
+
+PopupMenu::PopupMenu(HWND sourceWnd)
+{
+ parentRootWnd = NULL;
+ parentWnd = sourceWnd;
+ setStartHidden(1);
+ setRenderRatio(1.0);
+ reverse_side = 0;
+ kbdhooked = 0;
+ toplevelmenu = 0;
+ keyctrl = 0;
+ chainmenu = NULL;
+ lastxy.x = lastxy.y = -1;
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+ init(hInstance, sourceWnd, TRUE);
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+}
+
+PopupMenu::PopupMenu(PopupMenu *sourceWnd)
+{
+ parentRootWnd = sourceWnd;
+ parentWnd = sourceWnd->gethWnd();
+ setStartHidden(1);
+ setRenderRatio(1.0);
+ reverse_side = 0;
+ kbdhooked = 0;
+ toplevelmenu = 0;
+ chainmenu = NULL;
+ keyctrl = 0;
+ lastxy.x = lastxy.y = -1;
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+ init(sourceWnd, TRUE);
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+}
+
+int PopupMenu::onInit()
+{
+ POPUPMENU_PARENT::onInit();
+ bdown = 0;
+ lastitem = -1;
+ rcp = 0;
+ openmenuid = -1;
+ timerset = 0;
+ timeritem = -1;
+ rcode = -1;
+ toplevelmenu = 0;
+ disable_autopop = 0;
+ popupdelay = 250; //TODO: Config
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ setTransparency(_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), "Popup menu alpha", 255));
+#else
+setTransparency(255);
+#endif
+
+ tex = "wasabi.popup.menu.background";
+ ful = "wasabi.popup.menu.border.topLeft";
+ fur = "wasabi.popup.menu.border.topRight";
+ fll = "wasabi.popup.menu.border.bottomLeft";
+ flr = "wasabi.popup.menu.border.bottomRight";
+ fl = "wasabi.popup.menu.border.left";
+ fr = "wasabi.popup.menu.border.right";
+ ft = "wasabi.popup.menu.border.top";
+ fb = "wasabi.popup.menu.border.bottom";
+ sl = "wasabi.popup.menu.selection.left";
+ sr = "wasabi.popup.menu.selection.right";
+ sc = "wasabi.popup.menu.selection.center";
+
+ return 1;
+}
+
+PopupMenu::~PopupMenu()
+{
+ if (kbdhooked)
+ {
+ WASABI_API_WND->unhookKeyboard(this);
+ kbdhooked = 0;
+ }
+ int x, n;
+ n = items.getNumItems();
+ for (x = 0; x < n; x ++)
+ {
+ if (items[x])
+ {
+ if (items[x]->butt) delete items[x]->butt;
+ if (items[x]->menu) delete items[x]->menu;
+ delete items[x];
+ }
+ }
+}
+
+void PopupMenu::addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled)
+{
+ ASSERT(text != NULL);
+ ButtonWnd *b = new ButtonWnd();
+ b->init(this);
+ b->setParent(this);
+ b->setNotifyId( -1);
+ b->setButtonText(translateButtonText(text), 14);
+ // b->setTextJustification(BUTTONJUSTIFY_LEFT);
+ b->setTextAlign(TEXTALIGN_LEFT);
+ b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
+ if (disabled) b->enableButton(FALSE);
+ ItemT *t = new ItemT;
+ t->issep = 0;
+ t->butt = b;
+ t->menu = menu;
+ t->cmd = -1;
+ t->cb = NULL;
+ items.addItem(t);
+}
+
+void PopupMenu::addSubMenuImage(PopupMenu *menu, const char *bitmap, const char *pushedbitmap, const char *highlightbitmap)
+{
+ ButtonWnd *b = new ButtonWnd();
+ b->init(this);
+ b->setParent(this);
+ b->setBitmaps(bitmap, pushedbitmap, highlightbitmap);
+ b->setBitmapCenter(1);
+ b->setNotifyId( -1);
+ b->setAutoDim(1);
+ b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
+ ItemT *t = new ItemT;
+ t->issep = 0;
+ t->butt = b;
+ t->menu = menu;
+ t->cb = NULL;
+ t->cmd = -1;
+ items.addItem(t);
+}
+
+void PopupMenu::addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param)
+{
+ ASSERT(text != NULL);
+ ASSERT(cb != NULL);
+ ButtonWnd *b = new ButtonWnd();
+ b->init(this);
+ b->setParent(this);
+ b->setNotifyId( -1);
+ b->setButtonText(translateButtonText(text), 14);
+ // b->setTextJustification(BUTTONJUSTIFY_LEFT);
+ b->setTextAlign(TEXTALIGN_LEFT);
+ b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
+ ItemT *t = new ItemT;
+ t->issep = 0;
+ t->butt = b;
+ t->menu = 0;
+ t->cb = cb;
+ t->cbparam = param;
+ t->cmd = -1;
+ items.addItem(t);
+}
+
+void PopupMenu::addSeparator(int addpos)
+{
+ ButtonWnd *b = new ButtonWnd();
+ b->init(this);
+ b->setParent(this);
+ b->setNotifyId( -1);
+ b->setBitmaps("wasabi.popup.menu.seperator");
+ b->setBitmapCenter(0);
+ b->enableButton(0);
+ b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
+ ItemT *t = new ItemT;
+ t->issep = 1;
+ t->butt = b;
+ t->menu = 0;
+ t->cb = NULL;
+ t->cmd = -1;
+ items.addItem(t, addpos);
+}
+
+void PopupMenu::addCommandImage(const char *bitmap, const char *pushedbitmap, const char *highlightbitmap, int command, int checked, int disabled, int addpos)
+{
+ ButtonWnd *b = new ButtonWnd();
+ b->init(this);
+ b->setParent(this);
+ b->setBitmaps(bitmap, pushedbitmap, highlightbitmap);
+ b->setBitmapCenter(1);
+ b->setNotifyId(command);
+ b->enableButton(disabled ? 0 : 1);
+ b->setChecked(checked ? 1 : 0);
+ b->setAutoDim(1);
+ b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
+ ItemT *t = new ItemT;
+ t->issep = 0;
+ t->butt = b;
+ t->menu = 0;
+ t->cb = NULL;
+ t->cmd = -1;
+ items.addItem(t);
+}
+
+void PopupMenu::addCommand(const wchar_t *_txt, int command, int checked, int disabled, int addpos)
+{
+ if (!_txt)
+ {
+ addSeparator();
+ return ;
+ }
+ String txt = translateButtonText(_txt);
+ ButtonWnd *b = new ButtonWnd();
+ b->init(this);
+ b->setParent(this);
+ b->setNotifyId(disabled ? -1 : command);
+
+#ifdef WASABI_COMPILE_LOCALES
+ const wchar_t *bind = (command != 0) ? WASABI_API_LOCALE->locales_getBindFromAction(command) : NULL;
+ if (bind) txt += StringPrintfW(L"\t%s", bind);
+#endif
+
+ b->setButtonText(txt);
+
+ // b->setTextJustification(BUTTONJUSTIFY_LEFT);
+ b->setTextAlign(TEXTALIGN_LEFT);
+ b->enableButton(disabled ? 0 : 1);
+ b->setChecked(checked);
+ if (checked == 2) b->setAlpha(128);
+ b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
+ ItemT *t = new ItemT;
+ t->issep = 0;
+ t->butt = b;
+ t->menu = 0;
+ t->cmd = command;
+ t->cb = NULL;
+ ASSERT(PTRLIST_POS_LAST == -1); //BU
+ items.addItem(t, addpos);
+}
+
+void PopupMenu::disableCommand(int cmd, int disable)
+{
+ for (int i = 0;i < items.getNumItems();i++)
+ if (items.enumItem(i)->cmd == cmd)
+ {
+ if (items.enumItem(i)->butt)
+ items.enumItem(i)->butt->enableButton(!!!disable);
+ break;
+ }
+}
+
+void PopupMenu::checkCommand(int cmd, int check)
+{
+ for (int i = 0;i < items.getNumItems();i++)
+ if (items.enumItem(i)->cmd == cmd)
+ {
+ if (items.enumItem(i)->butt)
+ items.enumItem(i)->butt->setChecked(check);
+ break;
+ }
+}
+
+const wchar_t *PopupMenu::getCommandText(int command)
+{
+ for (int i = 0;i < items.getNumItems();i++)
+ if (items.enumItem(i)->cmd == command && items.enumItem(i)->butt)
+ return items.enumItem(i)->butt->getName();
+ return NULL;
+}
+
+int PopupMenu::popAtXY(int x, int y)
+{
+ toplevelmenu = 1;
+ rcode = -1;
+ if (items.getNumItems())
+ {
+ POINT pt = {x, y};
+
+#ifdef WIN32
+ HWND oldcw = GetCapture(); // nonportable
+ ifc_window *oldcrw = (ifc_window*)GetWindowLong(oldcw, GWL_USERDATA);
+ if (oldcrw != NULL) oldcrw->cancelCapture();
+#endif
+
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+
+ showAtXY(x, y, &rcode);
+ beginCapture();
+
+ MSG msg;
+
+#ifdef WIN32
+ SetCursor(LoadCursor(NULL, IDC_ARROW)); // NONPORTABLE
+#endif
+ while (rcode == -1 && GetMessage( &msg, INVALIDOSWINDOWHANDLE, 0, 0 ))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ endCapture();
+ hide();
+
+ // if (hadcapture && under) under->beginCapture();
+
+#ifdef WIN32
+ if (rcode == -2 || rcode == -3)
+ {
+ DWORD p = GetMessagePos();
+ POINT pt;
+ pt.x = (signed short)LOWORD(p);
+ pt.y = (signed short)HIWORD(p);
+ HWND w = WindowFromPoint(pt);
+ ScreenToClient(w, &pt);
+ p = (pt.x & 0xFFFF) | (pt.y << 16);
+ //if (under) under->getRootParent()->wndProc(under->getRootParent()->gethWnd(), WM_MOUSEMOVE, 0, p);
+ //PostMessage(w, (rcode == -2) ? WM_MOUSEMOVE : WM_RBUTTONDOWN, 0, p);
+ //PostMessage(w, (rcode == -2) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN, 0, p);
+ }
+#else
+DebugString("portme: popup.cpp pass on click");
+#endif
+
+ }
+
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+
+ //DebugString("appdeactivation_pop_disallow\n");
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+
+ onPostPop(rcode);
+
+#ifdef WASABI_COMPILE_SKIN
+ if (!switchskinto.isempty())
+ {
+ WASABI_API_SKIN->skin_switchSkin(switchskinto.getNonConstVal());
+ switchskinto = "";
+ }
+#endif
+
+ return rcode;
+}
+
+void PopupMenu::showAtXY(int x, int y, int *rc, int revside, int parentW)
+{
+ int i, n;
+ int w = 0, h = 0;
+ lastitem = -1;
+ rcp = rc;
+ n = items.getNumItems();
+ for (i = 0; i < n; i ++)
+ {
+ if (items[i]->menu || items[i]->cb)
+ items[i]->butt->setRightBitmap("wasabi.popup.menu.submenu");
+ if (!items[i]->butt->getChecked()) items[i]->butt->setChecked( -1);
+ h += items[i]->butt->getHeight();
+ items[i]->butt->setUseBaseTexture(0);
+ items[i]->butt->setBorders(0);
+ int tw = items[i]->butt->getWidth();
+ if (w < tw)w = tw;
+ }
+ int neww = w + 6 + fl.getWidth() + fr.getWidth();
+ int newh = h + 6 + ft.getHeight() + fb.getHeight();
+
+ POINT p = {x, y};
+ RECT vp;
+ Std::getViewport(&vp, &p);
+
+ // maintain parent's reversal state
+ reverse_side = revside;
+ int savx = x;
+ if (reverse_side) x -= (neww + parentW);
+ if (x + neww > vp.right || x < 0)
+ {
+ reverse_side = !reverse_side;
+ x = savx;
+ if (reverse_side) x -= (neww + parentW);
+ }
+
+ if (y + newh > vp.bottom) y -= newh;
+ if (x < vp.left) x = vp.left;
+ if (y < vp.top) y = vp.top;
+
+ resize(x, y, neww, newh);
+
+ h = 0;
+ for (i = 0; i < n; i ++)
+ {
+ int lh = h;
+ h += items[i]->butt->getHeight();
+ items[i]->butt->resize(3 + fl.getWidth(), 3 + lh + ft.getHeight(), w, h - lh);
+ items[i]->butt->setHilite(0);
+ items[i]->butt->setPushed(0);
+ }
+
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+#ifdef WIN32
+ SetWindowPos(gethWnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+#elif defined(LINUX)
+Atom NET_STATE = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE", True );
+Atom state[2];
+state[0] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_SKIP_TASKBAR", True );
+state[1] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_ABOVE", True );
+
+if ( NET_STATE && state[0] && state[1] )
+{
+ XChangeProperty( Linux::getDisplay(), gethWnd(), NET_STATE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)state, 2 );
+}
+#endif
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+ setVisible(1);
+}
+
+void PopupMenu::onSetVisible(int v)
+{
+ POPUPMENU_PARENT::onSetVisible(v);
+ if (v && !kbdhooked)
+ {
+ WASABI_API_WND->hookKeyboard(this);
+ kbdhooked = 1;
+ }
+ else if (!v && kbdhooked)
+ {
+ WASABI_API_WND->unhookKeyboard(this);
+ kbdhooked = 0;
+ }
+
+}
+
+void PopupMenu::hide()
+{
+ if (lastitem >= 0 && items[lastitem]->menu)
+ {
+ items[lastitem]->menu->hide();
+ lastitem = -1;
+ }
+ setVisible(0);
+}
+
+int PopupMenu::popAnchored(int type)
+{
+ RECT wr;
+ if (parentRootWnd != NULL)
+ {
+ parentRootWnd->getWindowRect(&wr);
+ }
+ else if (parentWnd != INVALIDOSWINDOWHANDLE)
+ {
+#ifdef WIN32
+ GetWindowRect(parentWnd, &wr);
+#else
+DebugString("portme PopupMenu::popAnchored\n");
+#endif
+
+ }
+ else
+ {
+ ASSERTALWAYS("can't call popAnchored without instantiating with a parent window");
+ }
+ switch (type)
+ {
+ case POPUP_ANCHOR_UL: return popAtXY(wr.left, wr.top);
+ case POPUP_ANCHOR_LL: return popAtXY(wr.left, wr.bottom);
+ case POPUP_ANCHOR_UR: return popAtXY(wr.right, wr.top);
+ case POPUP_ANCHOR_LR: return popAtXY(wr.right, wr.bottom);
+ }
+ return 0;
+}
+
+int PopupMenu::popAtMouse()
+{
+ int x, y;
+ Std::getMousePos(&x, &y);
+ return popAtXY(x, y);
+}
+
+int PopupMenu::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)
+{
+ if (msg == ChildNotify::BUTTON_LEFTPUSH || msg == ChildNotify::BUTTON_RIGHTPUSH)
+ {
+ for (int i = 0;i < items.getNumItems();i++)
+ {
+ if (child == items[i]->butt && (items[i]->menu || items[i]->cb))
+ {
+ if (!items[i]->butt->getEnabled()) continue;
+ if (items[i]->cb) initMenuCallback(i);
+ if (!items[i]->menu) continue;
+ if (openmenuid == i) continue;
+ RECT r;
+ if (openmenuid >= 0)
+ {
+ items[openmenuid]->menu->hide();
+ openmenuid = -1;
+ }
+ items[i]->butt->getWindowRect(&r);
+ PopupMenu *p = items[i]->menu;
+ p->showAtXY(r.right, r.top, rcp, reverse_side, r.right - r.left);
+ if (p1)
+ {
+ p->selectFirst();
+ }
+ openmenuid = i;
+ }
+ }
+ // mig: changed this to call getNotifyId();
+ // *rcp=p1;
+ *rcp = child->getNotifyId();
+ return 0;
+ }
+ if (msg == ChildNotify::POPUP_SUBMENUCLOSE)
+ {
+ for (int i = 0;i < items.getNumItems();i++)
+ {
+ if (child == items[i]->menu)
+ {
+ if (openmenuid != i) continue;
+ items[openmenuid]->menu->hide();
+ openmenuid = -1;
+ return 0;
+ }
+ }
+ }
+ return POPUPMENU_PARENT::childNotify(child, msg, p1, p2);
+}
+
+void PopupMenu::selectFirst()
+{
+ ButtonWnd *b = NULL;
+ int i;
+ for (i = 0; i < items.getNumItems(); i++)
+ {
+ b = items.enumItem(i)->butt;
+ if (b != NULL) break;
+ }
+ if (b == NULL) return ;
+ lastitem = i;
+ b->setHilite(1);
+ invalidate();
+}
+
+int PopupMenu::getWhichItem(POINT &p)
+{
+ int x, n;
+ RECT r2;
+ getWindowRect(&r2);
+ n = items.getNumItems();
+ for (x = 0; x < n; x ++)
+ {
+ RECT r;
+ items[x]->butt->getWindowRect(&r);
+ r.right = r2.right;
+ r.left = r2.left;
+ if (Std::pointInRect(r, p))
+ {
+ return x;
+ }
+ }
+ return -1;
+}
+
+int PopupMenu::isMine(int x, int y)
+{
+ RECT r;
+ getWindowRect(&r);
+ POINT p = {x, y};
+ if (Std::pointInRect(r, p)) return 1;
+ if (lastitem >= 0 && items[lastitem]->menu && items[lastitem]->menu->isMine(x, y)) return 1;
+ return 0;
+}
+
+void PopupMenu::setFriendlyId(const char *id)
+{
+ friendid = id;
+}
+
+int PopupMenu::onLeftButtonDown(int x, int y)
+{
+ clientToScreen(&x, &y);
+ onButtonDown(1, x, y);
+ return 0;
+}
+
+int PopupMenu::onRightButtonDown(int x, int y)
+{
+ clientToScreen(&x, &y);
+ onButtonDown(2, x, y);
+ return 0;
+}
+
+int PopupMenu::onMouseMove(int x, int y)
+{
+ POPUPMENU_PARENT::onMouseMove(x, y);
+ POINT pnt = {x, y};
+ clientToScreen(&pnt);
+
+ if (keyctrl && lastxy.x == pnt.x && lastxy.y == pnt.y) return 1;
+ keyctrl = 0;
+ lastxy = pnt;
+
+ if (lastitem >= 0)
+ {
+ if (openmenuid >= 0 && items[openmenuid]->menu && items[openmenuid]->menu->isMine(pnt.x, pnt.y))
+ {
+ if (lastitem != openmenuid)
+ {
+ items[lastitem]->butt->setHilite(0);
+ items[lastitem]->butt->setPushed(0);
+ items[openmenuid]->butt->setHilite(1);
+ items[openmenuid]->butt->setPushed(1);
+ invalidateItem(lastitem);
+ lastitem = openmenuid;
+ invalidateItem(lastitem);
+ }
+ resetTimer( -1);
+ items[openmenuid]->menu->screenToClient(&pnt);
+ items[openmenuid]->menu->onMouseMove(pnt.x, pnt.y);
+ return 0;
+ }
+ }
+
+ int p = getWhichItem(pnt);
+ if (p >= 0)
+ {
+ ItemT *it = items[p];
+ if (!it->issep)
+ {
+ if (p != lastitem)
+ {
+ if (lastitem >= 0)
+ {
+ /* if (items[lastitem]->menu)
+ {
+ items[lastitem]->menu->hide();
+ }*/
+ items[lastitem]->butt->setHilite(0);
+ items[lastitem]->butt->setPushed(0);
+ invalidateItem(lastitem);
+ }
+ invalidateItem(lastitem);
+ lastitem = p;
+ invalidateItem(lastitem);
+ items[p]->butt->setHilite(1);
+ if (bdown) items[p]->butt->setPushed(1);
+ /* if (items[p]->menu) {
+ RECT r;
+ items[p]->butt->getWindowRect(&r);
+ items[p]->menu->showAtXY(r.right,r.top,rcp);
+ }*/
+ resetTimer(p);
+ invalidateItem(lastitem);
+ }
+ }
+ else
+ {
+ RECT _r;
+ getClientRect(&_r);
+ int inside = (x >= 0 && y >= 0 && x <= _r.right - _r.left && y <= _r.bottom - _r.top);
+ if (lastitem >= 0 && !inside)
+ {
+ items[lastitem]->butt->setHilite(0);
+ items[lastitem]->butt->setPushed(0);
+ invalidateItem(lastitem);
+ lastitem = -1;
+ }
+ }
+ }
+ else
+ {
+ if (!friendid.isempty())
+ {
+ ifc_window *w = WASABI_API_WND->rootWndFromPoint(&pnt);
+ if (w != NULL)
+ {
+ MenuButtonSurface *s = static_cast<MenuButtonSurface *>(w->getInterface(menuButtonSurfaceGuid));
+ if (s != NULL)
+ {
+ if (s->getParentWnd() != parentRootWnd)
+ {
+ const char *str = s->getParentMenuId();
+ if (STRCASEEQLSAFE(str, friendid))
+ {
+ abort();
+ rcode = -4;
+ chainmenu = s;
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void PopupMenu::resetTimer(int p)
+{
+ if (timerset)
+ {
+ killTimer(POPUP_TIMERID);
+ timeritem = -1;
+ }
+ if (p >= 0 && !disable_autopop)
+ {
+ setTimer(POPUP_TIMERID, popupdelay);
+ timeritem = p;
+ timerset = 1;
+ }
+}
+
+void PopupMenu::timerCallback(int id)
+{
+ switch (id)
+ {
+ case POPUP_TIMERID:
+ killTimer(POPUP_TIMERID);
+ timerset = 0;
+ if (timeritem == openmenuid)
+ {
+ timeritem = -1;
+ break;
+ }
+ if (openmenuid >= 0 && items[openmenuid]->menu)
+ {
+ items[openmenuid]->menu->hide();
+ openmenuid = -1;
+ }
+ if (timeritem >= 0)
+ {
+ if (items[timeritem]->cb) initMenuCallback(timeritem);
+ if (items[timeritem]->butt->getEnabled() && items[timeritem]->menu)
+ {
+ RECT r;
+ items[timeritem]->butt->getWindowRect(&r);
+ items[timeritem]->menu->showAtXY(r.right, r.top, rcp, reverse_side, r.right - r.left);
+ openmenuid = timeritem;
+ }
+ timeritem = -1;
+ }
+ break;
+ default:
+ POPUPMENU_PARENT::timerCallback(id);
+ break;
+ }
+}
+
+void PopupMenu::initMenuCallback(int item)
+{
+ int a = rcode;
+ rcode = 0;
+ PopupMenu *p = items[item]->cb->popupMenuCallback(this, items[item]->cbparam);
+ rcode = a;
+ if (p)
+ {
+ items[item]->cb = NULL;
+ items[item]->menu = p;
+ }
+}
+
+int PopupMenu::onLeftButtonUp(int x, int y)
+{
+ clientToScreen(&x, &y);
+ onButtonUp(1, x, y);
+ return 0;
+}
+
+int PopupMenu::onRightButtonUp(int x, int y)
+{
+ clientToScreen(&x, &y);
+ onButtonUp(2, x, y);
+ return 0;
+}
+
+void PopupMenu::onButtonDown(int wb, int x, int y)
+{
+ POINT pos = {x, y};
+ RECT r;
+ bdown |= wb;
+ if (lastitem >= 0)
+ {
+ if (items[lastitem]->menu && items[lastitem]->menu->isMine(pos.x, pos.y))
+ {
+ items[lastitem]->menu->onButtonDown(wb, x, y);
+ return ;
+ }
+ }
+ getWindowRect(&r);
+ if (!Std::pointInRect(r, pos))
+ {
+ rcode = (wb == 1) ? -2 : -3;
+ }
+ else
+ {
+ int item = getWhichItem(pos);
+ if (item >= 0) items[item]->butt->setPushed(1);
+ }
+}
+
+void PopupMenu::onButtonUp(int wb, int x, int y)
+{
+ if (lastitem >= 0)
+ {
+ POINT pos = {x, y};
+ if (items[lastitem]->menu && items[lastitem]->menu->isMine(pos.x, pos.y))
+ {
+ items[lastitem]->menu->onButtonUp(wb, x, y);
+ return ;
+ }
+ }
+ if (bdown & wb)
+ {
+ bdown &= ~wb;
+ POINT pnt = {x, y};
+ int p = getWhichItem(pnt);
+ if (p >= 0)
+ {
+ items[p]->butt->onLeftPush(x, y);
+ if (!bdown)
+ {
+ items[p]->butt->setPushed(0);
+ }
+ }
+ }
+}
+
+int PopupMenu::onKillFocus()
+{
+#ifndef LINUX
+ if (rcode == -1) rcode = -2;
+#endif
+ return POPUPMENU_PARENT::onKillFocus();
+}
+
+// only translates the text, not the optional accelerator
+String PopupMenu::translateButtonText(const wchar_t *text)
+{
+ PathParser pp(text, "\t");
+ String ret;
+ for (int i = 0; i < pp.getNumStrings(); i++)
+ {
+ if (i == 0) ret += _(pp.enumString(i)); // translate first
+ else ret += pp.enumString(i);
+ if (i != pp.getNumStrings() - 1) ret += "\t";
+ }
+ return ret;
+}
+
+int PopupMenu::onPaint(Canvas *canvas)
+{
+ PaintBltCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ POPUPMENU_PARENT::onPaint(canvas);
+
+ RECT r, r2;
+
+ getClientRect(&r);
+ tex.getBitmap()->blitTile(canvas, &r);
+
+ // left side
+ ful.getBitmap()->blitAlpha(canvas, 0, 0);
+
+ r2.left = 0;
+ r2.right = fl.getWidth();
+ r2.top = ful.getHeight();
+ r2.bottom = r.bottom - fll.getHeight();
+ fl.getBitmap()->stretchToRectAlpha(canvas, &r2);
+
+ fll.getBitmap()->blitAlpha(canvas, 0, r.bottom - fll.getHeight());
+
+ // right side
+ fur.getBitmap()->blitAlpha(canvas, r.right - fur.getWidth(), 0);
+
+ r2.left = r.right - fr.getWidth();
+ r2.right = r.right;
+ r2.top = fur.getHeight();
+ r2.bottom = r.bottom - flr.getHeight();
+ fr.getBitmap()->stretchToRectAlpha(canvas, &r2);
+
+ flr.getBitmap()->blitAlpha(canvas, r.right - flr.getWidth(), r.bottom - flr.getHeight());
+
+ // top
+ r2.left = ful.getWidth();
+ r2.right = r.right - fur.getWidth();
+ r2.top = 0;
+ r2.bottom = ft.getHeight();
+ ft.getBitmap()->stretchToRectAlpha(canvas, &r2);
+
+ // bottom
+ r2.left = fll.getWidth();
+ r2.right = r.right - flr.getWidth();
+ r2.top = r.bottom - fb.getHeight();
+ r2.bottom = r.bottom;
+ fb.getBitmap()->stretchToRectAlpha(canvas, &r2);
+
+ // selection bar
+
+ if (lastitem != -1)
+ {
+ ItemT *it = items[lastitem];
+ RECT r3, c;
+
+ it->butt->getClientRect(&r3);
+
+ // left
+ r2.left = r.left + fl.getWidth() + SELMARGIN;
+ r2.top = r.top + r3.top;
+ r2.right = r2.left + sl.getWidth();
+ r2.bottom = r2.top + (r3.bottom - r3.top);
+ sl.getBitmap()->stretchToRectAlpha(canvas, &r2);
+
+ c = r2;
+ c.left = c.right - 1;
+
+ // right
+ r2.right = r.right - fr.getWidth() - SELMARGIN;
+ r2.left = r2.right - sr.getWidth();
+ sr.getBitmap()->stretchToRectAlpha(canvas, &r2);
+
+ c.right = r2.left;
+
+ // center
+ sc.getBitmap()->stretchToRectAlpha(canvas, &c);
+
+ }
+
+ return 1;
+}
+
+void PopupMenu::invalidateItem(int i)
+{
+ if (i < 0 || i >= items.getNumItems()) return ;
+ RECT r, r2, r3;
+ getClientRect(&r);
+
+ ItemT *it = items[i];
+ it->butt->getClientRect(&r3);
+
+ r2.left = r.left + fl.getWidth();
+ r2.top = r.top + r3.top;
+ r2.right = r.right - fl.getWidth();
+ r2.bottom = r2.top + (r3.bottom - r3.top);
+ invalidateRect(&r2);
+}
+
+int PopupMenu::getNumCommands()
+{
+ return items.getNumItems();
+}
+
+#ifdef WASABI_COMPILE_SKIN
+int PopupMenu::skincb_onCheckPreventSwitch(const char *skinname)
+{
+ switchskinto = skinname;
+ rcode = -2;
+ return 1;
+}
+#endif
+
+int PopupMenu::onSysKeyDown(int code, int d)
+{
+ int a = POPUPMENU_PARENT::onSysKeyDown(code, d);
+ /* if (d & (1<<29)) {
+ //ALT key pressed, abort menu (mimics win32 popup behavior)
+ abort();
+ if(getParent()) SendMessageW(getParent()->gethWnd(),WM_SYSKEYDOWN,code,d);
+ return 0;
+ }*/
+ if (a == 0)
+ return onKeyDown(code);
+ return 0;
+}
+
+int PopupMenu::onKeyDown(int code)
+{
+ if (POPUPMENU_PARENT::onKeyDown(code)) return 1;
+ switch (code)
+ {
+ case STDKEY_DOWN:
+ navigate(1);
+ return 1;
+ case STDKEY_UP:
+ navigate( -1);
+ return 1;
+ case STDKEY_RETURN:
+ navigate(0, 1);
+ return 1;
+ case STDKEY_RIGHT:
+ navigate(0, 0);
+ return 1;
+ case VK_LEFT:
+ if (!toplevelmenu)
+ notifyParent(ChildNotify::POPUP_SUBMENUCLOSE);
+ return 1;
+ case VK_ESCAPE:
+ abort();
+ return 1;
+ }
+ return 0;
+}
+
+void PopupMenu::abort()
+{
+ if (toplevelmenu)
+ rcode = -2;
+ else
+ notifyParent(ChildNotify::POPUP_SUBMENUCLOSE);
+}
+
+void PopupMenu::navigate(int p, int f)
+{
+ keyctrl = 1;
+ int i = lastitem;
+
+ ItemT *t = NULL;
+
+ if (p == 0)
+ {
+
+ if (lastitem >= 0)
+ {
+ ItemT *t = items.enumItem(lastitem);
+ if (f || t->menu || t->cb)
+ {
+ t->butt->setHilite(1);
+ t->butt->setPushed(1);
+ childNotify(t->butt, ChildNotify::BUTTON_LEFTPUSH, 1, 0);
+ }
+ }
+ return ;
+ }
+
+ while (!t || t->issep)
+ {
+ i += p;
+ i %= items.getNumItems();
+ if (i == -1) i = items.getNumItems() - 1;
+ if (i >= items.getNumItems()) return ;
+ t = items.enumItem(i);
+ }
+
+ if (t->butt)
+ {
+ int i;
+ i = items.searchItem(t);
+ t->butt->setHilite(1);
+ if (lastitem != -1)
+ {
+ ItemT *s = items.enumItem(lastitem);
+ if (s->butt)
+ {
+ s->butt->setPushed(0);
+ s->butt->setHilite(0);
+ }
+ }
+ lastitem = i;
+ invalidate();
+ }
+}
+
+
+
+
+#else
+
+//------------------------------------------------------------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------------------------------------------------------------
+//------------------------------------------------------------------------------------------------------------------------------------------
+// 3rd level popup menu, yay
+
+#include "script/c_script/c_text.h"
+#include "script/c_script/c_rootobj.h"
+#include "script/c_script/c_button.h"
+#include "script/c_script/c_group.h"
+
+
+PopupMenu::PopupMenu(ifc_window *sourceWnd)
+{
+ ASSERT(sourceWnd != NULL);
+ myInit();
+ setParent(sourceWnd);
+ sourceWnd->setAllowDeactivation(0);
+ init(HINSTANCEfromHWND(getParent()->gethWnd()), sourceWnd->gethWnd(), TRUE);
+ sourceWnd->setAllowDeactivation(1);
+}
+
+PopupMenu::PopupMenu()
+{
+ myInit();
+ setParent(WASABI_API_WND->main_getRootWnd());
+ WASABI_API_WND->main_getRootWnd()->setAllowDeactivation(0);
+ init(hInstance, WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE);
+ WASABI_API_WND->main_getRootWnd()->setAllowDeactivation(1);
+}
+
+PopupMenu::PopupMenu(PopupMenu *sourceWnd)
+{
+ myInit();
+ setParent(sourceWnd);
+ sourceWnd->setAllowDeactivation(0);
+ init(GetModuleHandle(NULL), sourceWnd->gethWnd(), TRUE);
+ sourceWnd->setAllowDeactivation(1);
+}
+
+void PopupMenu::myInit()
+{
+ setVirtual(0);
+ setStartHidden(1);
+ setRenderRatio(1.0);
+ reverse_side = 0;
+ rcode = 0;
+ submenus = 0;
+ c_grouplist = NULL;
+ WASABI_API_WND->popupexit_register(this, this);
+}
+
+PopupMenu::~PopupMenu()
+{
+ WASABI_API_WND->popupexit_deregister(this);
+ delete c_grouplist;
+}
+
+int PopupMenu::onInit()
+{
+ POPUPMENU_PARENT::onInit();
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ setTransparency(_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), "Popup menu alpha", 255));
+#else
+setTransparency(255);
+#endif
+
+
+
+ setContent("wasabi.popup.main.group");
+
+ return 1;
+}
+
+int PopupMenu::popAtXY(int x, int y)
+{
+ rcode = -1;
+ if (1 /*items.getNumItems()*/)
+ {
+ POINT pt = {x, y};
+
+ //DebugString("appdeactivation_push_disallow\n");
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+
+ showAtXY(x, y, &rcode);
+
+ //MSG msg;
+ /*while (rcode == -1 && GetMessage( &msg, NULL, 0, 0 )) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }*/
+
+ SetCursor(LoadCursor(NULL, IDC_ARROW)); // NONPORTABLE
+
+ int quit = 0;
+ while (!quit)
+ {
+ rcode = getGuiObject()->guiobject_runModal();
+ if (rcode & 0x40000000 && rcode != -2 && rcode != -1)
+ {
+ int submenuentry = rcode & ~0x40000000;
+ ItemT *t = items.enumItem(submenuentry);
+ if (t->cb != NULL)
+ initMenuCallback(submenuentry);
+ if (t->menu != NULL)
+ {
+ setAllowDeactivation(0);
+ t->menu->showAtXY(0, 0, NULL, 0, 0);
+ setAllowDeactivation(1);
+ }
+ }
+ else
+ quit = 1;
+ }
+
+ setVisible(0);
+ }
+
+ //DebugString("appdeactivation_pop_disallow\n");
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+
+ onPostPop(rcode);
+
+ return rcode;
+}
+
+void PopupMenu::showAtXY(int x, int y, int *rc, int revside /* =0 */, int parentW /* =0 */)
+{
+ fillContent();
+ int neww = getPreferences(SUGGESTED_W);
+ int newh = getPreferences(SUGGESTED_H);;
+
+ POINT p = {x, y};
+ RECT vp;
+ Std::getViewport(&vp, &p);
+
+ // maintain parent's reversal state
+ reverse_side = revside;
+ int savx = x;
+ if (reverse_side) x -= (neww + parentW);
+ if (x + neww > vp.right || x < 0)
+ {
+ reverse_side = !reverse_side;
+ x = savx;
+ if (reverse_side) x -= (neww + parentW);
+ }
+
+ if (y + newh > vp.bottom) y -= newh;
+ if (x < vp.left) x = vp.left;
+ if (y < vp.top) y = vp.top;
+
+ resize(x, y, neww, newh);
+
+ WASABI_API_WND->appdeactivation_push_disallow(this);
+#ifdef WIN32
+ SetWindowPos(gethWnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+#else
+Atom NET_STATE = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE", True );
+Atom state[2];
+state[0] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_SKIP_TASKBAR", True );
+state[1] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_ABOVE", True );
+
+if ( NET_STATE && state[0] && state[1] )
+{
+ XChangeProperty( Linux::getDisplay(), gethWnd(), NET_STATE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)state, 2 );
+}
+#endif
+ WASABI_API_WND->appdeactivation_pop_disallow(this);
+ setVisible(1);
+}
+
+int PopupMenu::popAnchored(int type)
+{
+ RECT wr;
+ getParent()->getWindowRect(&wr);
+ switch (type)
+ {
+ case POPUP_ANCHOR_UL: return popAtXY(wr.left, wr.top);
+ case POPUP_ANCHOR_LL: return popAtXY(wr.left, wr.bottom);
+ case POPUP_ANCHOR_UR: return popAtXY(wr.right, wr.top);
+ case POPUP_ANCHOR_LR: return popAtXY(wr.right, wr.bottom);
+ }
+ return 0;
+}
+
+int PopupMenu::popAtMouse()
+{
+ int x, y;
+ Std::getMousePos(&x, &y);
+ return popAtXY(x, y);
+}
+
+void PopupMenu::onNewContent()
+{
+ POPUPMENU_PARENT::onNewContent();
+ if (isVisible())
+ fillContent();
+}
+
+void PopupMenu::fillContent()
+{
+ GuiObject *grouplist = findObject("popup.content");
+ if (grouplist != NULL)
+ {
+
+ delete c_grouplist;
+
+ c_grouplist = new C_GroupList(*grouplist);
+ c_grouplist->removeAll();
+ c_grouplist->setRedraw(0);
+
+ for (int i = 0;i < items.getNumItems();i++)
+ {
+ addItem(items.enumItem(i));
+ }
+
+ c_grouplist->setRedraw(1);
+ }
+}
+
+void PopupMenu::addItem(ItemT *i)
+{
+ if (c_grouplist == NULL) return ;
+ switch (i->type)
+ {
+
+ case POPUPITEM_TYPE_TEXT:
+ {
+ c_grouplist->instantiate("wasabi.popup.text.item", 1);
+ ScriptObject *o = c_grouplist->enumItem(c_grouplist->getNumItems() - 1);
+ if (o != NULL)
+ {
+ C_Group grp(o);
+
+ C_RootObject g(o);
+ g.notify("arrow", StringPrintfW(L"%d", (submenus) ? 1 : 0), 0, 0);
+ g.notify("checkmark", StringPrintfW(L"%d", menuchecks ? 1 : 0), 0, 0);
+ g.notify("id", StringPrintfW(L"%d", i->cmd), 0, 0);
+
+ ScriptObject *check = grp.getObject("popup.item.checkmark");
+ if (check != NULL)
+ {
+ C_Button toggle(check);
+ toggle.setActivated(i->checked);
+ }
+
+ ScriptObject *arrow = grp.getObject("popup.item.submenuarrow");
+ if (check != NULL)
+ {
+ C_Button sub(arrow);
+ sub.setActivated((i->menu != NULL || i->cb != NULL));
+ }
+
+ ScriptObject *txt = grp.getObject("popup.item.text");
+ if (txt != NULL)
+ {
+ C_Text itemtxt(txt);
+ itemtxt.setText(i->txt);
+ }
+ }
+ break;
+ }
+
+ case POPUPITEM_TYPE_IMAGE:
+ c_grouplist->instantiate("wasabi.popup.image.item", 1);
+ break;
+
+ case POPUPITEM_TYPE_SEPARATOR:
+ c_grouplist->instantiate("wasabi.popup.separator.item", 1);
+ break;
+
+ }
+}
+
+String PopupMenu::translateButtonText(const wchar_t *text)
+{
+ PathParser pp(text, "\t");
+ String ret;
+ for (int i = 0; i < pp.getNumStrings(); i++)
+ {
+ if (i == 0) ret += _(pp.enumString(i)); // translate first
+ else ret += pp.enumString(i);
+ if (i != pp.getNumStrings() - 1) ret += "\t";
+ }
+ return ret;
+}
+
+void PopupMenu::addCommand(const wchar_t *_txt, int command, int checked, int disabled, int addpos)
+{
+ if (!_txt)
+ {
+ addSeparator();
+ return ;
+ }
+
+ String txt = translateButtonText(_txt);
+#ifdef WASABI_COMPILE_LOCALES
+ const char *bind = WASABI_API_LOCALE->locales_getBindFromAction(command);
+ if (bind) txt += StringPrintfW(L"\t%s", bind);
+#endif
+ ItemT *t = new ItemT;
+ t->type = POPUPITEM_TYPE_TEXT;
+ t->cmd = command;
+ t->txt = txt;
+ t->checked = checked;
+ t->menu = NULL;
+ t->cb = NULL;
+ t->cmd = -1;
+ ASSERT(PTRLIST_POS_LAST == -1); //BU
+ items.addItem(t, addpos);
+}
+
+int PopupMenu::popupexitcb_onExitPopup()
+{
+ getGuiObject()->guiobject_endModal( -2);
+ return 1;
+}
+
+void PopupMenu::addSubMenu(PopupMenu *menu, const wchar_t *text)
+{
+ ASSERT(text != NULL);
+ submenus = 1;
+ ItemT *t = new ItemT;
+ t->type = POPUPITEM_TYPE_TEXT;
+ t->cmd = items.getNumItems() | 0x40000000;
+ t->txt = translateButtonText(text);
+ t->checked = 0;
+ t->menu = menu;
+ t->cb = NULL;
+ t->cmd = -1;
+ t->cmd = -1;
+ items.addItem(t);
+}
+
+void PopupMenu::addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param)
+{
+ ASSERT(text != NULL);
+ ASSERT(cb != NULL);
+ ItemT *t = new ItemT;
+ submenus = 1;
+ t->type = POPUPITEM_TYPE_TEXT;
+ t->checked = 0;
+ t->cmd = items.getNumItems() | 0x40000000;
+ t->menu = NULL;
+ t->cb = cb;
+ t->cbparam = param;
+ t->txt = translateButtonText(text);
+ t->cmd = -1;
+ items.addItem(t);
+}
+
+void PopupMenu::initMenuCallback(int item)
+{
+ int a = rcode;
+ rcode = 0;
+ PopupMenu *p = items[item]->cb->popupMenuCallback(this, items[item]->cbparam);
+ rcode = a;
+ if (p)
+ {
+ items[item]->cb = NULL;
+ items[item]->menu = p;
+ }
+}
+
+#endif
+
+
+#endif //WASABI_WANT_FF_POPUP
diff --git a/Src/Wasabi/api/wnd/popup.h b/Src/Wasabi/api/wnd/popup.h
new file mode 100644
index 00000000..9ee6d7f9
--- /dev/null
+++ b/Src/Wasabi/api/wnd/popup.h
@@ -0,0 +1,341 @@
+// PopupMenu NONPORTABLE, NewPopupMenu portable
+#ifndef _POPUP_H
+#define _POPUP_H
+
+#include <wasabicfg.h>
+#include <bfc/string/StringW.h>
+#include <bfc/PtrList.h>
+#include <api/locales/xlatstr.h>
+//#define WANT_NEW_POPUPMENU
+
+class PopupMenu;
+
+class PopupMenuCallback
+{
+public:
+ virtual PopupMenu *popupMenuCallback(PopupMenu *parent, intptr_t param) = 0; // returns the new popupmenu to be displayed
+};
+
+enum { POPUP_ANCHOR_UL, POPUP_ANCHOR_LL, POPUP_ANCHOR_UR, POPUP_ANCHOR_LR };
+
+#ifndef WASABI_WANT_FF_POPUP
+
+class PopupMenuEntry
+{
+public:
+ PopupMenuEntry(const wchar_t *txt, int cmd, PopupMenu *_submenu, int _checked, int _disabled, PopupMenuCallback *cb = NULL, int cbparam = 0) : text(_(txt)), command(cmd), submenu(_submenu), checked(_checked), disabled(_disabled), callback(cb), callbackparam(cbparam) {} // txt = null for separators and menus, cmd = -1 for separators and submenus, if submenu == null && cmd == -1 and text == NULL then it's a separator
+ virtual ~PopupMenuEntry() {}
+ int getCommand() { return command; }
+ const wchar_t *getText() { return text; }
+ PopupMenu *getSubmenu() { return submenu; }
+ int getChecked() { return checked; }
+ int getDisabled() { return disabled; }
+ int isSeparator() { return command == -1 && submenu == NULL && text == NULL; }
+ int isSubmenu() { return (command == -1 && submenu != NULL) || callback; }
+ void setChecked(int check) { checked = check; }
+ void setDisabled(int disable) { disabled = disable; }
+ PopupMenuCallback *getCallback() { return callback; }
+ int getCallbackParam() { return callbackparam; }
+private:
+ StringW text;
+ int command;
+ PopupMenu *submenu;
+ int checked;
+ int disabled;
+ PopupMenuCallback *callback;
+ int callbackparam;
+};
+
+class SortMenuEntries
+{
+public:
+ static int compareItem(PopupMenuEntry *p1, PopupMenuEntry *p2)
+ {
+ if (p1->getCommand() < p2->getCommand()) return -1;
+ if (p1->getCommand() > p2->getCommand()) return 1;
+ return 0;
+ }
+ static int compareAttrib(const wchar_t *attrib, PopupMenuEntry *item)
+ {
+ int c = *(int *)attrib;
+ if (c < item->getCommand()) return -1;
+ if (c > item->getCommand()) return 1;
+ return 0;
+ }
+};
+
+
+class PopupMenu
+{
+public:
+ PopupMenu();
+ PopupMenu(ifc_window *parent);
+ PopupMenu(PopupMenu *parent);
+ ~PopupMenu();
+
+ virtual void addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled = FALSE);
+ virtual void addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param);
+ virtual void addCommand(const wchar_t *text, int command, int checked = 0, int disabled = 0, int addpos = -1);
+ virtual void addSeparator(int addpos = -1);
+ virtual void checkCommand(int cmd, int check);
+ virtual void disableCommand(int cmd, int disable);
+ virtual int popAtXY(int x, int y, int native = 0);
+ virtual int popAnchored(int type = POPUP_ANCHOR_LL); // dropped off the sourceWnd given above
+ virtual int popAtMouse();
+ virtual int getNumCommands();
+ virtual const wchar_t *getCommandText(int command);
+ OSMENUHANDLE getOSMenuHandle();
+ virtual void abort();
+
+private:
+ void rebuildMenu();
+ void invalidateMenu(); // no virtual please (it's called in the destructor)
+ ifc_window *getParent() { return parent; }
+
+ PtrList<PopupMenuEntry> entries;
+ PtrListQuickSorted<PopupMenuEntry, SortMenuEntries> sortedentries;
+ OSMENUHANDLE hmenu;
+ ifc_window *parent;
+};
+
+#else // WASABI_WANT_FF_POPUP
+
+#include "../bfc/basewnd.h"
+#include "../bfc/ptrlist.h"
+#include <tataki/bitmap/autobitmap.h>
+#include "../studio/skincb.h"
+
+#define POPUP_TIMERID 1171
+
+class PopupMenu;
+class ButtonWnd;
+class MenuButtonSurface;
+
+class _PopupMenu
+{
+public:
+ virtual ~_PopupMenu() {}
+
+ virtual void addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled = FALSE) = 0;
+ virtual void addSubMenuImage(PopupMenu *menu, const wchar_t *bitmap, const wchar_t *pushedbitmap = 0, const wchar_t *highlightbitmap = 0) = 0;
+ virtual void addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param) = 0;
+
+ virtual void addCommand(const char *text, int command, int checked = 0, int disabled = 0, int addpos = -1) = 0;
+ virtual void addCommandImage(const wchar_t *bitmap, const wchar_t *pushedbitmap, const wchar_t *highlightbitmap, int command, int checked, int disabled, int addpos = -1) = 0;
+ virtual void addSeparator(int addpos = -1) = 0;
+
+ virtual void checkCommand(int cmd, int check) = 0;
+ virtual void disableCommand(int cmd, int disable) = 0;
+
+ virtual int popAtXY(int x, int y) = 0;
+ virtual int popAnchored(int type = POPUP_ANCHOR_LL) = 0; // dropped off the sourceWnd given above
+ virtual int popAtMouse() = 0;
+ virtual void showAtXY(int x, int y, int *rc, int revside = 0, int parentW = 0) = 0;
+ virtual int getNumCommands() = 0;
+ virtual const wchar_t *getCommandText(int command) = 0;
+ virtual void onPostPop(intptr_t result) = 0;
+ virtual void selectFirst() = 0;
+};
+
+#ifndef WANT_NEW_POPUPMENU
+
+#define POPUPMENU_PARENT BaseWnd
+
+class PopupMenu : public _PopupMenu, public POPUPMENU_PARENT, public SkinCallbackI
+{
+public:
+ PopupMenu(ifc_window *sourceWnd);
+ PopupMenu(HWND sourceWnd);
+ PopupMenu(PopupMenu *sourceWnd);
+ PopupMenu();
+ virtual ~PopupMenu();
+
+ void addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled = FALSE);
+ void addSubMenuImage(PopupMenu *menu, const wchar_t *bitmap, const wchar_t *pushedbitmap = 0, const wchar_t *highlightbitmap = 0);
+ void addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param);
+
+ void addCommand(const wchar_t *text, int command, int checked = 0, int disabled = 0, int addpos = -1);
+ void addCommandImage(const wchar_t *bitmap, const wchar_t *pushedbitmap, const wchar_t *highlightbitmap, int command, int checked, int disabled, int addpos = -1);
+ void addSeparator(int addpos = -1);
+
+ void checkCommand(int cmd, int check);
+ void disableCommand(int cmd, int disable);
+
+ int popAtXY(int x, int y);
+ int popAnchored(int type = POPUP_ANCHOR_LL); // dropped off the sourceWnd given above
+ int popAtMouse();
+ int getNumCommands();
+
+ virtual int bypassModal() { return 1; }
+
+ const wchar_t *getCommandText(int command);
+
+ virtual int onPaint(Canvas *canvas);
+
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onRightButtonDown(int x, int y);
+ virtual int onMouseMove(int x, int y); // only called when mouse captured
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onRightButtonUp(int x, int y);
+ virtual void timerCallback(int id);
+
+ virtual int onKillFocus();
+
+ virtual int skincb_onCheckPreventSwitch(const char *skinname);
+
+ virtual int onKeyDown(int code);
+
+ virtual void navigate(int p, int f = 0); // 1 = next, -1 = previous, 0 = self (open submenu or run action)
+
+ virtual void onSetVisible(int p);
+ virtual void selectFirst();
+ virtual int onSysKeyDown(int code, int d);
+
+ virtual void abort();
+
+ virtual void setFriendlyId(const wchar_t *id);
+ virtual MenuButtonSurface *getNextFriend() { return chainmenu; }
+
+protected:
+ virtual int onInit();
+
+ void invalidateItem(int i);
+ String translateButtonText(const wchar_t *text);
+
+ virtual void onPostPop(intptr_t result) {}
+
+ // used internally, as well as by parent Popups.
+ void showAtXY(int x, int y, int *rc, int revside = 0, int parentW = 0);
+ void hide();
+ int isMine(int x, int y);
+private:
+ int getWhichItem(POINT &p);
+ void onButtonUp(int wb, int x, int y);
+ void onButtonDown(int wb, int x, int y);
+ void resetTimer(int p);
+ void initMenuCallback(int item);
+
+ int bdown;
+ int lastitem;
+ int rcode;
+ int *rcp;
+ typedef struct
+ {
+ int cmd;
+ ButtonWnd *butt;
+ PopupMenu *menu;
+ PopupMenuCallback *cb;
+ int issep;
+ int cbparam;
+ }
+ ItemT;
+ PtrList<ItemT> items;
+ ifc_window *parentRootWnd;
+ HWND parentWnd;
+ AutoSkinBitmap tex, ful, fur, fll, flr, fl, fr, ft, fb, sr, sl, sc;
+ int openmenuid;
+ int timerset;
+ int timeritem;
+ int popupdelay;
+ int reverse_side;
+ ifc_window *init_with;
+ int disable_autopop;
+ int kbdhooked;
+ int toplevelmenu;
+ POINT lastxy;
+ int keyctrl;
+ String friendid;
+ MenuButtonSurface *chainmenu;
+
+#ifdef WASABI_COMPILE_SKIN
+ String switchskinto;
+#endif
+};
+
+#else
+
+#include "guiobjwnd.h"
+#include "script/c_script/c_grouplist.h"
+#include "../bfc/popexitcb.h"
+#include "../bfc/notifmsg.h"
+
+#define POPUPMENU_PARENT GuiObjectWnd
+
+enum {
+ POPUPITEM_TYPE_TEXT = 0,
+ POPUPITEM_TYPE_IMAGE,
+ POPUPITEM_TYPE_SEPARATOR,
+};
+
+typedef struct
+{
+ int type;
+ int cmd;
+ PopupMenu *menu;
+ PopupMenuCallback *cb;
+ String txt;
+ int checked;
+ int disabled;
+ int cbparam;
+}
+ItemT;
+
+class PopupMenu : public _PopupMenu, public POPUPMENU_PARENT, public PopupExitCallbackI
+{
+public:
+ PopupMenu(ifc_window *sourceWnd);
+ // PopupMenu(HWND sourceWnd);
+ PopupMenu(PopupMenu *sourceWnd);
+ PopupMenu();
+ virtual ~PopupMenu();
+
+ virtual void addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled = FALSE);
+ virtual void addSubMenuImage(PopupMenu *menu, const wchar_t *bitmap, const wchar_t *pushedbitmap = 0, const wchar_t *highlightbitmap = 0) {}
+ virtual void addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param);
+
+ virtual void addCommand(const wchar_t *text, int command, int checked = 0, int disabled = 0, int addpos = -1);
+ virtual void addCommandImage(const wchar_t *bitmap, const wchar_t *pushedbitmap, const wchar_t *highlightbitmap, int command, int checked, int disabled, int addpos = -1) {}
+ virtual void addSeparator(int addpos = -1) {}
+
+ virtual void checkCommand(int cmd, int check) {}
+ virtual void disableCommand(int cmd, int disable) {}
+
+ virtual int popAtXY(int x, int y);
+ virtual int popAnchored(int type = POPUP_ANCHOR_LL);
+ virtual int popAtMouse();
+ virtual void showAtXY(int x, int y, int *rc, int revside = 0, int parentW = 0);
+ virtual int getNumCommands() { return 0;}
+ virtual const wchar_t *getCommandText(int command) { return NULL; }
+ virtual void onPostPop(intptr_t result) {}
+
+ virtual int onInit();
+
+ virtual void onNewContent();
+
+ virtual int popupexitcb_onExitPopup();
+ virtual ifc_dependent *popupexit_getDependencyPtr() { return getDependencyPtr(); }
+
+private:
+
+ virtual int bypassModal() { return 1; }
+ String translateButtonText(const wchar_t *text);
+ void fillContent();
+ void addItem(ItemT *item);
+ void initMenuCallback(int item);
+
+ void myInit();
+ int reverse_side;
+ int rcode;
+
+ PtrList<ItemT> items;
+ int menuchecks;
+ int submenus;
+ C_GroupList *c_grouplist;
+ int totalheight, totalwidth;
+};
+
+#endif
+#endif // WASABI_WANT_FF_POPUP
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/region.cpp b/Src/Wasabi/api/wnd/region.cpp
new file mode 100644
index 00000000..ceeb0d64
--- /dev/null
+++ b/Src/Wasabi/api/wnd/region.cpp
@@ -0,0 +1 @@
+#include "precomp.h"
diff --git a/Src/Wasabi/api/wnd/region.h b/Src/Wasabi/api/wnd/region.h
new file mode 100644
index 00000000..a925f3e1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/region.h
@@ -0,0 +1,5 @@
+#ifdef _WIN32
+#include <api/wnd/platform/win32/region.h>
+#elif defined(__APPLE__)
+#include <api/wnd/platform/osx/region.h>
+#endif
diff --git a/Src/Wasabi/api/wnd/resizable.h b/Src/Wasabi/api/wnd/resizable.h
new file mode 100644
index 00000000..7b8b6faf
--- /dev/null
+++ b/Src/Wasabi/api/wnd/resizable.h
@@ -0,0 +1,21 @@
+#ifndef _RESIZABLE_H
+#define _RESIZABLE_H
+
+// {834F172D-FE95-4324-B0EE-BCE29886D7BE}
+static const GUID guiResizableGuid =
+{ 0x834f172d, 0xfe95, 0x4324, { 0xb0, 0xee, 0xbc, 0xe2, 0x98, 0x86, 0xd7, 0xbe } };
+
+class GuiResizable {
+public:
+ virtual void beginMove()=0;
+ virtual void beginScale()=0;
+ virtual void beginResize()=0;
+ virtual void endMove()=0;
+ virtual void endScale()=0;
+ virtual void endResize()=0;
+ virtual ifc_window *guiresizable_getRootWnd()=0;
+ virtual void setEndMoveResize(int w, int h)=0;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/rootwnd.cpp b/Src/Wasabi/api/wnd/rootwnd.cpp
new file mode 100644
index 00000000..2f302a34
--- /dev/null
+++ b/Src/Wasabi/api/wnd/rootwnd.cpp
@@ -0,0 +1,197 @@
+#include <precomp.h>
+#include "rootwnd.h"
+
+#define CBCLASS RootWndI
+START_DISPATCH;
+ CB(GETTIMERCLIENT, getTimerClient);
+ VCB(BATCHPROCESSES, performBatchProcesses);
+ CB(GETOSWINDOWHANDLE, getOsWindowHandle);
+ CB(GETOSMODULEHANDLE, getOsModuleHandle);
+ CB(GETROOTWNDNAME, getRootWndName);
+ CB(GETID, getId);
+ CB(GETGUIOBJECT, getGuiObject);
+ CB(INIT, init);
+ CB(ISINITED, isInited);
+ CB(ISPOSTONINIT, isPostOnInit);
+ CB(SETVIRTUAL, setVirtual);
+ CB(CLICKTHROUGH, isClickThrough);
+ CB(GETFORWARDWND, getForwardWnd);
+ CB(ONMOUSEMOVE, onMouseMove);
+ CB(ONLBUP, onLeftButtonUp);
+ CB(ONRBUP, onRightButtonUp);
+ CB(ONLBDOWN, onLeftButtonDown);
+ CB(ONRBDOWN, onRightButtonDown);
+ CB(ONLBDBLCLK, onLeftButtonDblClk);
+ CB(ONRBDBLCLK, onRightButtonDblClk);
+ CB(GETDRAGINTERFACE, getDragInterface);
+ CB(GETCURSORTYPE, getCursorType);
+ CB(GETCUSTOMCURSOR, getCustomCursor);
+ CB(FROMPOINT, rootWndFromPoint);
+ VCB(GETCLIENTRECT, getClientRect);
+ VCB(GETNONCLIENTRECT, getNonClientRect);
+ VCB(GETWINDOWRECT, getWindowRect);
+ VCB(SETVISIBLE, setVisible);
+ VCB(SETCLOAKED, setCloaked);
+ VCB(ONSETVISIBLE, onSetVisible);
+ CB(ISVISIBLE, isVisible);
+ CB(GETINTERFACE, getInterface);
+ VCB(INVALIDATE, invalidate);
+ VCB(INVALIDATERECT, invalidateRect);
+ VCB(INVALIDATERGN, invalidateRgn);
+ VCB(INVALIDATEFROM, invalidateFrom);
+ VCB(INVALIDATERECTFROM, invalidateRectFrom);
+ VCB(INVALIDATERGNFROM, invalidateRgnFrom);
+ VCB(ONCHILDINVALIDATE, onChildInvalidate);
+ VCB(VALIDATE, validate);
+ VCB(VALIDATERECT, validateRect);
+ VCB(VALIDATERGN, validateRgn);
+ CB(PAINTTREE, rootwnd_paintTree);
+ CB(PAINT, paint);
+ CB(GETFRAMEBUFFER, getFrameBuffer);
+ CB(GETPARENT, getParent);
+ CB(GETROOTPARENT, getRootParent);
+ CB(GETDESKTOPPARENT, getDesktopParent);
+ VCB(SETPARENT, setParent);
+ CB(ONSIBINVALIDATE, onSiblingInvalidateRgn);
+ CB(WANTSIBINVALIDATE, wantSiblingInvalidations);
+ CB(CASCADEREPAINTFROM, cascadeRepaintFrom);
+ CB(CASCADEREPAINTRGNFROM, cascadeRepaintRgnFrom);
+ CB(CASCADEREPAINTRECTFROM, cascadeRepaintRectFrom);
+ CB(CASCADEREPAINT, cascadeRepaint);
+ CB(CASCADEREPAINTRGN, cascadeRepaintRgn);
+ CB(CASCADEREPAINTRECT, cascadeRepaintRect);
+ VCB(REPAINT, repaint);
+ CB(GETTEXTUREWND, getBaseTextureWindow);
+ CB(CHILDNOTIFY, childNotify);
+ CB(GETPREFERENCES, getPreferences);
+ VCB(SETPREFERENCES, setPreferences);
+ CB(GETREGION, getRegion);
+ VCB(SETSTARTHIDDEN, setStartHidden);
+ CB(GETRENDERRATIO, getRenderRatio);
+ VCB(SETRENDERRATIO, setRenderRatio);
+ VCB(SETRATIOLINKED, setRatioLinked);
+ CB(HANDLERATIO, handleRatio);
+ VCB(_RESIZE, resize);
+ VCB(_MOVE, move);
+ VCB(NOTIFYDEFERREDMOVE, notifyDeferredMove);
+ VCB(GETPOSITION, getPosition);
+ VCB(REGISTERROOTWNDCHILD, registerRootWndChild);
+ VCB(UNREGISTERROOTWNDCHILD, unregisterRootWndChild);
+ CB(FINDROOTWNDCHILD, findRootWndChild);
+ CB(ENUMROOTWNDCHILDREN, enumRootWndChildren);
+ CB(GETNUMROOTWNDCHILDREN, getNumRootWndChildren);
+ CB(ISVIRTUAL, isVirtual);
+ VCB(BRINGVTOFRONT, bringVirtualToFront);
+ VCB(BRINGVTOBACK, bringVirtualToBack);
+ VCB(BRINGVABOVE, bringVirtualAbove);
+ VCB(BRINGVBELOW, bringVirtualBelow);
+ CB(CHECKDBLCLK, checkDoubleClick);
+ VCB(SETVCAPTURE, setVirtualChildCapture);
+ CB(GETVCAPTURE, getVirtualChildCapture);
+ CB(PTINREGION, ptInRegion);
+ VCB(CLIENTSCREEN, clientToScreen);
+ VCB(SCREENCLIENT, screenToClient);
+ CB(ONACTIVATE, onActivate);
+ VCB(ACTIVATE, activate);
+ CB(ONDEACTIVATE, onDeactivate);
+ CB(ISACTIVATED, isActive);
+ CB(HANDLETRANSPARENCY, handleTransparency);
+ CB(HANDLEDESKTOPALPHA, handleDesktopAlpha);
+ CB(GETNOTIFYID, getNotifyId);
+ VCB(SETENABLED, setEnabled);
+ CB(ONENABLE, onEnable);
+ CB(ISENABLED, isEnabled);
+ CB(GETPAINTALPHA, getPaintingAlpha);
+ VCB(SETALPHA, setAlpha);
+ VCB(GETALPHA, getAlpha);
+ VCB(SETCLICKTHROUGH, setClickThrough);
+ VCB(SETTOOLTIP, setTip);
+ CB(RUNMODAL, runModal);
+ VCB(ENDMODAL, endModal);
+ CB(WANTAUTOCONTEXTMENU, wantAutoContextMenu);
+ VCB(ONCANCELCAPTURE, onCancelCapture);
+ VCB(CANCELCAPTURE, cancelCapture);
+ VCB(BRINGTOFRONT, bringToFront);
+ VCB(BRINGTOBACK, bringToBack);
+ VCB(SETFOCUS, setFocus);
+ CB(GOTFOCUS, gotFocus);
+ CB(ONGETFOCUS, onGetFocus);
+ CB(ONKILLFOCUS, onKillFocus);
+ CB(GETNEXTVFOCUS, getNextVirtualFocus);
+ VCB(SETVFOCUS, setVirtualChildFocus);
+ CB(WANTFOCUS, wantFocus);
+ CB(ONACCELERATOREVENT, onAcceleratorEvent);
+ CB(ONCHAR, onChar);
+ CB(ONKEYDOWN, onKeyDown);
+ CB(ONKEYUP, onKeyUp);
+ CB(ONSYSKEYDOWN, onSysKeyDown);
+ CB(ONSYSKEYUP, onSysKeyUp);
+ CB(GETREGIONOP, getRegionOp);
+ VCB(SETREGIONOP, setRegionOp);
+ VCB(INVALWNDRGN, invalidateWindowRegion);
+ CB(GETCOMPOSEDRGN, getComposedRegion);
+ CB(GETSUBTRACTORRGN, getSubtractorRegion);
+ CB(ISRECTRGN, isRectRgn);
+ VCB(SETRECTRGN, setRectRgn);
+ CB(GETDEPENDENCYPTR, rootwnd_getDependencyPtr);
+ VCB(ADDMINMAXENFORCER, addMinMaxEnforcer);
+ VCB(REMOVEMINMAXENFORCER, removeMinMaxEnforcer);
+ CB(GETNUMMINMAXENFORCERS, getNumMinMaxEnforcers);
+ CB(ENUMMINMAXENFORCER, enumMinMaxEnforcer);
+ VCB(SIGNALMINMAXCHANGED, signalMinMaxEnforcerChanged);
+ CB(ROOTWNDONACTION, onAction);
+ VCB(SETRENDERBASETEXTURE, setRenderBaseTexture);
+ CB(GETRENDERBASETEXTURE, getRenderBaseTexture);
+ VCB(RENDERBASETEXTURE, rootwnd_renderBaseTexture);
+ CB(TRIGGEREVENT, triggerEvent);
+ CB(GETFLAG, getFlag);
+ CB(ALLOWDEACTIVATE, allowDeactivation);
+ VCB(SETALLOWDEACTIVATE, setAllowDeactivation);
+ CB(FINDWND_BYID, findWindow);
+ CB(FINDWND_BYGUID, findWindowByInterface);
+ CB(FINDWND_BYCB, findWindowByCallback);
+ CB(FINDWNDCHAIN, findWindowChain);
+ VCB(SETTABORDER, setTabOrder);
+ CB(GETTABORDER, getTabOrder);
+ VCB(SETVIRTUALTABORDER, setVirtualTabOrder);
+ CB(GETVIRTUALTABORDER, getVirtualTabOrder);
+ VCB(SETAUTOTABORDER, setAutoTabOrder);
+ VCB(SETVIRTUALAUTOTABORDER, setVirtualAutoTabOrder);
+ CB(GETCURVIRTUALCHILDFOCUS, getCurVirtualChildFocus);
+ CB(GETTAB, getTab);
+ VCB(FOCUSNEXT, focusNext);
+ VCB(FOCUSPREVIOUS, focusPrevious);
+ VCB(SETWINDOWTITLE, setWindowTitle);
+ CB(ENUMTAB, enumTab);
+ CB(GETNUMTABS, getNumTabs);
+ VCB(ONSETROOTFOCUS, onSetRootFocus);
+ VCB(SETFOCUSONCLICK, setFocusOnClick);
+ CB(GETFOCUSONCLICK, getFocusOnClick);
+ VCB(SETNODOUBLECLICKS, setNoDoubleClicks);
+ VCB(SETNOLEFTCLICKS, setNoLeftClicks);
+ VCB(SETNORIGHTCLICKS, setNoRightClicks);
+ VCB(SETNOMOUSEMOVES, setNoMouseMoves);
+ VCB(SETNOCONTEXTMENUS, setNoContextMenus);
+ CB(WANTLEFTCLICKS, wantLeftClicks);
+ CB(WANTRIGHTCLICKS, wantRightClicks);
+ CB(WANTDOUBLECLICKS, wantDoubleClicks);
+ CB(WANTMOUSEMOVES, wantMouseMoves);
+ CB(WANTCONTEXTMENUS, wantContextMenus);
+ CB(WANTACTIVATION, wantActivation);
+ VCB(SETDEFAULTCURSOR, setDefaultCursor);
+ CB(GETACCESSIBLEOBJECT, getAccessibleObject);
+ CB(ACCGETSTATE,accessibility_getState);
+#ifndef WA3COMPATIBILITY
+ VCB(SETDROPTARGET, setDropTarget);
+ CB(GETDROPTARGET, getDropTarget);
+#endif
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ VCB(SETALWAYSONTOP, setAlwaysOnTop);
+ CB(GETALWAYSONTOP, getAlwaysOnTop);
+#endif
+ CB(ISMINIMIZED, isMinimized);
+ VCB(MAXIMIZE, maximize);
+ VCB(RESTORE, restore);
+ CB(GETRESTOREDRECT, getRestoredRect);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/wnd/rootwnd.h b/Src/Wasabi/api/wnd/rootwnd.h
new file mode 100644
index 00000000..2b33e324
--- /dev/null
+++ b/Src/Wasabi/api/wnd/rootwnd.h
@@ -0,0 +1,275 @@
+#ifndef _ROOTWND_H
+#define _ROOTWND_H
+
+#include "api_window.h"
+#include <bfc/wasabi_std.h>
+#include <bfc/dispatch.h>
+#include <api/wnd/cursor.h>
+
+class ifc_canvas;
+class api_region;
+class TimerClient;
+class ifc_dependent;
+class GuiObject;
+class FindObjectCallback;
+class Cursor;
+class Accessible;
+class Canvas;
+
+// only these methods are safe across dll boundaries
+// this is the pointer you find in the GWL_USERDATA of a window
+
+class DragInterface;
+
+class NOVTABLE RootWndI : public ifc_window
+{
+protected:
+ RootWndI() {} // protect constructor
+
+public:
+ virtual OSWINDOWHANDLE getOsWindowHandle()=0;
+ virtual OSMODULEHANDLE getOsModuleHandle()=0;
+ virtual void performBatchProcesses()=0;
+ virtual TimerClient *getTimerClient()=0;
+ virtual const wchar_t *getRootWndName()=0;
+ virtual const wchar_t *getId()=0;
+ virtual int init(ifc_window *parent, int nochild)=0;
+ virtual int isInited()=0;
+ virtual int isPostOnInit()=0;
+
+ virtual int setVirtual(int i)=0;
+
+ virtual int isClickThrough()=0;
+ virtual int onMouseMove(int x, int y)=0;
+ virtual int onLeftButtonUp(int x, int y)=0;
+ virtual int onRightButtonUp(int x, int y)=0;
+ virtual int onLeftButtonDown(int x, int y)=0;
+ virtual int onRightButtonDown(int x, int y)=0;
+ virtual int onLeftButtonDblClk(int x, int y)=0;
+ virtual int onRightButtonDblClk(int x, int y)=0;
+
+ virtual DragInterface *getDragInterface()=0;
+
+ virtual int getCursorType(int x, int y)=0;
+ virtual OSCURSORHANDLE getCustomCursor(int x, int y)=0;
+ virtual ifc_window *rootWndFromPoint(POINT *pt)=0;
+
+ virtual void getClientRect(RECT *r)=0;
+ virtual void getNonClientRect(RECT *rect)=0;
+ virtual void getWindowRect(RECT *r)=0;
+
+ virtual void setVisible(int show)=0;
+ virtual void setCloaked(int cloak)=0;
+ virtual void onSetVisible(int show)=0;
+ virtual int isVisible(int within=0)=0;
+
+ virtual void *getInterface(GUID interface_guid)=0;
+
+ virtual void invalidate()=0;
+ virtual void invalidateRect(RECT *r)=0;
+ virtual void invalidateRgn(api_region *r)=0;
+ virtual void invalidateFrom(ifc_window *who)=0;
+ virtual void invalidateRectFrom(RECT *r, ifc_window *who)=0;
+ virtual void invalidateRgnFrom(api_region *r, ifc_window *who)=0;
+ virtual void validate()=0;
+ virtual void validateRect(RECT *r)=0;
+ virtual void validateRgn(api_region *reg)=0;
+ virtual void onChildInvalidate(api_region *r, ifc_window *who)=0;
+
+ virtual int rootwnd_paintTree(ifc_canvas *canvas, api_region *r)=0;
+ virtual int paint (Canvas *canvas, api_region *r)=0;
+ virtual Canvas *getFrameBuffer()=0;
+
+ virtual ifc_window *getParent()=0;
+ virtual ifc_window *getRootParent()=0;
+ virtual ifc_window *getDesktopParent()=0;
+ virtual void setParent(ifc_window *parent)=0;
+
+ virtual int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx)=0;
+ virtual int wantSiblingInvalidations()=0;
+
+ virtual int cascadeRepaintFrom(ifc_window *who, int pack=1)=0;
+ virtual int cascadeRepaintRgnFrom(api_region *reg, ifc_window *who, int pack=1)=0;
+ virtual int cascadeRepaintRectFrom(RECT *r, ifc_window *who, int pack=1)=0;
+ virtual int cascadeRepaint(int pack=1)=0;
+ virtual int cascadeRepaintRgn(api_region *reg, int pack=1)=0;
+ virtual int cascadeRepaintRect(RECT *r, int pack=1)=0;
+ virtual void repaint()=0;
+
+ virtual void setClickThrough(int ct)=0;
+ virtual ifc_window *getBaseTextureWindow()=0;
+ virtual void rootwnd_renderBaseTexture(ifc_canvas *c, const RECT *r, int alpha=255)=0;
+#if defined (_WIN64)
+ virtual int childNotify(ifc_window* child, int msg, int p1, int p2) = 0;
+#else
+ virtual int childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)=0;
+#endif
+ virtual int getPreferences(int what)=0;
+ virtual void setPreferences(int what, int v)=0;
+
+ virtual api_region *getRegion()=0;
+ virtual int getRegionOp()=0;
+ virtual void setRegionOp(int op)=0;
+ virtual int isRectRgn()=0;
+ virtual void setRectRgn(int rrgn)=0;
+ virtual void invalidateWindowRegion()=0;
+ virtual api_region *getComposedRegion()=0;
+ virtual api_region *getSubtractorRegion()=0;
+
+ virtual void setStartHidden(int sh)=0;
+ virtual double getRenderRatio()=0;
+ virtual void setRenderRatio(double r)=0;
+ virtual void setRatioLinked(int l)=0;
+ virtual int handleRatio()=0;
+ virtual void resize(int x, int y, int w, int h, int wantcb=1)=0;
+ virtual void move(int x, int y)=0;
+ virtual void notifyDeferredMove(int x, int y)=0;
+
+ virtual void getPosition(POINT *pt)=0;
+ virtual ifc_window *getForwardWnd()=0;
+
+ virtual void registerRootWndChild(ifc_window *child)=0;
+ virtual void unregisterRootWndChild(ifc_window *child)=0;
+ virtual ifc_window *findRootWndChild(int x, int y, int only_virtuals=0)=0;
+ virtual ifc_window *enumRootWndChildren(int _enum)=0;
+ virtual int getNumRootWndChildren()=0;
+
+ virtual int isVirtual()=0;
+
+ virtual void bringVirtualToFront(ifc_window *w)=0;
+ virtual void bringVirtualToBack(ifc_window *w)=0;
+ virtual void bringVirtualAbove(ifc_window *w, ifc_window *b)=0;
+ virtual void bringVirtualBelow(ifc_window *w, ifc_window *b)=0;
+ virtual int checkDoubleClick(int button, int x, int y)=0;
+
+ virtual void onCancelCapture()=0;
+ virtual void cancelCapture()=0;
+
+ virtual void clientToScreen(int *x, int *y)=0;
+ virtual void screenToClient(int *x, int *y)=0;
+
+ virtual void setVirtualChildCapture(ifc_window *child)=0;
+ virtual ifc_window *getVirtualChildCapture()=0;
+
+ virtual int ptInRegion(int x, int y)=0;
+
+ virtual int onActivate()=0;
+ virtual void activate()=0;
+ virtual int onDeactivate()=0;
+ virtual int isActive()=0;
+ virtual int handleTransparency()=0;
+ virtual int handleDesktopAlpha()=0;
+
+ virtual int getNotifyId()=0;
+ virtual void setEnabled(int en)=0;
+ virtual int isEnabled(int within=0)=0;
+ virtual int onEnable(int e)=0;
+
+ virtual int getPaintingAlpha()=0;
+ virtual void getAlpha(int *active=NULL, int *inactive=NULL)=0;
+ virtual void setAlpha(int activealpha, int inactivealpha=-1)=0;
+
+ virtual void setTip(const wchar_t *tip)=0;
+ virtual int runModal()=0;
+ virtual void endModal(int retcode)=0;
+ virtual int wantAutoContextMenu()=0;
+ virtual int wantActivation()=0;
+
+ virtual void bringToFront()=0;
+ virtual void bringToBack()=0;
+ virtual void setFocus()=0;
+ virtual int gotFocus()=0;
+ virtual ifc_window *getNextVirtualFocus(ifc_window *w)=0;
+ virtual void setVirtualChildFocus(ifc_window *w)=0;
+ virtual void setVirtualTabOrder(ifc_window *w, int a)=0;
+ virtual int getVirtualTabOrder(ifc_window *w)=0;
+ virtual int wantFocus()=0;
+ virtual void setTabOrder(int a)=0;
+ virtual int getTabOrder()=0;
+ virtual ifc_window *getTab(int what=TAB_GETCURRENT)=0;
+ virtual void setAutoTabOrder()=0;
+ virtual void setVirtualAutoTabOrder(ifc_window *w)=0;
+ virtual ifc_window *getCurVirtualChildFocus()=0;
+ virtual void onSetRootFocus(ifc_window *w)=0;
+
+ virtual int onAcceleratorEvent(const wchar_t *name)=0;
+
+ virtual int onChar(unsigned int c)=0;
+ virtual int onKeyDown(int keycode)=0;
+ virtual int onKeyUp(int keycode)=0;
+ virtual int onSysKeyDown(int keyCode, int keyData)=0;
+ virtual int onSysKeyUp(int keyCode, int keyData)=0;
+ virtual int onKillFocus()=0;
+ virtual int onGetFocus()=0;
+ virtual ifc_dependent *rootwnd_getDependencyPtr()=0;
+ virtual void addMinMaxEnforcer(ifc_window *w)=0;
+ virtual void removeMinMaxEnforcer(ifc_window *w)=0;
+ virtual ifc_window *enumMinMaxEnforcer(int n)=0;
+ virtual int getNumMinMaxEnforcers()=0;
+ virtual void signalMinMaxEnforcerChanged()=0;
+
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL)=0;
+
+ virtual void setRenderBaseTexture(int r)=0;
+ virtual int getRenderBaseTexture()=0;
+ virtual GuiObject *getGuiObject()=0; // not guaranteed non null
+
+ virtual int getFlag(int flag)=0;
+ virtual int triggerEvent(int event, intptr_t p1, intptr_t p2)=0;
+
+
+ virtual int allowDeactivation()=0;
+ virtual void setAllowDeactivation(int allow)=0;
+
+ virtual ifc_window *findWindow(const wchar_t *id)=0;
+ virtual ifc_window *findWindowByInterface(GUID interface_guid)=0;
+ virtual ifc_window *findWindowByCallback(FindObjectCallback *cb)=0;
+ virtual ifc_window *findWindowChain(FindObjectCallback *cb, ifc_window *wcaller)=0;
+
+ virtual void focusNext()=0;
+ virtual void focusPrevious()=0;
+
+ virtual void setWindowTitle(const wchar_t *title) = 0;
+ virtual ifc_window *enumTab(int i)=0;
+ virtual int getNumTabs()=0;
+
+ virtual int getFocusOnClick()=0;
+ virtual void setFocusOnClick(int i)=0;
+
+ virtual void setNoDoubleClicks(int no)=0;
+ virtual void setNoLeftClicks(int no)=0;
+ virtual void setNoRightClicks(int no)=0;
+ virtual void setNoMouseMoves(int no)=0;
+ virtual void setNoContextMenus(int no)=0;
+
+ virtual int wantDoubleClicks()=0;
+ virtual int wantLeftClicks()=0;
+ virtual int wantRightClicks()=0;
+ virtual int wantMouseMoves()=0;
+ virtual int wantContextMenus()=0;
+
+ virtual void setDefaultCursor(Cursor *c)=0;
+
+ virtual Accessible *getAccessibleObject(int createifnotexist=1)=0;
+ virtual int accessibility_getState()=0;
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ virtual void setAlwaysOnTop(int i)=0;
+ virtual int getAlwaysOnTop()=0;
+#endif
+
+#ifndef WA3COMPATIBILITY
+ virtual void setDropTarget(void *dt)=0;
+ virtual void *getDropTarget()=0;
+#endif
+
+ virtual int isMinimized()=0;
+ virtual void maximize(int axis=MAXIMIZE_WIDTH|MAXIMIZE_HEIGHT)=0;
+ virtual void restore(int what=RESTORE_X|RESTORE_Y|RESTORE_WIDTH|RESTORE_HEIGHT)=0;
+ virtual int getRestoredRect(RECT *r)=0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/textalign.h b/Src/Wasabi/api/wnd/textalign.h
new file mode 100644
index 00000000..83ea89e5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/textalign.h
@@ -0,0 +1,32 @@
+/*
+
+Darkain Made This. :)
+// and BU tweaked it
+
+*/
+
+/*
+Darkain: i wanted one base for ALL text alignment in ALL classes.
+*/
+
+
+#ifndef _TEXTALIGN_H
+#define _TEXTALIGN_H
+
+typedef enum {
+ TEXTALIGN_LEFT,
+ TEXTALIGN_CENTER, //what ever default center style is... see bellow
+ TEXTALIGN_RIGHT,
+ TEXTALIGN_EVENSPACING, //add more space between letters/words to make it fit in 100% of the area
+ TEXTALIGN_FITTOWIDTH, //make the font larger or smaller to fit in 100% of the area
+ TEXTALIGN_LEFT_ELLIPSIS, //align left, and truncate text to fit if too large
+ TEXTALIGN_CENTER_CENTER, //if text is too wide, it will still center on the middle, choping off left and right sides
+ TEXTALIGN_CENTER_LEFT, //will chop off right side if too big
+ TEXTALIGN_CENTER_RIGHT, //will chop off left side if too big
+ TEXTALIGN_SCROLL, //if text is too large, it will use default scrolling (see bellow)
+ TEXTALIGN_SCROLL_BACKFORTH, //text will scroll back and forth if too large
+ TEXTALIGN_SCROLL_TICKER, //text will scroll in one direction, and loop
+} TextAlign;
+
+
+#endif // TEXT_ALIGN_H
diff --git a/Src/Wasabi/api/wnd/usermsg.h b/Src/Wasabi/api/wnd/usermsg.h
new file mode 100644
index 00000000..21da3e5a
--- /dev/null
+++ b/Src/Wasabi/api/wnd/usermsg.h
@@ -0,0 +1,23 @@
+#ifndef _USERMSG_H
+#define _USERMSG_H
+
+// WM_USER+ messages for common classes
+// DO NOT PUT ANY MORE FUCKING NON WNDPROC SHIT IN HERE
+// childNotify stuff goes into notifmsg.h
+#ifdef _WIN32
+enum
+{
+ UMSG_NOP = WM_USER,
+
+ UMSG_DEFERRED_CALLBACK,
+
+//CUT UMSG_TREEVIEW_EDITLABELDEFERRED,
+//CUT UMSG_TREEVIEW_SELECTITEM,
+
+ UMSG_COMPON_POSTMESSAGE,
+
+ LAST_COMMON_UMSG
+};
+#endif
+
+#endif
diff --git a/Src/Wasabi/api/wnd/virtualwnd.cpp b/Src/Wasabi/api/wnd/virtualwnd.cpp
new file mode 100644
index 00000000..dd45da11
--- /dev/null
+++ b/Src/Wasabi/api/wnd/virtualwnd.cpp
@@ -0,0 +1,672 @@
+#include <precomp.h>
+#include "virtualwnd.h"
+#include <tataki/region/api_region.h>
+
+#include <api/wnd/usermsg.h>
+#include <api/wnd/accessible.h>
+
+VirtualWnd::VirtualWnd()
+{
+ virtualX = virtualY = virtualH = virtualW = 0;
+ bypassvirtual = 0;
+ focus = 0;
+ resizecount = 0;
+ lastratio = 1;
+}
+
+VirtualWnd::~VirtualWnd()
+{}
+
+int VirtualWnd::init(ifc_window *parWnd, int nochild)
+{
+ if (!bypassvirtual)
+ setParent(parWnd);
+
+ return (VIRTUALWND_PARENT::init(parWnd, nochild));
+}
+
+int VirtualWnd::init(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild)
+{
+ if (!bypassvirtual)
+ {
+ ASSERTPR(getParent() != NULL, "Virtual window created without specifying BaseWnd parent");
+
+ if (getStartHidden())
+ this_visible = 0;
+ else
+ this_visible = 1;
+
+ onInit();
+
+ onPostOnInit();
+
+ if (isVisible())
+ onSetVisible(1);
+
+ return 1;
+ }
+ else
+ return VIRTUALWND_PARENT::init(moduleHandle, parent, nochild);
+}
+
+OSWINDOWHANDLE VirtualWnd::getOsWindowHandle()
+{
+ // ASSERTPR(getParent() != NULL, "Virtual window used as base parent !");
+ if (!bypassvirtual)
+ {
+ if (!getParent())
+ return INVALIDOSWINDOWHANDLE;
+
+ return getParent()->getOsWindowHandle();
+ }
+ else
+ {
+ return VIRTUALWND_PARENT::getOsWindowHandle();
+ }
+}
+
+OSMODULEHANDLE VirtualWnd::getOsModuleHandle()
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent())
+ return INVALIDOSMODULEHANDLE;
+
+ return getParent()->getOsModuleHandle();
+ }
+ else
+ return VIRTUALWND_PARENT::getOsModuleHandle();
+}
+
+void VirtualWnd::resize(RECT *r, int wantcb)
+{
+ if (!bypassvirtual)
+ {
+ resize(r->left, r->top, r->right - r->left, r->bottom - r->top, wantcb);
+ }
+ else
+ {
+ VIRTUALWND_PARENT::resize( r, wantcb );
+
+ //virtualX = rx;
+ //virtualY = ry;
+ //virtualW = rwidth;
+ //virtualH = rheight;
+ }
+}
+
+// fg> the resizecount > 1 is a hack, it should be 0 but i need more time to fix this thing, at least this way we don't lose the optim
+void VirtualWnd::resize(int x, int y, int w, int h, int wantcb)
+{
+ if (!bypassvirtual)
+ {
+ if (x == NOCHANGE)
+ x = virtualX;
+
+ if (y == NOCHANGE)
+ y = virtualY;
+
+ if (w == NOCHANGE)
+ w = virtualW;
+
+ if (h == NOCHANGE)
+ h = virtualH;
+
+ double thisratio = getRenderRatio();
+
+ if (resizecount > 1 && virtualX == x && virtualY == y && virtualW == w && virtualH == h && lastratio == thisratio)
+ return ;
+
+ lastratio = thisratio;
+
+ if (isVisible())
+ {
+ RECT r;
+ getNonClientRect(&r);
+ invalidateRect(&r);
+ }
+
+ virtualX = x;
+ virtualY = y;
+ virtualW = w;
+ virtualH = h;
+
+ if (isVisible())
+ {
+ RECT r;
+ getNonClientRect(&r);
+ invalidateRect(&r);
+ }
+
+ setRSize(x, y, w, h);
+
+ if (wantcb && isPostOnInit())
+ {
+ resizecount = MIN(resizecount + 1, 2);
+ onResize();
+ }
+ }
+ else
+ {
+ VIRTUALWND_PARENT::resize( x, y, w, h, wantcb );
+
+ //virtualX = rx;
+ //virtualY = ry;
+ //virtualW = rwidth;
+ //virtualH = rheight;
+ }
+}
+
+//CUTvoid VirtualWnd::resize(RECT *r) {
+//CUT resize(r->left, r->top, r->right-r->left, r->bottom-r->top);
+//CUT}
+
+void VirtualWnd::move(int x, int y)
+{
+ //DebugStringW( L"VirtualWnd::move( x = %d, y = %d )\n", x, y );
+
+ if (!bypassvirtual)
+ {
+ if (isVisible())
+ {
+ RECT r;
+ getNonClientRect(&r);
+ invalidateRect(&r);
+ }
+
+ virtualX = x;
+ virtualY = y;
+
+ if (isVisible())
+ {
+ RECT r;
+ getNonClientRect(&r);
+ invalidateRect(&r);
+ }
+ }
+ else
+ {
+ VIRTUALWND_PARENT::move( x, y );
+
+ //virtualX = x;
+ //virtualY = y;
+ }
+}
+
+void VirtualWnd::invalidate()
+{
+ if (!bypassvirtual)
+ {
+ if (!getRootParent()) return ;
+ RECT r(clientRect());
+ getRootParent()->invalidateRectFrom(&r, this);
+ // VIRTUALWND_PARENT::invalidate();
+ }
+ else
+ VIRTUALWND_PARENT::invalidate();
+}
+
+void VirtualWnd::invalidateRect(RECT *r)
+{
+ if (!bypassvirtual)
+ {
+ if (!getRootParent()) return ;
+ getRootParent()->invalidateRectFrom(r, this);
+ }
+ else
+ VIRTUALWND_PARENT::invalidateRect(r);
+}
+
+void VirtualWnd::invalidateRgn(api_region *reg)
+{
+ if (!bypassvirtual)
+ {
+ if (!getRootParent()) return ;
+ getRootParent()->invalidateRgnFrom(reg, this);
+ }
+ else
+ VIRTUALWND_PARENT::invalidateRgn(reg);
+}
+
+void VirtualWnd::validate()
+{
+ if (!bypassvirtual)
+ {
+ if (!getRootParent()) return ;
+ RECT r;
+ getClientRect(&r);
+ getRootParent()->validateRect(&r);
+ }
+ else
+ VIRTUALWND_PARENT::validate();
+}
+
+void VirtualWnd::validateRect(RECT *r)
+{
+ if (!bypassvirtual)
+ {
+ if (!getRootParent())
+ return ;
+
+ getRootParent()->validateRect(r);
+ }
+ else
+ VIRTUALWND_PARENT::validateRect( r );
+}
+
+void VirtualWnd::validateRgn(api_region *reg)
+{
+ if (!bypassvirtual)
+ {
+ if (!getRootParent()) return ;
+ getRootParent()->validateRgn(reg);
+ }
+ else
+ VIRTUALWND_PARENT::validateRgn(reg);
+}
+
+void VirtualWnd::getClientRect(RECT *rect)
+{
+ if (!bypassvirtual)
+ {
+ // CT:getClientRect behaves differently here for virtual windows
+ // so we can use onPaint directly on the destination canvas
+ // without using another temporary canvas.
+ Wasabi::Std::setRect(rect, virtualX, virtualY, virtualX + virtualW, virtualY + virtualH);
+ // rect->left=0; rect->right=virtualW;
+ // rect->top=0; rect->bottom=virtualH;
+ }
+ else
+ VIRTUALWND_PARENT::getClientRect(rect);
+}
+
+void VirtualWnd::getNonClientRect(RECT *rect)
+{
+ VirtualWnd::getClientRect(rect);
+}
+
+void VirtualWnd::getWindowRect(RECT *rect)
+{
+ if (!bypassvirtual)
+ {
+ RECT a;
+ getRootParent()->getWindowRect(&a);
+
+ int x = virtualX, y = virtualY, w = virtualW, h = virtualH;
+
+ if (renderRatioActive())
+ {
+ multRatio(&x, &y);
+ multRatio(&w, &h);
+ }
+
+ rect->left = a.left + x; rect->right = rect->left + w;
+ rect->top = a.top + y; rect->bottom = rect->top + h;
+ }
+ else
+ VIRTUALWND_PARENT::getWindowRect(rect);
+}
+
+int VirtualWnd::beginCapture()
+{
+ if (!bypassvirtual)
+ {
+ disable_tooltip_til_recapture = 0;
+ getRootParent()->setVirtualChildCapture(this);
+ return 1;
+ }
+ else
+ return VIRTUALWND_PARENT::beginCapture();
+}
+
+int VirtualWnd::endCapture()
+{
+ if (!bypassvirtual)
+ {
+ if (getRootParent() == NULL) return 0;
+ getRootParent()->setVirtualChildCapture(NULL);
+ return 1;
+ }
+ else
+ return VIRTUALWND_PARENT::endCapture();
+}
+
+int VirtualWnd::getCapture()
+{
+ if (!bypassvirtual)
+ {
+ if (getRootParent() == NULL) return 0;
+ return getRootParent()->getVirtualChildCapture() == this;
+ }
+ else
+ return VIRTUALWND_PARENT::getCapture();
+}
+
+void VirtualWnd::setVirtualChildCapture(BaseWnd *child)
+{
+ if (!bypassvirtual)
+ {
+ getParent()->setVirtualChildCapture(child);
+ }
+ else
+ VIRTUALWND_PARENT::setVirtualChildCapture(child);
+}
+
+// eek
+void VirtualWnd::repaint()
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return ;
+ getParent()->repaint();
+ }
+ else
+ VIRTUALWND_PARENT::repaint();
+}
+
+/*int VirtualWnd::focusNextSibbling(int dochild) {
+ return 1;
+}
+
+int VirtualWnd::focusNextVirtualChild(BaseWnd *child) {
+ return 1;
+}*/
+
+int VirtualWnd::cascadeRepaint(int pack)
+{
+ if (!bypassvirtual)
+ {
+ if (getRootParent())
+ {
+ RECT r;
+ VirtualWnd::getNonClientRect(&r);
+ getRootParent()->cascadeRepaintRectFrom(&r, this, pack);
+ }
+ return 1;
+ }
+ else
+ return VIRTUALWND_PARENT::cascadeRepaint(pack);
+}
+
+int VirtualWnd::cascadeRepaintRect(RECT *r, int pack)
+{
+ if (!bypassvirtual)
+ {
+ if (getRootParent())
+ {
+ getRootParent()->cascadeRepaintRectFrom(r, this, pack);
+ }
+ return 1;
+ }
+ else
+ return VIRTUALWND_PARENT::cascadeRepaintRect(r, pack);
+}
+
+int VirtualWnd::cascadeRepaintRgn(api_region *r, int pack)
+{
+ if (!bypassvirtual)
+ {
+ if (getRootParent())
+ {
+ getRootParent()->cascadeRepaintRgnFrom(r, this, pack);
+ }
+ return 1;
+ }
+ else
+ return VIRTUALWND_PARENT::cascadeRepaintRgn(r, pack);
+}
+
+/*api_window *VirtualWnd::getWindowBehindMyself(int x, int y) {
+ RECT r;
+ if (!bypassvirtual) {
+ if (!getParent()) return NULL;
+ int n = getParent()->getNumVirtuals();
+
+ api_window *c = NULL;
+
+ for (int i=n-1;i>=0;i++) {
+ c = getParent()->getVirtualChild(i);
+ if (c == this) break;
+ }
+
+ i--;
+ if (i < 0) return getParent();
+
+ for (;i>=0; i--) {
+ c = getParent()->getVirtualChild(i);
+ c->getNonClientRect(&r);
+ if (x>=r.left&&x<=r.right&&y>=r.top&&y<=r.bottom)
+ return c;
+ }
+ return getParent();
+ } else
+ return NULL;
+}*/
+
+ifc_window *VirtualWnd::rootWndFromPoint(POINT *pt)
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return NULL;
+ return getParent()->rootWndFromPoint(pt);
+ }
+ else
+ return VIRTUALWND_PARENT::rootWndFromPoint(pt);
+}
+
+double VirtualWnd::getRenderRatio()
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return 1.0;
+ return getParent()->getRenderRatio();
+ }
+ else
+ return VIRTUALWND_PARENT::getRenderRatio();
+}
+
+void VirtualWnd::bringToFront()
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return ;
+ //getParent()->bringVirtualToFront(this); TODO: FIX!!!
+ }
+ else
+ VIRTUALWND_PARENT::bringToFront();
+}
+
+void VirtualWnd::bringToBack()
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return ;
+ //getParent()->bringVirtualToBack(this); TODO: FIX!!!
+ }
+ else
+ VIRTUALWND_PARENT::bringToBack();
+}
+
+void VirtualWnd::bringAbove(BaseWnd *o)
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return ;
+ getParent()->bringVirtualAbove(this, o);
+ } /* else
+ VIRTUALWND_PARENT::bringAbove();*/
+}
+
+void VirtualWnd::bringBelow(BaseWnd *o)
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return ;
+ getParent()->bringVirtualBelow(this, o);
+ } /* else
+ VIRTUALWND_PARENT::bringBelow();*/
+}
+
+int VirtualWnd::reparent(ifc_window *newparent)
+{
+ if (!bypassvirtual)
+ {
+ if (getParent())
+ getParent()->unregisterRootWndChild(this);
+ parentWnd = NULL;
+ newparent->registerRootWndChild(this);
+ onSetParent(newparent);
+ newparent->invalidate();
+ return 1;
+ }
+ else
+ {
+ return VIRTUALWND_PARENT::reparent(newparent);
+ }
+}
+
+int VirtualWnd::setVirtual(int i)
+{
+ // ASSERT(!isInited()); // cut
+
+ if (isInited()) return 0;
+ bypassvirtual = !i;
+ return 1;
+}
+
+ifc_window *VirtualWnd::getRootParent()
+{
+ if (!bypassvirtual)
+ {
+ if (!getParent()) return NULL;
+ ifc_window *t = this;
+ while (t->isVirtual())
+ {
+ if (!t->getParent()) return NULL;
+ t = t->getParent();
+ }
+ return t;
+ }
+ else
+ {
+ return VIRTUALWND_PARENT::getRootParent();
+ }
+}
+
+int VirtualWnd::gotFocus()
+{
+ if (!bypassvirtual)
+ return focus;
+ else
+ return VIRTUALWND_PARENT::gotFocus();
+}
+
+int VirtualWnd::onGetFocus()
+{
+ if (!bypassvirtual)
+ {
+ focus = 1;
+ getRootParent()->onSetRootFocus(this);
+ invalidate();
+ Accessible *a = getAccessibleObject();
+ if (a != NULL)
+ a->onGetFocus();
+ }
+ else
+ return VIRTUALWND_PARENT::onGetFocus();
+ return 1;
+}
+
+int VirtualWnd::onKillFocus()
+{
+ if (!bypassvirtual)
+ {
+ focus = 0;
+ invalidate();
+ }
+ else
+ return VIRTUALWND_PARENT::onKillFocus();
+ return 1;
+}
+
+void VirtualWnd::setFocus()
+{
+ ifc_window *f = this;
+ if (!f->wantFocus() && f->getParent())
+ {
+ while (f)
+ {
+ ifc_window *rp = f->getRootParent();
+ if (rp == f) rp = f->getParent();
+ f = rp;
+ if (f && (!f->getParent() || f->wantFocus() || f == WASABI_API_WND->main_getRootWnd()))
+ {
+ f->setFocus();
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!bypassvirtual)
+ {
+ if (getParent())
+ {
+ getParent()->setVirtualChildFocus(this);
+ }
+ }
+ else
+ VIRTUALWND_PARENT::setFocus();
+ }
+}
+
+void VirtualWnd::setVirtualChildFocus(ifc_window *child)
+{
+ if (!bypassvirtual)
+ {
+ getParent()->setVirtualChildFocus(child);
+ }
+ else
+ VIRTUALWND_PARENT::setVirtualChildFocus(child);
+}
+
+int VirtualWnd::onActivate()
+{
+ if (bypassvirtual)
+ return VIRTUALWND_PARENT::onActivate();
+ return 1;
+}
+
+int VirtualWnd::onDeactivate()
+{
+ if (bypassvirtual)
+ return VIRTUALWND_PARENT::onDeactivate();
+ return 1;
+}
+
+void VirtualWnd::setAllowDeactivation(int allow)
+{
+ ifc_window *w = getDesktopParent();
+ if (w != NULL && w != this)
+ w->setAllowDeactivation(allow);
+ else VIRTUALWND_PARENT::setAllowDeactivation(allow);
+}
+
+int VirtualWnd::allowDeactivation()
+{
+ ifc_window *w = getDesktopParent();
+ if (w != NULL && w != this)
+ return w->allowDeactivation();
+ return VIRTUALWND_PARENT::allowDeactivation();
+}
+
+
+
+/* todo: setCursor
+
+ + real childs going invisible should deferedInvalidate their rect on their parent window if it has a virtualCanvas
+*/
+
+
+
+// No need for screenToClient/clientToScreen overrides since the virtual's origin is the same as it's parent
diff --git a/Src/Wasabi/api/wnd/virtualwnd.h b/Src/Wasabi/api/wnd/virtualwnd.h
new file mode 100644
index 00000000..fc10ef63
--- /dev/null
+++ b/Src/Wasabi/api/wnd/virtualwnd.h
@@ -0,0 +1,84 @@
+#ifndef _VIRTUALWND_H
+#define _VIRTUALWND_H
+
+#include <api/wnd/basewnd.h>
+
+#define VIRTUALWND_PARENT BaseWnd
+#define AUTOWH 0xFFFE
+#define NOCHANGE 0xFFFD
+
+class NOVTABLE VirtualWnd : public VIRTUALWND_PARENT
+{
+protected:
+ VirtualWnd();
+ virtual ~VirtualWnd();
+public:
+ virtual int init( ifc_window *parent, int nochild = FALSE );
+ virtual int init( OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild = FALSE );
+
+ virtual void bringToFront();
+ virtual void bringToBack();
+ virtual void bringAbove( BaseWnd *w );
+ virtual void bringBelow( BaseWnd *w );
+
+ //NONPORTABLE--avoid prolonged use
+ virtual HWND getOsWindowHandle();
+ virtual HINSTANCE getOsModuleHandle();
+
+public:
+ virtual void resize( int x, int y, int w, int h, int wantcb = 1 ) override;
+ virtual void resize( RECT *r, int wantcb = 1 );
+ virtual void move( int x, int y ) override;
+ virtual void invalidate() override;
+ virtual void invalidateRect( RECT *r ) override;
+ virtual void invalidateRgn( api_region *reg ) override;
+ virtual void validate() override;
+ virtual void validateRect( RECT *r ) override;
+ virtual void validateRgn( api_region *reg ) override;
+ virtual void getClientRect( RECT * ) override;
+ virtual void getNonClientRect( RECT * ) override;
+ virtual void getWindowRect( RECT * ) override;
+ virtual int beginCapture() override;
+ virtual int endCapture() override;
+ virtual int getCapture() override;
+ virtual void setVirtualChildCapture( BaseWnd *child );
+ virtual void repaint() override;
+ /* virtual int focusNextSibbling(int dochild);
+ virtual int focusNextVirtualChild(BaseWnd *child);*/
+ virtual int cascadeRepaint( int pack = 1 ) override;
+ virtual int cascadeRepaintRect( RECT *r, int pack = 1 ) override;
+ virtual int cascadeRepaintRgn( api_region *r, int pack = 1 ) override;
+ virtual ifc_window *rootWndFromPoint( POINT *pt ) override;
+ virtual double getRenderRatio() override;
+ virtual int reparent( ifc_window *newparent ) override;
+ virtual int setVirtual( int i ) override;
+ virtual ifc_window *getRootParent() override;
+ virtual int gotFocus() override;
+ virtual int onGetFocus() override;
+ virtual int onKillFocus() override;
+ virtual void setFocus() override;
+ virtual int onActivate() override;
+ virtual int onDeactivate() override;
+ virtual void setVirtualChildFocus( ifc_window *child ) override;
+ virtual int wantFocus() override
+ {
+ return 0;
+ }
+ virtual void setAllowDeactivation( int allow ) override;
+ virtual int allowDeactivation() override;
+
+public:
+ virtual int isVirtual() override
+ {
+ return !bypassvirtual;
+ }
+
+protected:
+ int virtualX, virtualY, virtualH, virtualW;
+ int bypassvirtual;
+ int focus;
+ int resizecount;
+ double lastratio;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndapi.cpp b/Src/Wasabi/api/wnd/wndapi.cpp
new file mode 100644
index 00000000..25de4d94
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndapi.cpp
@@ -0,0 +1,384 @@
+#include <precomp.h>
+#include <api.h>
+#include "wndapi.h"
+#include <api/wnd/api_window.h>
+#include <tataki/canvas/ifc_canvas.h>
+
+#include <api/wnd/deactivatemgr.h>
+#include <api/wnd/wndtrack.h>
+
+#include <api/syscb/callbacks/consolecb.h>
+#include <api/wnd/keyboard.h>
+
+#ifdef WASABI_COMPILE_SKIN
+// #include <api/skin/groupmgr.h>
+#endif
+
+#ifdef WASABI_COMPILE_PAINTSETS
+#ifdef WASABI_COMPILE_IMGLDR
+ #include <api/wnd/paintset.h>
+#endif
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+//#include <api/skin/skin.h>
+#endif
+#include <bfc/stack.h>
+#include <tataki/region/region.h>
+wnd_api *wndApi = NULL;
+
+#ifndef ODS
+#define ODS(msg1, msg2) __ODS(__LINE__, msg1, msg2, 0);
+#endif
+
+static Stack<ifc_window*> modal_wnd_stack;
+
+static void __ODS(int line, wchar_t *message1, wchar_t *message2, int severity) {
+ StringPrintfW s(L"wndApi(%d): %s: %s\n", line, message1, message2);
+#ifdef WIN32
+ DebugStringW(L"%s\n", s);
+#endif
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::CONSOLE, ConsoleCallback::DEBUGMESSAGE, severity, reinterpret_cast<intptr_t>(s.getValue()));
+}
+
+WndApi::WndApi()
+{
+}
+
+WndApi::~WndApi()
+{
+
+}
+
+void WndApi::main_setRootWnd(ifc_window *w) {
+ genericwnd = w;
+}
+
+ifc_window *WndApi::main_getRootWnd() {
+ return genericwnd;
+}
+
+ifc_window *WndApi::getModalWnd() {
+ if (!modal_wnd_stack.peek()) return NULL;
+ return modal_wnd_stack.top();
+}
+
+void WndApi::pushModalWnd(ifc_window *w) {
+ modal_wnd_stack.push(w);
+}
+
+void WndApi::popModalWnd(ifc_window *w) {
+ if (getModalWnd() != w) return;
+ modal_wnd_stack.pop();
+}
+/* TODO: Benski> move to api_wndmgr */
+ifc_window *WndApi::rootWndFromPoint(POINT *pt) {
+ return WindowTracker::rootWndFromPoint(pt);
+}
+
+ifc_window *WndApi::rootWndFromOSHandle(OSWINDOWHANDLE wnd) {
+ return WindowTracker::rootWndFromHwnd(wnd);
+}
+
+void WndApi::registerRootWnd(ifc_window *wnd) {
+ WindowTracker::addRootWnd(wnd);
+}
+
+void WndApi::unregisterRootWnd(ifc_window *wnd) {
+ WindowTracker::removeRootWnd(wnd);
+}
+/* --- end TO MOVE ---*/
+
+int WndApi::rootwndIsValid(ifc_window *wnd) {
+ return windowTracker->checkWindow(wnd);
+}
+void WndApi::hookKeyboard(ifc_window *hooker) {
+ Keyboard::hookKeyboard(hooker);
+}
+
+void WndApi::unhookKeyboard(ifc_window *hooker) {
+ Keyboard::unhookKeyboard(hooker);
+}
+
+void WndApi::kbdReset() {
+ Keyboard::reset();
+}
+
+// so when a key is pressed in a basewnd, it is first intercepted and sent to these functions to check if the system should handle it instead of the wnd...
+
+int WndApi::interceptOnChar(unsigned int c) {
+ return Keyboard::interceptOnChar(c);
+}
+
+int WndApi::interceptOnKeyDown(int k) {
+ return Keyboard::interceptOnKeyDown(k);
+}
+
+int WndApi::interceptOnKeyUp(int k) {
+ return Keyboard::interceptOnKeyUp(k);
+}
+
+int WndApi::interceptOnSysKeyDown(int k, int kd) {
+ return Keyboard::interceptOnSysKeyDown(k, kd);
+}
+
+int WndApi::interceptOnSysKeyUp(int k, int kd) {
+ return Keyboard::interceptOnSysKeyUp(k, kd);
+}
+
+// ... if not, then it is sent to the wnd, and if the wnd doesn't need it, it is then forwarded to the system again, for default handling :
+
+int WndApi::forwardOnChar(ifc_window *from, unsigned int c, int kd) {
+ return Keyboard::onForwardOnChar(from, c, kd);
+}
+
+int WndApi::forwardOnKeyDown(ifc_window *from, int k, int kd) {
+ return Keyboard::onForwardOnKeyDown(from, k, kd);
+}
+
+int WndApi::forwardOnKeyUp(ifc_window *from, int k, int kd) {
+ return Keyboard::onForwardOnKeyUp(from, k, kd);
+}
+
+int WndApi::forwardOnSysKeyDown(ifc_window *from, int k, int kd) {
+ return Keyboard::onForwardOnSysKeyDown(from, k, kd);
+}
+
+int WndApi::forwardOnSysKeyUp(ifc_window *from, int k, int kd) {
+ return Keyboard::onForwardOnSysKeyUp(from, k, kd);
+}
+
+int WndApi::forwardOnKillFocus() {
+ return Keyboard::onForwardOnKillFocus();
+}
+
+void WndApi::popupexit_register(PopupExitCallback *cb, ifc_window *watched)
+{
+ popupExitChecker.registerCallback(cb, watched);
+}
+void WndApi::popupexit_deregister(PopupExitCallback *cb)
+{
+ popupExitChecker.deregisterCallback(cb);
+}
+
+int WndApi::popupexit_check(ifc_window *w) {
+
+ return popupExitChecker.check(w);
+}
+
+void WndApi::popupexit_signal()
+{
+ popupExitChecker.signal();
+}
+
+#define RenderBaseTexture renderBaseTexture //CUT
+void WndApi::skin_renderBaseTexture(ifc_window *basetexturewnd, ifc_canvas *c, const RECT *r, ifc_window *destwnd, int alpha) {
+ if (c == NULL) {
+ ODS(L"illegal param", L"c == NULL");
+ return;
+ }
+ if (basetexturewnd == NULL) {
+ ODS(L"illegal param", L"base == NULL");
+ BaseCloneCanvas canvas(c);
+ canvas.fillRect(r, 0xFF00FF);
+ return;
+ }
+ if (destwnd == NULL) {
+ ODS(L"illegal param", L"destwnd == NULL");
+ return;
+ }
+ renderBaseTexture(basetexturewnd, c, *r, destwnd, alpha);
+}
+
+void WndApi::skin_registerBaseTextureWindow(ifc_window *window, const wchar_t *bitmap) {
+ if (window == NULL) {
+ ODS(L"illegal param", L"window == NULL");
+ return;
+ }
+ BaseTexture *s = new BaseTexture(window, bitmap);
+ baseTextureList.addItem(s);
+}
+
+void WndApi::skin_unregisterBaseTextureWindow(ifc_window *window) {
+ if (window == NULL) {
+ ODS(L"illegal param", L"window == NULL");
+ return;
+ }
+ for (int i=0;i<baseTextureList.getNumItems();i++) {
+ if (baseTextureList.enumItem(i)->getWnd() == window) {
+ BaseTexture *s = baseTextureList.enumItem(i);
+ baseTextureList.delByPos(i);
+ delete s;
+ if (baseTextureList.getNumItems() == 0)
+ baseTextureList.removeAll();
+ break;
+ }
+ }
+}
+
+void WndApi::appdeactivation_push_disallow(ifc_window *from_whom) {
+ AppDeactivationMgr::push_disallow(from_whom);
+}
+
+void WndApi::appdeactivation_pop_disallow(ifc_window *from_whom) {
+ AppDeactivationMgr::pop_disallow(from_whom);
+}
+
+int WndApi::appdeactivation_isallowed(ifc_window *w) {
+ return AppDeactivationMgr::is_deactivation_allowed(w);
+}
+
+void WndApi::appdeactivation_setbypass(int i) {
+ AppDeactivationMgr::setbypass(i);
+}
+
+#ifdef WASABI_COMPILE_PAINTSETS
+#ifdef WASABI_COMPILE_IMGLDR
+
+void WndApi::paintset_render(int set, ifc_canvas *c, const RECT *r, int alpha) {
+ if (c == NULL) {
+ ODS(L"illegal param", L"c == NULL");
+ return;
+ }
+ if (r == NULL) {
+ ODS(L"illegal param", L"r == NULL");
+ return;
+ }
+ paintset_renderPaintSet(set, c, r, alpha);
+}
+
+#ifdef WASABI_COMPILE_FONTS
+void WndApi::paintset_renderTitle(const wchar_t *t, ifc_canvas *c, const RECT *r, int alpha) {
+ if (c == NULL) {
+ ODS(L"illegal param", L"c == NULL");
+ return;
+ }
+ if (r == NULL) {
+ ODS(L"illegal param", L"r == NULL");
+ return;
+ }
+ ::paintset_renderTitle(t, c, r, alpha);
+}
+#endif // WASABI_COMPILE_FONTS
+#endif // WASABI_COMPILE_IMGLDR
+#endif // WASABI_COMPILE_PAINTSETS
+
+BaseTexture *WndApi::getBaseTexture(ifc_window *b) {
+ if (b == NULL) return NULL;
+ for (int i=0;i<baseTextureList.getNumItems();i++)
+ if (baseTextureList.enumItem(i)->getWnd() == b)
+ return baseTextureList.enumItem(i);
+ return NULL;
+}
+
+void WndApi::renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) {
+ renderBaseTexture(base, getBaseTexture(base), c, r, dest, alpha);
+}
+
+void WndApi::renderBaseTexture(ifc_window *base, BaseTexture *bt, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha) {
+ if (!bt) {
+ DebugString("Warning, no base texture found in renderBaseTexture\n");
+ return;
+ }
+
+ bt->renderBaseTexture(base, c, r, dest, alpha);
+}
+
+#ifndef SAFEROUND
+#define SAFEROUND(d) ((float)(int)d == d) ? (int)d : (d - (float)(int)d > 0) ? ((int)d)+1 : ((int)d)-1
+#endif
+
+void BaseTexture::renderBaseTexture(ifc_window *wndbase, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha)
+{
+ // pick our basetexture
+ AutoSkinBitmap *b = &texture;
+
+ if(!b) return;
+
+ // srcRect is the source rectangle in the basetexture
+ RECT srcRect;
+ // destProjectedRect is the basetexture rectangle projected to dest coordinates
+ RECT destProjectedRect;
+
+ ifc_window *p = dest;
+ POINT pt;
+ int sx=0, sy=0;
+ while (p && p != wndbase) {
+ if (!p->isVirtual()) {
+ p->getPosition(&pt);
+ sx += pt.x;
+ sy += pt.y;
+ }
+ p = p->getParent();
+ }
+ ASSERT(p);
+
+ wndbase->getNonClientRect(&destProjectedRect);
+ Wasabi::Std::offsetRect(&destProjectedRect, -sx, -sy);
+
+ Wasabi::Std::setRect(&srcRect, 0, 0, b->getWidth(), b->getHeight());
+
+#if 0
+ // NONPORTABLE
+ HDC hdc=c->getHDC();
+ HRGN oldRgn=CreateRectRgn(0,0,0,0);
+ HRGN newRgn=CreateRectRgnIndirect(&r);
+
+ int cs=GetClipRgn(hdc,oldRgn);
+
+ ExtSelectClipRgn(hdc,newRgn,(cs!=1)?RGN_COPY:RGN_AND);
+#endif
+#ifdef _WIN32
+ // TODO: review: wtf does this even accomplish? we're still blitting to c at the end
+ BaseCloneCanvas clone(c);
+ RegionI oldRgn;
+ RegionI newRgn(&r);
+
+ int cs = clone.getClipRgn(&oldRgn);
+
+ if ( cs ) newRgn.andRegion(&oldRgn);
+
+ clone.selectClipRgn( &newRgn );
+#endif
+ b->stretchToRectAlpha(c, &srcRect, &destProjectedRect, alpha);
+
+#ifdef _WIN32
+ // TODO: review: wtf does this even accomplish? we're still blitting to c at the end
+ clone.selectClipRgn(cs ? &oldRgn : NULL);
+#endif
+}
+
+int WndApi::forwardOnMouseWheel(int l, int a) {
+ return 0;
+}
+
+#ifdef WASABI_COMPILE_PAINTSETS
+int WndApi::paintset_present(int set) {
+ return ::paintset_present(set);
+}
+#endif
+
+void WndApi::setDefaultDropTarget(void *dt) {
+ default_drop_target = dt;
+}
+
+void *WndApi::getDefaultDropTarget() {
+ return default_drop_target;
+}
+
+int WndApi::pushKeyboardLock() {
+ return ++kbdlock;
+}
+
+int WndApi::popKeyboardLock() {
+ return --kbdlock;
+}
+
+int WndApi::isKeyboardLocked() {
+ return kbdlock;
+}
+
+ifc_window *WndApi::genericwnd = NULL;
+PtrList<BaseTexture> WndApi::baseTextureList;
+void *WndApi::default_drop_target = NULL;
+int WndApi::kbdlock = 0;
diff --git a/Src/Wasabi/api/wnd/wndapi.h b/Src/Wasabi/api/wnd/wndapi.h
new file mode 100644
index 00000000..21e5a748
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndapi.h
@@ -0,0 +1,101 @@
+#ifndef _WNDAPI_H
+#define _WNDAPI_H
+
+#include <api/wnd/api_wnd.h>
+#include <bfc/ptrlist.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <api/wnd/popexitchecker.h>
+// ---
+
+class BaseTexture
+{
+ public:
+ BaseTexture(ifc_window *_wnd, const wchar_t *_bmp) : wnd(_wnd), texture(_bmp) {}
+ virtual ~BaseTexture() {}
+
+ SkinBitmap *getTexture() { return texture.getBitmap(); }
+ ifc_window *getWnd() { return wnd; }
+
+ virtual void renderBaseTexture(ifc_window *wndbase, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha);
+
+ private:
+ ifc_window *wnd;
+ AutoSkinBitmap texture;
+};
+
+// ---
+
+class WndApi : public wnd_apiI
+{
+ public:
+
+ WndApi();
+ virtual ~WndApi();
+
+ virtual ifc_window *main_getRootWnd();
+ virtual void main_setRootWnd(ifc_window *w);
+ virtual ifc_window *getModalWnd();
+ virtual void pushModalWnd(ifc_window *w=MODALWND_NOWND);
+ virtual void popModalWnd(ifc_window *w=MODALWND_NOWND);
+ virtual ifc_window *rootWndFromPoint(POINT *pt);
+ virtual ifc_window *rootWndFromOSHandle(OSWINDOWHANDLE wnd);
+ virtual void registerRootWnd(ifc_window *wnd);
+ virtual void unregisterRootWnd(ifc_window *wnd);
+ virtual int rootwndIsValid(ifc_window *wnd);
+ virtual void hookKeyboard(ifc_window *hooker);
+ virtual void unhookKeyboard(ifc_window *hooker);
+ virtual void kbdReset();
+ virtual int interceptOnChar(unsigned int c);
+ virtual int interceptOnKeyDown(int k);
+ virtual int interceptOnKeyUp(int k);
+ virtual int interceptOnSysKeyDown(int k, int kd);
+ virtual int interceptOnSysKeyUp(int k, int kd);
+ virtual int forwardOnChar(ifc_window *from, unsigned int c, int kd);
+ virtual int forwardOnKeyDown(ifc_window *from, int k, int kd);
+ virtual int forwardOnKeyUp(ifc_window *from, int k, int kd);
+ virtual int forwardOnSysKeyDown(ifc_window *from, int k, int kd);
+ virtual int forwardOnSysKeyUp(ifc_window *from, int k, int kd);
+ virtual int forwardOnKillFocus();
+ virtual void popupexit_deregister(PopupExitCallback *cb);
+ virtual void popupexit_register(PopupExitCallback *cb, ifc_window *watched);
+ virtual int popupexit_check(ifc_window *w);
+ virtual void popupexit_signal();
+ virtual void skin_renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT *r, ifc_window *destWnd, int alpha=255);
+ virtual void skin_registerBaseTextureWindow(ifc_window *window, const wchar_t *bmp=NULL);
+ virtual void skin_unregisterBaseTextureWindow(ifc_window *window);
+ virtual void appdeactivation_push_disallow(ifc_window *w);
+ virtual void appdeactivation_pop_disallow(ifc_window *w);
+ virtual int appdeactivation_isallowed(ifc_window *w);
+ virtual void appdeactivation_setbypass(int i);
+#ifdef WASABI_COMPILE_PAINTSETS
+ virtual int paintset_present(int set);
+#ifdef WASABI_COMPILE_IMGLDR
+ virtual void paintset_render(int set, ifc_canvas *c, const RECT *r, int alpha=255);
+#ifdef WASABI_COMPILE_FONTS
+ virtual void paintset_renderTitle(const wchar_t *t, ifc_canvas *c, const RECT *r, int alpha=255);
+#endif // fonts
+#endif // imgldr
+#endif // paintsets
+ virtual int forwardOnMouseWheel(int l, int a);
+ virtual void setDefaultDropTarget(void *dt);
+ virtual void *getDefaultDropTarget();
+ static int getNumBaseTextures() { return baseTextureList.getNumItems(); }
+ virtual int pushKeyboardLock();
+ virtual int popKeyboardLock();
+ virtual int isKeyboardLocked();
+
+ PopupExitChecker popupExitChecker;
+ private:
+
+ static BaseTexture *getBaseTexture(ifc_window *b);
+ static void renderBaseTexture(ifc_window *base, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha);
+ static void renderBaseTexture(ifc_window *base, BaseTexture *s, ifc_canvas *c, const RECT &r, ifc_window *dest, int alpha);
+ static PtrList<BaseTexture> baseTextureList;
+ static ifc_window *genericwnd;
+ static void *default_drop_target;
+ static int kbdlock;
+};
+
+extern WndApi _wndApi;
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/SelItemList.cpp b/Src/Wasabi/api/wnd/wndclass/SelItemList.cpp
new file mode 100644
index 00000000..07f5edd9
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/SelItemList.cpp
@@ -0,0 +1,72 @@
+#include <precomp.h>
+#include "SelItemList.h"
+#include "listwnd.h"
+
+#define SELITEMEXPAND 2040
+
+SelItemList::SelItemList(ListWnd *parent) :
+listwnd(parent), list(SELITEMEXPAND), num_selected(0) { }
+
+void SelItemList::setSelected(int pos, int selected, int cb)
+{
+ int s = list.getSize();
+ if (pos >= s)
+ {
+ if (!selected)
+ {
+ // turning off something that's out of range is a no-brainer
+ return ;
+ }
+ s = ((s / SELITEMEXPAND) + 1) * SELITEMEXPAND;
+ list.setSize(s);
+ }
+
+ char *l = list.getMemory();
+ if (selected)
+ {
+ // quick and dirty way to prevent more than one item from
+ // ever being selected?
+ if (listwnd->getPreventMultipleSelection())
+ {
+ listwnd->deselectAll(cb);
+ }
+ if (!isSelected(pos))
+ {
+ l[pos] = 1;
+ num_selected++;
+ if (cb) listwnd->itemSelection(pos, TRUE);
+ listwnd->invalidateItem(pos);
+ }
+ }
+ else
+ {
+ if (isSelected(pos))
+ {
+ l[pos] = 0;
+ num_selected--;
+ if (cb) listwnd->itemSelection(pos, FALSE);
+ listwnd->invalidateItem(pos);
+ }
+ }
+}
+int SelItemList::isSelected(int pos)
+{
+ if (pos >= list.getSize()) return 0;
+ return list.getMemory()[pos];
+}
+int SelItemList::getNumSelected() { return num_selected; }
+
+void SelItemList::deleteByPos(int pos)
+{
+ ASSERT(pos >= 0);
+ int s = list.getSize();
+ if (pos >= s) return ;
+ num_selected -= isSelected(pos);
+ char *m = list.getMemory() + pos;
+ MEMCPY(m, m + 1, s - (pos + 1));
+}
+void SelItemList::deselectAll()
+{ // for internal use, doesn't send callbacks
+ list.zeroMemory();
+ num_selected = 0;
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/SelItemList.h b/Src/Wasabi/api/wnd/wndclass/SelItemList.h
new file mode 100644
index 00000000..f17a1511
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/SelItemList.h
@@ -0,0 +1,31 @@
+#ifndef NULLSOFT_SELITEMLISTH
+#define NULLSOFT_SELITEMLISTH
+
+class ListWnd;
+
+#define SELITEMEXPAND 2040
+
+//note to whoever redid this as a bitlist
+// a) this is pointlessly slow as a bitlist given the memory used
+// b) perhaps you should investigate bitlist.h
+class SelItemList
+{
+public:
+ SelItemList(ListWnd *parent);
+
+ void setSelected(int pos, int selected, int cb=1);
+ int isSelected(int pos);
+ int getNumSelected();
+
+ void deleteByPos(int pos);
+protected:
+friend ListWnd;
+ void deselectAll();
+
+private:
+ ListWnd *listwnd;
+ MemBlock<char> list;
+ int num_selected;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/abstractwndhold.cpp b/Src/Wasabi/api/wnd/wndclass/abstractwndhold.cpp
new file mode 100644
index 00000000..95af35a8
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/abstractwndhold.cpp
@@ -0,0 +1,287 @@
+#include "precomp.h"
+#include <api/syscb/api_syscb.h>
+
+#include "abstractwndhold.h"
+#include <api/service/svc_enum.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/service/svcs/svc_wndcreate.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_guiobject.h>
+#include <api/script/objects/c_script/c_group.h>
+#include <api/wnd/notifmsg.h>
+
+
+#define CB_ABSTRACTLOAD 0x1125
+
+AbstractWndHolder::AbstractWndHolder(const wchar_t *grpid, int autoresize) : ServiceWndHolder(NULL, NULL)
+{
+ scripts_enabled = 1;
+ groupid = grpid;
+ group_item = NULL;
+ guid = INVALID_GUID;
+ group = NULL;
+ cbreg = 0;
+ inselfresize = 0;
+ autoresizefromcontent = autoresize;
+ allow_deferred_content = 0;
+ need_deferred_load = 0;
+}
+
+AbstractWndHolder::AbstractWndHolder(SkinItem *groupitem, int autoresize) : ServiceWndHolder(NULL, NULL) {
+ group_item = groupitem;
+ guid = INVALID_GUID;
+ group = NULL;
+ cbreg = 0;
+ inselfresize = 0;
+ autoresizefromcontent = autoresize;
+ allow_deferred_content = 0;
+ need_deferred_load = 0;
+}
+
+AbstractWndHolder::AbstractWndHolder(GUID g, int autoresize) : ServiceWndHolder(NULL, NULL) {
+ guid = g;
+ group = NULL;
+ cbreg = 0;
+ group_item = NULL;
+ inselfresize = 0;
+ autoresizefromcontent = autoresize;
+ allow_deferred_content = 0;
+ need_deferred_load = 0;
+}
+
+AbstractWndHolder::~AbstractWndHolder() {
+ if (group) {
+#ifdef WASABI_COMPILE_SKIN
+ WASABI_API_SKIN->group_destroy(group);
+#endif
+ group = NULL;
+ }
+ if (cbreg) WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int AbstractWndHolder::onInit() {
+ ABSTRACTWNDHOLDER_PARENT::onInit();
+ createChild();
+ return 1;
+}
+
+ifc_window *AbstractWndHolder::rootwndholder_getRootWnd() {
+ if (group != NULL) return group;
+ return ABSTRACTWNDHOLDER_PARENT::rootwndholder_getRootWnd();
+}
+
+void AbstractWndHolder::abstract_setContent(const wchar_t *group_id, int autoresize)
+{
+ setBothContent(group_id, INVALID_GUID, autoresize);
+}
+
+void AbstractWndHolder::abstract_setContentBySkinItem(SkinItem *item, int autoresize) {
+ setContentSkinItem(item, autoresize);
+}
+
+void AbstractWndHolder::abstract_setContent(GUID g, int autoresize) {
+ setBothContent(NULL, g, autoresize);
+}
+
+void AbstractWndHolder::setBothContent(const wchar_t *group_id, GUID g, int autoresize)
+{
+ group_item = NULL;
+ if (autoresize != -1)
+ autoresizefromcontent = autoresize;
+ if (WCSCASEEQLSAFE(groupid, group_id) || (guid != INVALID_GUID && guid == g)) return;
+ GUID _g = nsGUID::fromCharW(group_id);
+ if (g == INVALID_GUID && _g != INVALID_GUID) {
+ groupid = NULL;
+ guid = _g;
+ } else {
+ groupid = group_id;
+ guid = g;
+ }
+ createChild();
+}
+
+void AbstractWndHolder::setContentSkinItem(SkinItem *item, int autoresize)
+{
+ if (autoresize != -1)
+ autoresizefromcontent = autoresize;
+ groupid.trunc(0);
+ guid = INVALID_GUID;
+ group_item = item;
+ createChild();
+}
+
+int AbstractWndHolder::onGroupChange(const wchar_t *grpid)
+{
+ if (WCSCASEEQLSAFE(groupid, grpid))
+ {
+ createChild();
+ notifyParent(ChildNotify::GROUPRELOAD);
+ notifyParent(ChildNotify::AUTOWHCHANGED);
+ }
+ return 1;
+}
+
+void AbstractWndHolder::createChild() {
+ if (!isInited()) return;
+ destroyContent();
+ if (allow_deferred_content && !isVisible())
+ need_deferred_load = 1;
+ else
+ doLoadContent();
+}
+
+void AbstractWndHolder::destroyContent()
+{
+ if (group != NULL) {
+#ifdef WASABI_COMPILE_SKIN
+ WASABI_API_SKIN->group_destroy(group);
+#endif
+ if (cbreg) {
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+ cbreg=0;
+ }
+ ABSTRACTWNDHOLDER_PARENT::setChild(NULL, NULL);
+ }
+ group = NULL;
+}
+
+int AbstractWndHolder::onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ if (p1 == CB_ABSTRACTLOAD) {
+ doLoadContent();
+ return 1;
+ }
+ return ABSTRACTWNDHOLDER_PARENT::onDeferredCallback(p1, p2);
+}
+
+#include <bfc/util/profiler.h>
+
+void AbstractWndHolder::doLoadContent() {
+ int didsomething = 0;
+ need_deferred_load = 0;
+ if (group_item != NULL) {
+#ifdef WASABI_COMPILE_SKIN
+ group = WASABI_API_SKIN->group_createBySkinItem(group_item, scripts_enabled);
+#endif
+ if (group) {
+ if (!cbreg) {
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+ cbreg=1;
+ }
+ group->setParent(this);
+ group->init(this);
+ abstract_onNewContent();
+ didsomething = 1;
+ }
+ } else if (!groupid.isempty()) {
+#ifdef WASABI_COMPILE_SKIN
+ group = WASABI_API_SKIN->group_create(groupid, scripts_enabled);
+#endif
+ if (group) {
+ if (!cbreg) {
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+ cbreg=1;
+ }
+ group->setParent(this);
+ group->init(this);
+ abstract_onNewContent();
+ didsomething = 1;
+ }
+ } else if (guid != INVALID_GUID) {
+ svc_windowCreate *svc = WindowCreateByGuidEnum(guid).getNext();
+ ABSTRACTWNDHOLDER_PARENT::setChild(svc->createWindowByGuid(guid, this), svc);
+ abstract_onNewContent();
+ didsomething = 1;
+ }
+ if (didsomething && isPostOnInit())
+ {
+ onResize();
+ }
+}
+
+void AbstractWndHolder::abstract_onNewContent()
+{
+ if (isPostOnInit()) {
+ ifc_window *w = getDesktopParent();
+ if (w != NULL) {
+ if (w->enumMinMaxEnforcer(0)) {
+ w->signalMinMaxEnforcerChanged();
+ }
+ }
+ }
+}
+
+GuiObject *AbstractWndHolder::abstract_findObject(const wchar_t *object_id)
+{
+ ifc_window *w = rootwndholder_getRootWnd();
+ if (w == NULL) return NULL;
+ GuiObject *o = static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
+ return o->guiobject_findObject(object_id);
+}
+
+ScriptObject *AbstractWndHolder::abstract_findScriptObject(const wchar_t *object_id)
+{
+ ifc_window *w = rootwndholder_getRootWnd();
+ if (w == NULL) return NULL;
+ GuiObject *o = static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
+ GuiObject *fo = o->guiobject_findObject(object_id);
+ if (fo != NULL) return fo->guiobject_getScriptObject();
+ return NULL;
+}
+
+
+GuiObject *AbstractWndHolder::abstract_getContent() {
+ ifc_window *w = rootwndholder_getRootWnd();
+ if (w == NULL) return NULL;
+ return static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
+}
+
+ScriptObject *AbstractWndHolder::abstract_getContentScriptObject() {
+ ifc_window *w = rootwndholder_getRootWnd();
+ if (w == NULL) return NULL;
+ return static_cast<ScriptObject *>(w->getInterface(scriptObjectGuid));
+}
+
+int AbstractWndHolder::onResize() {
+ int rt = ABSTRACTWNDHOLDER_PARENT::onResize();
+ if (group != NULL && abstract_wantAutoResizeFromContent()) {
+ if (inselfresize) return rt;
+ inselfresize=1;
+ int w = group->getPreferences(SUGGESTED_W);
+ int h = group->getPreferences(SUGGESTED_H);
+ resize(NOCHANGE, NOCHANGE, w == AUTOWH ? NOCHANGE : w, h == AUTOWH ? NOCHANGE : h);
+ inselfresize = 0;
+ }
+ return rt;
+}
+
+void AbstractWndHolder::onSetVisible( int show )
+{
+ ABSTRACTWNDHOLDER_PARENT::onSetVisible( show );
+ if ( allow_deferred_content )
+ {
+ if ( show & need_deferred_load )
+ {
+ doLoadContent();
+ }
+ if ( !show && !need_deferred_load )
+ {
+ destroyContent();
+ need_deferred_load = 1;
+ }
+ }
+}
+
+void AbstractWndHolder::abstract_setScriptsEnabled(int en)
+{
+ if (scripts_enabled == en) return;
+ scripts_enabled = en;
+ if (group != NULL) {
+ destroyContent();
+ doLoadContent();
+ }
+}
+
+int AbstractWndHolder::abstact_getScriptsEnabled() {
+ return scripts_enabled;
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/abstractwndhold.h b/Src/Wasabi/api/wnd/wndclass/abstractwndhold.h
new file mode 100644
index 00000000..c81ad683
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/abstractwndhold.h
@@ -0,0 +1,267 @@
+#ifndef __ABSTRACTWNDHOLD_H
+#define __ABSTRACTWNDHOLD_H
+
+#include <api/wnd/wndclass/svcwndhold.h>
+#include <api/syscb/callbacks/wndcb.h>
+
+class GuiObject;
+class ScriptObject;
+class SkinItem;
+
+#define ABSTRACTWNDHOLDER_PARENT ServiceWndHolder
+
+
+/**
+ The AbstractWndHolder enables you to display deferred content. This means
+ the content does not actually need to exist at creation. It will be automatically
+ loaded when it is found.
+
+ This class is meant to be derived from. You shouldn't create an AbstractWndHolder
+ directly to implement this kind of functionality. Please use GuiObjectWnd along
+ with the setContent() method.
+
+ @short An abstracted window holder with deferred content loading.
+ @author Nullsoft
+ @ver 1.0
+ @see GuiObjectWnd
+*/
+class AbstractWndHolder : public ABSTRACTWNDHOLDER_PARENT, public WndCallbackI {
+
+ protected:
+
+ // don't create me directly, create a GuiObjectWnd and setContent("group.id") on it
+ // these are for inheriting and have a deferred content (so if you _were_ using that,
+ // your findObjects would fail right after init and before abstract_onNewContent)
+
+ /**
+ Sets the group id of the content and the auto resize flag.
+
+ Setting the auto resize flag to 1 will enable the automatic resize of
+ the window according to the size of the content attempting to be
+ displayed.
+
+ @param groupid The content group.
+ @param _autoresizefromcontent 0, disable auto resize; 1, enable auto resize;
+ */
+ AbstractWndHolder(const wchar_t *groupid=NULL, int _autoresizefromcontent=0);
+ AbstractWndHolder(SkinItem *groupitem, int _autoresizefromcontent=0);
+
+ /**
+ Finds the group with the matching GUID and uses that group as the content.
+ This insures you get the exact group and not a replacement.
+
+ Setting the auto resize flag to 1 will enable the automatic resize of
+ the window according to the size of the content attempting to be
+ displayed.
+
+ @param _guid The GUID the content group.
+ @param _autoresizefromcontent 0, disable auto resize; 1, enable auto resize;
+ */
+ AbstractWndHolder(GUID _guid, int _autoresizefromcontent=0);
+
+ public:
+
+
+ /**
+ Destroys the instance of the group used for content automatically.
+ */
+ virtual ~AbstractWndHolder();
+
+
+ /**
+ Sets the content group using the group id.
+
+ @param groupid The content group id.
+ @param _autoresizefromcontent -1, no change; 0, disable auto resize; 1, enable auto resize;
+ */
+ virtual void abstract_setContent(const wchar_t *groupid, int _autoresizefromcontent=-1); // -1 = no change, 0 = false, 1 = true
+
+ /**
+ Sets the content group using the group's GUID.
+ This insures you get the exact group and not a replacement.
+
+ @param g The content group's GUID.
+ @param _autoresizefromcontent -1, no change; 0, disable auto resize; 1, enable auto resize;
+ */
+ virtual void abstract_setContent(GUID g, int _autoresizefromcontent=-1); // -1 = no change, 0 = false, 1 = true
+
+ virtual void abstract_setContentBySkinItem(SkinItem *groupitem, int _autoresizefromcontent=-1); // -1 = no change, 0 = false, 1 = true
+
+ /**
+ This event is triggered when the content is loaded or the content changes.
+ Override it to implement your own handling of this event.
+ */
+ virtual void abstract_onNewContent();
+
+ /**
+ This event is triggered when the content group is changed.
+ Override it to implement your own handling of this event.
+
+ @see abstract_setContant()
+ @ret 1, if you handle the event;
+ @param grpid The new group that was set.
+ */
+ virtual int onGroupChange(const wchar_t *grpid);
+
+ /**
+ This event is triggered when the visibility of the window changes.
+ Override it to implement your own handling of this event.
+
+ @see onGroupChange()
+ @param show 0, hide window; 1, show window;
+ */
+ virtual void onSetVisible(int show);
+
+
+ /**
+ This event is triggered when the window is being initialized.
+ Override it to implement your own handling of this event.
+
+ @ret 1, if you handle the event;
+ */
+ virtual int onInit();
+
+ /**
+ This event is triggered when the window is resized.
+ Override it to implement your own handling of this event.
+
+ @ret 1, if you handle the event;
+ */
+ virtual int onResize();
+
+
+ /**
+ Get the api_window.
+
+ @ret
+ */
+ ifc_window *rootwndholder_getRootWnd();
+
+ /**
+ Find an object in the content group. This is done via
+ the object's text id.
+
+ @see abstract_findScriptObject()
+ @ret !NULL, The requested object pointer; NULL, Failed to find object.
+ @param The id of the object to find.
+ */
+ virtual GuiObject *abstract_findObject(const wchar_t *object_id);
+
+ /**
+ Find a script object in the content group. This is done via the
+ script object's text id.
+
+ @see abstract_findObject()
+ @ret !NULL, The requested script object pointer; NULL, Failed to find the object.
+ @param The id of the script object to find.
+ // TODO: benski> currently unused. cut?
+ */
+ virtual ScriptObject *abstract_findScriptObject(const wchar_t *object_id);
+
+ /**
+ Get the content group.
+
+ @see abstract_getContentScriptObject()
+ @ret A pointer to the content group GuiObject.
+ */
+ virtual GuiObject *abstract_getContent();
+
+ /**
+ Get the content script object.
+
+ @see abstract_getContent()
+ @ret A pointer to the content ScriptObject.
+ */
+ virtual ScriptObject *abstract_getContentScriptObject();
+
+ /**
+ Get the ifc_window that is holding the content group.
+
+ @see rootwndholder_getRootWnd()
+ @ret A pointer to the ifc_window holding the content group.
+ */
+ virtual ifc_window *abstract_getContentRootWnd() { return group; }
+
+ /**
+ Read the auto-resize from content flag.
+
+ @see abstract_setAutoResizeFromContent()
+ @ret 0, disable auto resize; 1, enable auto resize;
+ @param
+ */
+ virtual int abstract_wantAutoResizeFromContent() { return autoresizefromcontent; }
+
+ /**
+ Set the auto-resize from content flag.
+
+ @see abstract_wantAutoResizeFromContent()
+ @param i 0, disable auto resize; 1, enable auto resize;
+ */
+ virtual void abstract_setAutoResizeFromContent(int i) { autoresizefromcontent = i; }
+
+ /**
+ Set the allow deferred content flag. Allowing deferred content enables content to be
+ loaded after the window is shown.
+
+ @param allow 0, Do not allow; 1, Allow
+ */
+ virtual void abstract_setAllowDeferredContent(int allow) { allow_deferred_content = allow; }
+
+
+ /**
+ The deferred callback.
+
+ @ret 1, If you handle the event.
+ @param p1
+ @param p2
+ */
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ virtual void setContentSkinItem(SkinItem *groupitem, int autoresize=-1);
+
+ virtual void abstract_setScriptsEnabled(int en);
+ virtual int abstact_getScriptsEnabled();
+
+ private:
+
+
+ /**
+ Creates the child content window when required.
+ */
+ void createChild();
+
+ /**
+ Set Both Content.
+
+ @param guid
+ @param g
+ @param _autoresizefromcontent
+ */
+ void setBothContent(const wchar_t *guid, GUID g, int _autoresizefromcontent);
+
+ /**
+ Loads the content from the previously specified group.
+
+ @see abstract_setContent()
+ */
+ void doLoadContent();
+
+ /**
+ Destroys the instantiated copy of the content group.
+ */
+ void destroyContent();
+
+ StringW groupid;
+ GUID guid;
+
+ ifc_window *group;
+ int cbreg;
+ int inselfresize;
+ int autoresizefromcontent;
+ int allow_deferred_content;
+ int need_deferred_load;
+ SkinItem *group_item;
+ int scripts_enabled = 0;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp b/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp
new file mode 100644
index 00000000..11629fc1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/appbarwnd.cpp
@@ -0,0 +1,1113 @@
+#include "precomp.h"
+#include "appbarwnd.h"
+#include <tataki/region/region.h>
+#include <api/wnd/resizable.h>
+#include <api/wndmgr/layout.h>
+#include <api/config/items/cfgitem.h>
+#include <api/config/items/attrint.h>
+#include "../../../../Plugins/General/gen_ff/wa2cfgitems.h"
+
+#define CB_CHECK 0x101
+#define DOCK_DISTANCE_X 5
+#define DOCK_DISTANCE_Y 5
+
+#ifndef WIN32
+#error port me or remove me from the inheritance on this platform !
+#endif
+
+#include <windows.h>
+#include <windowsx.h>
+#include <shlobj.h>
+#include "../../../../Plugins/General/gen_ff/main.h"
+#include "appbarwnd.h"
+
+extern _int cfg_options_appbardockingdistance;
+
+// -----------------------------------------------------------------------
+AppBarWnd::AppBarWnd() {
+ m_registered = 0;
+ m_side = APPBAR_NOTDOCKED;
+ m_enabled = 0;
+ m_cur_side = APPBAR_NOTDOCKED;
+ m_cur_autohide = 0;
+ m_cur_hiding = 0;
+ m_oldZOrder = NULL;
+ m_destroying = FALSE;
+ m_norestore = 0;
+ m_sliding = 0;
+ m_autounhide_timer_set = 0;
+ m_autohide_timer_set = 0;
+ m_suspended = 0;
+ m_fs = 0;
+ m_wahidden = 0;
+}
+
+// -----------------------------------------------------------------------
+AppBarWnd::~AppBarWnd() {
+ m_destroying = TRUE;
+ if (m_cur_side != APPBAR_NOTDOCKED) unDock();
+ unregisterWinAppBar();
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::registerWinAppBar()
+{
+ if (m_registered)
+ unregisterWinAppBar();
+
+ APPBARDATA abd;
+
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.hWnd = getOsWindowHandle();
+ abd.uCallbackMessage = APPBAR_CALLBACK;
+
+ m_registered = (int)SHAppBarMessage(ABM_NEW, &abd);
+ return m_registered;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::unregisterWinAppBar() {
+ if (m_registered) {
+ APPBARDATA abd;
+
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.hWnd = getOsWindowHandle();
+
+ SHAppBarMessage(ABM_REMOVE, &abd);
+ m_registered = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::appbar_dock(int side) {
+ m_side = side;
+ updateDocking();
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_isDocked() {
+ return m_side != APPBAR_NOTDOCKED;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_getSide() {
+ return m_side;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::appbar_setEnabledSides(int mask) {
+ m_enabled = mask;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_getEnabledSides() {
+ return m_enabled;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_isSideEnabled(int side) {
+ if (side == APPBAR_LEFT && !(m_enabled & APPBAR_LEFT_ENABLED)) return 0;
+ if (side == APPBAR_TOP && !(m_enabled & APPBAR_TOP_ENABLED)) return 0;
+ if (side == APPBAR_RIGHT && !(m_enabled & APPBAR_RIGHT_ENABLED)) return 0;
+ if (side == APPBAR_BOTTOM && !(m_enabled & APPBAR_BOTTOM_ENABLED)) return 0;
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_isSideAutoHideSafe(int side) {
+ OSWINDOWHANDLE cur = getCurAutoHide(side);
+
+ if (cur == NULL || cur == getOsWindowHandle()) {
+ RECT primary = {0};
+ Wasabi::Std::getViewport(&primary, hwnd, 1);
+
+ DebugStringW( L"primary screen coords = %d,%d -> %d,%d (%dx%d)\n", primary.left, primary.top, primary.right, primary.bottom, primary.right - primary.left, primary.bottom - primary.top );
+ int monitor = 0;
+ //int g = 0;
+ while (1) {
+ RECT r;
+ int ret = Wasabi::Std::enumViewports(monitor++, &r, 1);
+ if (ret == 0) break;
+
+ if (Wasabi::Std::rectEqual(&primary, &r)) continue;
+
+ DebugStringW(L"secondary screen = %d,%d -> %d,%d (%dx%d)\n", r.left, r.top, r.right, r.bottom, r.right-r.left, r.bottom-r.top);
+ if (r.right <= primary.left && side == APPBAR_LEFT) return 0;
+ if (r.bottom <= primary.top && side == APPBAR_TOP) return 0;
+ if (r.left >= primary.right && side == APPBAR_RIGHT) return 0;
+ if (r.top >= primary.bottom && side == APPBAR_BOTTOM) return 0;
+ }
+ }
+ else
+ return 0;
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+OSWINDOWHANDLE AppBarWnd::getCurAutoHide(int side) {
+ APPBARDATA abd;
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.hWnd = getOsWindowHandle();
+ abd.uEdge = side;
+ return (OSWINDOWHANDLE)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_testDock(int x, int y, RECT *dockrect) {
+ POINT ptCursor = {x, y};
+ LONG cxScreen, cyScreen;
+ int dx=999999, dy=999999;
+ int horiz=-1, vert=-1;
+ RECT viewRect = {0};
+
+ Wasabi::Std::getViewport(&viewRect, hwnd, 1);
+
+ // Find out which edge of the screen we're closest to
+ cxScreen = viewRect.right;
+ cyScreen = viewRect.bottom;
+
+ if (x < viewRect.left || x > cxScreen || y < viewRect.top || y > cyScreen) return APPBAR_NOTDOCKED;
+
+ if (ptCursor.x < (cxScreen / 2)) {
+ if (m_enabled & APPBAR_LEFT_ENABLED) {
+ dx = ptCursor.x;
+ horiz = APPBAR_LEFT;
+ }
+ }
+ else {
+ if (m_enabled & APPBAR_RIGHT_ENABLED) {
+ dx = cxScreen - ptCursor.x;
+ horiz = APPBAR_RIGHT;
+ }
+ }
+
+ if (ptCursor.y < (cyScreen / 2)) {
+ if (m_enabled & APPBAR_TOP_ENABLED) {
+ dy = ptCursor.y;
+ vert = APPBAR_TOP;
+ }
+ }
+ else {
+ if (m_enabled & APPBAR_BOTTOM_ENABLED) {
+ dy = cyScreen - ptCursor.y;
+ vert = APPBAR_BOTTOM;
+ }
+ }
+
+ int ret = -1;
+ #ifdef GEN_FF
+ int dockdist = cfg_options_appbardockingdistance;
+ #else
+ // TODO: do a config lookup, but make it not so slow
+ /*
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ int dockdist = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Appbars Docking Distance", 5);*/
+ int dockdist = 5;
+ #endif
+ if ((cxScreen * dy) > (cyScreen * dx))
+ if (dx <= dockdist)
+ ret = horiz;
+ if (dy <= dockdist)
+ ret = vert;
+
+ if (dockrect && ret != -1) {
+ getDockRect(ret, dockrect);
+ }
+
+ return ret;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::getDockRect(int side, RECT *rect) {
+ LONG cxScreen, cyScreen;
+ RECT viewRect = {0};
+ Wasabi::Std::getViewport(&viewRect, hwnd, 1);
+
+ cxScreen = viewRect.right;
+ cyScreen = viewRect.bottom;
+
+ if (isMaximized()) {
+ getRestoredRect(rect);
+ if (renderRatioActive()) multRatio(rect);
+ }
+ else getWindowRect(rect);
+
+ Layout *l = (Layout *)getInterface(layoutGuid);
+ if (l) {
+ RECT adj;
+ l->getSnapAdjust(&adj);
+ if (renderRatioActive()) {
+ multRatio((int *)&adj.left, (int *)&adj.top);
+ multRatio((int *)&adj.right, (int *)&adj.bottom);
+ }
+ int h = rect->bottom - rect->top;
+ int w = rect->right - rect->left;
+ h -= adj.top + adj.bottom;
+ w -= adj.left + adj.right;
+ rect->left += adj.left;
+ rect->top += adj.top;
+ rect->bottom = rect->top + h;
+ rect->right = rect->left + w;
+ }
+
+ switch (side) {
+ case APPBAR_TOP:
+ case APPBAR_LEFT:
+ OffsetRect(rect, -rect->left, -rect->top);
+ break;
+ case APPBAR_BOTTOM:
+ case APPBAR_RIGHT:
+ OffsetRect(rect, cxScreen-rect->right, cyScreen-rect->bottom);
+ break;
+ }
+
+ switch (side) {
+ case APPBAR_TOP:
+ case APPBAR_BOTTOM:
+ rect->left = viewRect.left;
+ rect->right = cxScreen;
+ break;
+ case APPBAR_LEFT:
+ case APPBAR_RIGHT:
+ rect->top = viewRect.top;
+ rect->bottom = cyScreen;
+ break;
+ }
+
+ OSWINDOWHANDLE cur = getCurAutoHide(side);
+ int safeah = appbar_isSideAutoHideSafe(side);
+
+ if (!safeah || !(appbar_wantAutoHide() && (!cur || cur == getOsWindowHandle()))) {
+ straightenRect(side, rect);
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::updateDocking() {
+ if (!isVisible()) {
+ m_suspended = 1;
+ return;
+ }
+ updateSide();
+ appbar_updateAutoHide();
+ appbar_updateAlwaysOnTop();
+ updateTimers();
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::updateTimers() {
+ if (m_cur_autohide) {
+ if (m_cur_hiding) {
+ resetAutoHideTimer();
+ setAutoUnHideTimer();
+ }
+ else {
+ resetAutoUnHideTimer();
+ setAutoHideTimer();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_updateAlwaysOnTop() {
+ if (m_side == APPBAR_NOTDOCKED) return 0;
+ SetWindowPos(getOsWindowHandle(), appbar_wantAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_updateAutoHide() {
+ int autohide = appbar_wantAutoHide();
+ if (m_cur_autohide == autohide) return 0;
+
+ if (autohide && !appbar_isSideAutoHideSafe(m_cur_side)) autohide = 0;
+
+ if (m_cur_autohide == autohide) return 0;
+
+ if (autohide) {
+ // cur_autohide is off, turn it on
+ m_cur_hiding = 0;
+ setAutoHideTimer();
+ }
+ else {
+ // cur_autohide is on, turn it off
+ if (m_cur_hiding) resetAutoUnHideTimer();
+ else resetAutoHideTimer();
+ }
+
+ m_cur_autohide = autohide;
+ dock(m_cur_side);
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::onAfterReinit() {
+ APPBARWND_PARENT::onAfterReinit();
+ m_autohide_timer_set = 0;
+ m_autounhide_timer_set = 0;
+ updateTimers();
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::setAutoHideTimer(){
+ if (!m_autohide_timer_set) {
+ SetTimer(getOsWindowHandle(), IDT_AUTOHIDE, cfg_uioptions_appbarshidetime, NULL);
+ m_autohide_timer_set = 1;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::setAutoUnHideTimer(){
+ if (!m_autounhide_timer_set) {
+ SetTimer(getOsWindowHandle(), IDT_AUTOUNHIDE, cfg_uioptions_appbarsshowtime, NULL);
+ m_autounhide_timer_set = 1;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::resetAutoHideTimer(){
+ if (m_autohide_timer_set) {
+ KillTimer(getOsWindowHandle(), IDT_AUTOHIDE);
+ m_autohide_timer_set = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::resetAutoUnHideTimer() {
+ if (m_autounhide_timer_set) {
+ KillTimer(getOsWindowHandle(), IDT_AUTOUNHIDE);
+ m_autounhide_timer_set = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::updateSide() {
+ if (m_cur_side == m_side) return;
+ if (m_side != m_cur_side && m_cur_side != APPBAR_NOTDOCKED && m_side != APPBAR_NOTDOCKED && m_cur_autohide) {
+ resetAutoHideSide(m_cur_side);
+ }
+ if (m_side == APPBAR_NOTDOCKED) unDock();
+ else dock(m_side);
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::resetAutoHideSide(int side) {
+ HWND cur = getCurAutoHide(side);
+ if (cur == getOsWindowHandle()) {
+ APPBARDATA abd;
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.hWnd = cur;
+ abd.uEdge = side;
+ abd.lParam = FALSE;
+ SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd);
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::setAutoHideSide(int side) {
+ APPBARDATA abd;
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.hWnd = getOsWindowHandle();
+ abd.uEdge = side;
+ abd.lParam = TRUE;
+ SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd);
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::dock(int side) {
+ unOwn();
+
+ if (!registerWinAppBar()) {
+ reOwn();
+ m_side = APPBAR_NOTDOCKED;
+ m_cur_side = APPBAR_NOTDOCKED;
+ m_cur_autohide = 0;
+ }
+
+ maximize(0);
+
+ RECT rect;
+ getDockRect(side, &rect);
+
+ {
+ RECT adj = rect;
+ if (ABS(getRenderRatio() - 1.0) > 0.01f) {
+ int _w = adj.right-adj.left;
+ int _h = adj.bottom-adj.top;
+ double rr = getRenderRatio();
+ _w = (int)((double)(_w) / rr + 0.5);
+ _h = (int)((double)(_h) / rr + 0.5);
+ adj.right = adj.left + _w;
+ adj.bottom = adj.top + _h;
+ }
+ snapAdjust(&adj, 1);
+ resizeToRect(&adj);
+ }
+
+ if (!appbar_wantAutoHide() || !appbar_isSideAutoHideSafe(side)) {
+ notifyWinAppBarPosition(side, rect);
+ }
+ else {
+ getEdge(side, &rect);
+ notifyWinAppBarPosition(side, rect);
+ setAutoHideSide(side);
+ m_cur_hiding = 0;
+ }
+
+ if (!m_suspended) appbar_onDock(side);
+
+ #ifdef WASABI_APPBAR_ONDOCKCHANGED
+ WASABI_APPBAR_ONDOCKCHANGED(this)
+ #endif
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::unDock() {
+ if (m_cur_side != APPBAR_NOTDOCKED) {
+
+ resetAutoHideSide(m_cur_side);
+ unregisterWinAppBar();
+
+ if (!m_destroying) {
+ reOwn();
+ if (!m_norestore) restore();
+ #ifdef WASABI_APPBAR_ONDOCKCHANGED
+ WASABI_APPBAR_ONDOCKCHANGED(this)
+ #endif
+ }
+
+ m_cur_side = APPBAR_NOTDOCKED;
+
+ if (!m_suspended) appbar_onUnDock();
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::notifyWinAppBarPosition(int side, RECT rect) {
+ APPBARDATA abd;
+
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.hWnd = getOsWindowHandle();
+ abd.rc = rect;
+ abd.uEdge = side;
+
+ SHAppBarMessage(ABM_SETPOS, &abd);
+ m_cur_side = side;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_isHiding() {
+ return m_cur_hiding;
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::appbar_isAutoHiding() {
+ return m_cur_autohide;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::appbar_posChanged() {
+ if (m_side == APPBAR_NOTDOCKED) return;
+ RECT wr;
+ getWindowRect(&wr);
+ int w = wr.right-wr.left;
+ int h = wr.bottom-wr.top;
+
+ if (m_cur_autohide && m_cur_side != APPBAR_NOTDOCKED && !appbar_isSideAutoHideSafe(m_cur_side))
+ m_cur_autohide = 0;
+
+ RECT rc;
+ getDockRect(m_cur_side, &rc);
+
+ if (!m_cur_autohide) {
+ {
+ RECT adj = rc;
+ if (ABS(getRenderRatio() - 1.0) > 0.01f) {
+ int _w = adj.right-adj.left;
+ int _h = adj.bottom-adj.top;
+ double rr = getRenderRatio();
+ _w = (int)((double)(_w) / rr + 0.5);
+ _h = (int)((double)(_h) / rr + 0.5);
+ adj.right = adj.left + _w;
+ adj.bottom = adj.top + _h;
+ }
+ snapAdjust(&adj, 1);
+ resizeToRect(&adj);
+ }
+ notifyWinAppBarPosition(m_cur_side, rc);
+ }
+ else {
+ int aaw = appbar_getAutoHideWidthHeight();
+ RECT er;
+ getEdge(m_cur_side, &er);
+ notifyWinAppBarPosition(m_cur_side, er);
+ RECT adj = {0,0,0,0};
+ Layout *l = (Layout *)getInterface(layoutGuid);
+ if (l) l->getSnapAdjust(&adj);
+ if (renderRatioActive()) multRatio(&adj);
+ if (m_cur_hiding) {
+ switch (m_cur_side) {
+ case APPBAR_TOP:
+ rc.bottom = er.top + aaw + adj.bottom;
+ rc.top = rc.bottom - h;
+ break;
+ case APPBAR_BOTTOM:
+ rc.top = er.bottom - aaw - adj.top;
+ rc.bottom = rc.top + h;
+ break;
+ case APPBAR_LEFT:
+ rc.right = er.left + aaw + adj.right;
+ rc.left = rc.right - w;
+ break;
+ case APPBAR_RIGHT:
+ rc.left = er.right - aaw - adj.left;
+ rc.right = rc.left + w;
+ break;
+ }
+ }
+ if (ABS(getRenderRatio() - 1.0) > 0.01f) {
+ int _w = rc.right-rc.left;
+ int _h = rc.bottom-rc.top;
+ double rr = getRenderRatio();
+ _w = (int)((double)(_w) / rr + 0.5);
+ _h = (int)((double)(_h) / rr + 0.5);
+ rc.right = rc.left + _w;
+ rc.bottom = rc.top + _h;
+ }
+ resizeToRect(&rc);
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::getEdge(int side, RECT *rc) {
+ ASSERT(rc != NULL);
+ Wasabi::Std::getViewport(rc, hwnd, 1);
+ switch (side) {
+ case APPBAR_TOP:
+ rc->bottom = rc->top; break;
+ case APPBAR_BOTTOM:
+ rc->top = rc->bottom; break;
+ case APPBAR_LEFT:
+ rc->right = rc->left; break;
+ case APPBAR_RIGHT:
+ rc->left = rc->right; break;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::appBarCallback(UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ APPBARDATA abd = {0};
+
+ if (m_registered) {
+ abd.cbSize = sizeof(abd);
+ abd.hWnd = getOsWindowHandle();
+
+ switch (wParam)
+ {
+ // the taskbar's autohide or always-on-top state has changed.
+ case ABN_STATECHANGE:
+ DebugString("AppBarCallback: ABN_STATECHANGE\n");
+ break;
+
+ // a full screen application is opening or closing. we must drop
+ // to the bottom of the Z-Order and restore it later.
+ case ABN_FULLSCREENAPP:
+ DebugString("AppBarCallback: ABN_FULLSCREENAPP\n");
+ if (lParam && !m_fs) {
+ m_fs=1;
+ m_oldZOrder = GetWindow(getOsWindowHandle(), GW_HWNDPREV);
+ SetWindowPos(getOsWindowHandle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ }
+ else if (!lParam && m_fs) {
+ m_fs = 0;
+ SetWindowPos(getOsWindowHandle(), appbar_wantAlwaysOnTop() ? HWND_TOPMOST : m_oldZOrder, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ m_oldZOrder = NULL;
+ }
+ break;
+
+ // something changed that may have modified the possible appbar's positions
+ case ABN_POSCHANGED:
+ DebugString("AppBarCallback: ABN_POSCHANGED\n");
+ appbar_posChanged();
+ break;
+
+ case ABN_WINDOWARRANGE:
+ if (lParam && !m_wahidden) {
+ m_wahidden = 1;
+ ShowWindow(getOsWindowHandle(), SW_HIDE);
+ }
+ else if (!lParam && m_wahidden) {
+ m_wahidden = 0;
+ ShowWindow(getOsWindowHandle(), SW_NORMAL);
+ }
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+LRESULT AppBarWnd::wndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+ if ( m_registered )
+ {
+ switch ( msg )
+ {
+ case WM_MOVE:
+ {
+ //DebugString("WM_MOVE\n");
+ return 0;
+ }
+ case WM_WINDOWPOSCHANGED:
+ {
+ //DebugString("WM_WINDOWPOSCHANGED\n");
+ //LPWINDOWPOS lpwpos = (LPWINDOWPOS)lparam;
+ APPBARDATA abd = { 0 };
+ abd.cbSize = sizeof( APPBARDATA );
+ abd.hWnd = getOsWindowHandle();
+
+ SHAppBarMessage( ABM_WINDOWPOSCHANGED, &abd );
+ }
+ case APPBAR_CALLBACK:
+ {
+ if ( !m_destroying ) appBarCallback( msg, wparam, lparam );
+ return 0;
+ }
+ case WM_DISPLAYCHANGE:
+ {
+ DebugString( "WM_DISPLAYCHANGE\n" );
+ appbar_posChanged();
+ }
+ case WM_TIMER:
+ { // // not using multiplexed timer for independent speed
+ switch ( wparam )
+ {
+ case IDT_AUTOHIDE:
+ onAutoHideTimer();
+ break;
+ case IDT_AUTOUNHIDE:
+ onAutoUnHideTimer();
+ break;
+ }
+ }
+ case WM_COMMAND:
+ {
+ // forward onto the main Winamp window and let it do it
+ if ( HIWORD( wparam ) == THBN_CLICKED )
+ {
+ SendMessageW( plugin.hwndParent, msg, wparam, lparam );
+ }
+ }
+ }
+ }
+
+ return APPBARWND_PARENT::wndProc( hwnd, msg, wparam, lparam );
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::onAutoHideTimer() {
+ HWND me = getOsWindowHandle();
+ POINT pt;
+ RECT rc;
+ HWND hact;
+ if (m_cur_autohide) {
+ if (!m_cur_hiding) {
+ GetCursorPos(&pt);
+ GetWindowRect(hwnd, &rc);
+ snapAdjust(&rc, -1);
+ hact = GetForegroundWindow();
+
+ if ((!PtInRect(&rc, pt) || screenCorner(&pt)) && (hact != me) && /*(hact!= NULL) && */(GetWindowOwner(hact) != me)) {
+ resetAutoHideTimer();
+ autoHide();
+ setAutoUnHideTimer();
+ }
+ }
+ else {
+ resetAutoHideTimer();
+ setAutoUnHideTimer();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::onAutoUnHideTimer() {
+ RECT rc;
+ POINT pt;
+ HWND me = getOsWindowHandle();
+
+ GetWindowRect(me, &rc);
+ snapAdjust(&rc, -1);
+ if (m_cur_autohide) {
+ if (m_cur_hiding) {
+ GetCursorPos(&pt);
+ if (PtInRect(&rc, pt) && !screenCorner(&pt)) {
+ resetAutoUnHideTimer();
+ autoUnHide();
+ setAutoHideTimer();
+ }
+ }
+ else {
+ resetAutoUnHideTimer();
+ setAutoHideTimer();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::autoHide() {
+ if (m_cur_autohide) {
+ if (!m_cur_hiding) {
+ RECT rc;
+
+ getWindowRect(&rc);
+
+ int h = rc.bottom-rc.top;
+ int w = rc.right-rc.left;
+
+ int aaw = appbar_getAutoHideWidthHeight();
+
+ RECT adj={0,0,0,0};
+ Layout *l = static_cast<Layout*>(getInterface(layoutGuid));
+ l->getSnapAdjust(&adj);
+ if (renderRatioActive()) multRatio(&adj);
+
+ RECT viewRect = {0};
+ Wasabi::Std::getViewport(&viewRect, hwnd, 1);
+
+ switch (m_side) {
+ case APPBAR_TOP:
+ rc.top = -(h - aaw + adj.top - adj.bottom);
+ break;
+ case APPBAR_BOTTOM:
+ rc.top = (viewRect.bottom - viewRect.top) - aaw - adj.top;
+ break;
+ case APPBAR_LEFT:
+ rc.left = -(w - aaw + adj.left - adj.right);
+ break;
+ case APPBAR_RIGHT:
+ rc.left = viewRect.right - aaw - adj.left;
+ break;
+ }
+
+ switch (m_side) {
+ case APPBAR_TOP:
+ case APPBAR_BOTTOM:
+ rc.bottom = rc.top + h;
+ break;
+ case APPBAR_LEFT:
+ case APPBAR_RIGHT:
+ rc.right = rc.left + w;
+ break;
+ }
+
+ slideWindow(&rc);
+ m_cur_hiding = 1;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::autoUnHide() {
+ if (m_cur_autohide) {
+ if (m_cur_hiding) {
+ m_cur_hiding = 0;
+
+ RECT rc;
+ getWindowRect(&rc);
+
+ int h = rc.bottom-rc.top;
+ int w = rc.right-rc.left;
+
+ int aaw = appbar_getAutoHideWidthHeight();
+
+ RECT adj={0,0,0,0};
+ Layout *l = static_cast<Layout*>(getInterface(layoutGuid));
+ l->getSnapAdjust(&adj);
+ if (renderRatioActive()) multRatio(&adj);
+
+ switch (m_side) {
+ case APPBAR_TOP:
+ rc.top += (h - aaw) - (adj.top + adj.bottom);
+ rc.bottom += (h - aaw) - (adj.top + adj.bottom);
+ break;
+ case APPBAR_BOTTOM:
+ rc.top -= (h - aaw) - (adj.top + adj.bottom);
+ rc.bottom -= (h - aaw) - (adj.top + adj.bottom);
+ break;
+ case APPBAR_LEFT:
+ rc.right += (w - aaw) - (adj.left + adj.right);
+ rc.left += (w - aaw) - (adj.left + adj.right);
+ break;
+ case APPBAR_RIGHT:
+ rc.left -= (w - aaw) - (adj.left + adj.right);
+ rc.right -= (w - aaw) - (adj.left + adj.right);
+ break;
+ }
+
+ slideWindow(&rc);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const int g_dtSlideHide = 400;
+const int g_dtSlideShow = 200;
+
+// -----------------------------------------------------------------------
+void AppBarWnd::slideWindow(RECT *prc) {
+ if (m_cur_autohide) {
+ m_sliding = 1;
+ RECT rcOld;
+ RECT rcNew;
+ int x, y, dx, dy, dt, t, t0;
+ BOOL fShow;
+ HANDLE hThreadMe;
+ int priority;
+
+ HWND hwnd = getOsWindowHandle();
+
+ rcNew = *prc;
+
+ /*DebugString("rcNew : left=%d, top=%d, "
+ "right=%d, bottom=%d\n", rcNew.left,
+ rcNew.top, rcNew.right, rcNew.bottom);*/
+
+ if ((g_dtSlideShow > 0) && (g_dtSlideHide > 0)) {
+ GetWindowRect(hwnd, &rcOld);
+
+ fShow = TRUE;/*(rcNew.bottom - rcNew.top) > (rcOld.bottom - rcOld.top) ||
+ (rcNew.right - rcNew.left) > (rcOld.right - rcOld.left);*/
+
+ dx = (rcNew.left - rcOld.left);
+ dy = (rcNew.top - rcOld.top);
+
+ if (fShow) {
+ rcOld = rcNew;
+ OffsetRect(&rcOld, -dx, -dy);
+ //DebugString("appbar_slideWindow %d %d\n", rcOld.left, rcOld.top);
+ move(rcOld.left, rcOld.top);
+ dt = g_dtSlideShow;
+ }
+ else {
+ dt = g_dtSlideHide;
+ }
+
+ hThreadMe = GetCurrentThread();
+ priority = GetThreadPriority(hThreadMe);
+ SetThreadPriority(hThreadMe, THREAD_PRIORITY_HIGHEST);
+
+ t0 = GetTickCount();
+ while ((t = GetTickCount()) < t0 + dt) {
+ x = rcOld.left + dx * (t - t0) / dt;
+ y = rcOld.top + dy * (t - t0) / dt;
+
+ //DebugString("appbar_slideWindow(2) %d %d\n", x, y);
+ move(x, y);
+ //SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+ if (fShow) {
+ UpdateWindow(hwnd);
+ //invalidateWindowRegion();
+ //updateWindowRegion();
+ }
+ else UpdateWindow(GetDesktopWindow());
+ }
+
+ SetThreadPriority(hThreadMe, priority);
+ }
+
+ //DebugString("appbar_slideWindow(3) %d %d\n", rcNew.left, rcNew.top);
+ move(rcNew.left, rcNew.top);
+ appbar_onSlide();
+ }
+ WASABI_API_MAKI->vcpu_setComplete();
+ m_sliding = 0;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::unOwn()
+{
+ // registration was successful, we should reparent the window to NULL so that minimizing the app or changing the main AOT flag does
+ // nothing to this window
+ Layout *l = static_cast<Layout*>(getInterface(layoutGuid));
+ if (l) {
+ if (!l->getNoParent()) {
+ l->setNoParent(2);
+ // whoaaah!
+ reinit();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::reOwn() {
+ OSWINDOWHANDLE mw = WASABI_API_WND->main_getRootWnd()->getOsWindowHandle();
+ if (IsIconic(mw)) ShowWindow(mw, SW_RESTORE);
+ // undock was successful, we should re-own the window to what it was previously. if the old owner is minimized, we should restore it first
+ OSWINDOWHANDLE oldparent = WASABI_API_WND->main_getRootWnd()->getOsWindowHandle();
+ if (IsIconic(oldparent)) ShowWindow(oldparent, SW_RESTORE);
+ Layout *l = static_cast<Layout *>(getInterface(layoutGuid));
+ if (l) {
+ int oldnp = l->getNoParent();
+ const wchar_t *np = l->getGuiObject()->guiobject_getXmlParam(L"noparent");
+ int newnp = WTOI(np);
+ if (oldnp != newnp)
+ {
+ l->setNoParent(newnp);
+ // whoaaah!
+ reinit();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::straightenRect(int side, RECT *r) {
+ int w=0, h=0;
+
+ int wasregistered = m_registered;
+ if (!m_registered) registerWinAppBar();
+
+ APPBARDATA abd;
+ abd.hWnd = hwnd;
+ abd.cbSize = sizeof(APPBARDATA);
+ abd.rc = *r;
+ abd.uEdge = side;
+
+ RECT viewRect = {0};
+ Wasabi::Std::getViewport(&viewRect, hwnd, 1);
+
+ switch (side) {
+ case APPBAR_LEFT:
+ case APPBAR_RIGHT:
+ w = abd.rc.right - abd.rc.left;
+ abd.rc.top = viewRect.top;
+ abd.rc.bottom = viewRect.bottom;
+ break;
+ case APPBAR_TOP:
+ case APPBAR_BOTTOM:
+ h = abd.rc.bottom - abd.rc.top;
+ abd.rc.left = viewRect.left;
+ abd.rc.right = viewRect.right;
+ break;
+ }
+
+ SHAppBarMessage(ABM_QUERYPOS, &abd);
+
+ switch (abd.uEdge) {
+ case APPBAR_LEFT:
+ abd.rc.right = abd.rc.left + w;
+ break;
+ case APPBAR_RIGHT:
+ abd.rc.left = abd.rc.right - w;
+ break;
+ case APPBAR_TOP:
+ abd.rc.bottom = abd.rc.top + h;
+ break;
+ case APPBAR_BOTTOM:
+ abd.rc.top = abd.rc.bottom - h;
+ break;
+ }
+
+ if (!wasregistered) unregisterWinAppBar();
+
+ *r = abd.rc;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::appbar_setNoRestore(int no) {
+ m_norestore = no;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::onSetVisible( int show )
+{
+ if ( !show && m_side != APPBAR_NOTDOCKED && !m_suspended )
+ {
+ if ( m_cur_autohide )
+ {
+ resetAutoHideSide( m_cur_side );
+ if ( m_cur_hiding )
+ resetAutoUnHideTimer();
+ else
+ resetAutoHideTimer();
+ }
+
+ m_suspended = 1;
+ unDock();
+ APPBARWND_PARENT::onSetVisible( show );
+ return;
+ }
+ else if ( show && m_suspended )
+ {
+ APPBARWND_PARENT::onSetVisible( show );
+ m_suspended = 0;
+ updateDocking();
+ return;
+ }
+
+ APPBARWND_PARENT::onSetVisible( show );
+}
+
+// -----------------------------------------------------------------------
+int AppBarWnd::screenCorner(POINT *pt) {
+ RECT primary = {0};
+ Wasabi::Std::getViewport(&primary, hwnd, 1);
+ if (pt->x > primary.right-2 && pt->x <= primary.right) {
+ if (pt->y > primary.bottom-2 && pt->y <= primary.bottom) {
+ // bottom right corner
+ return 1;
+ }
+ else if (pt->y < primary.top+2 && pt->y >= primary.top) {
+ // top right corner
+ return 1;
+ }
+ }
+ else if (pt->x < primary.left+2 && pt->x >= primary.left) {
+ if (pt->y > primary.bottom-2 && pt->y <= primary.bottom) {
+ // bottom left corner
+ return 1;
+ }
+ else if (pt->y < primary.top+2 && pt->y >= primary.top) {
+ // top left corner
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::snapAdjust(RECT *r, int way)
+{
+ RECT s;
+ Layout *l = static_cast<Layout*>(getInterface(layoutGuid));
+ if (!l) return;
+ l->getSnapAdjust(&s);
+ int h = r->bottom - r->top;
+ int w = r->right - r->left;
+ if (way == 1) {
+ h += s.top + s.bottom;
+ w += s.left + s.right;
+ r->left -= s.left;
+ r->top -= s.top;
+ r->bottom = r->top + h;
+ r->right = r->left + w;
+ }
+ else if (way == -1) {
+ h -= s.top + s.bottom;
+ w -= s.left + s.right;
+ r->left += s.left;
+ r->top += s.top;
+ r->bottom = r->top + h;
+ r->right = r->left + w;
+ }
+}
+
+// -----------------------------------------------------------------------
+void AppBarWnd::onRatioChanged()
+{
+ APPBARWND_PARENT::onRatioChanged();
+ if (m_side != APPBAR_NOTDOCKED) appbar_posChanged();
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/appbarwnd.h b/Src/Wasabi/api/wnd/wndclass/appbarwnd.h
new file mode 100644
index 00000000..7b8fba35
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/appbarwnd.h
@@ -0,0 +1,155 @@
+#ifndef _APPBARWND_H
+#define _APPBARWND_H
+
+#include <bfc/common.h>
+#include <shellapi.h>
+#include <api/wnd/wndclass/clickwnd.h>
+
+#define APPBARWND_PARENT ClickWnd
+
+#define APPBAR_TOP_ENABLED 1
+#define APPBAR_LEFT_ENABLED 2
+#define APPBAR_BOTTOM_ENABLED 4
+#define APPBAR_RIGHT_ENABLED 8
+
+#define APPABR_ALL_ENABLED (APPBAR_TOP_ENABLED|APPBAR_LEFT_ENABLED|APPBAR_BOTTOM_ENABLED|APPBAR_RIGHT_ENABLED)
+
+#define APPBAR_CALLBACK WM_USER + 1010
+
+#define IDT_AUTOHIDE 0x10000
+#define IDT_AUTOUNHIDE 0x10001
+
+#ifdef WIN32
+#define APPBAR_NOTDOCKED -1
+#define APPBAR_LEFT ABE_LEFT
+#define APPBAR_TOP ABE_TOP
+#define APPBAR_RIGHT ABE_RIGHT
+#define APPBAR_BOTTOM ABE_BOTTOM
+#else
+#error port me
+#endif
+
+// todo : dispatch
+class AppBar {
+public:
+ virtual void appbar_dock(int side)=0;
+ virtual int appbar_isDocked()=0;
+ virtual int appbar_getSide()=0;
+ virtual void appbar_setEnabledSides(int mask)=0;
+ virtual int appbar_getEnabledSides()=0;
+ virtual int appbar_isSideEnabled(int side)=0;
+ virtual int appbar_testDock(int x, int y, RECT *dockrect=NULL)=0;
+ virtual int appbar_updateAutoHide()=0;
+ virtual int appbar_updateAlwaysOnTop()=0;
+ virtual int appbar_isHiding()=0;
+ virtual int appbar_wantAutoHide()=0;
+ virtual int appbar_wantAlwaysOnTop()=0;
+ virtual int appbar_isAutoHiding()=0;
+ virtual void appbar_onDock(int side) {}
+ virtual void appbar_onUnDock() {}
+ virtual void appbar_onSlide() {}
+ virtual void appbar_posChanged()=0;
+ virtual int appbar_isSideAutoHideSafe(int side)=0;
+ virtual int appbar_getAutoHideWidthHeight()=0;
+ virtual void appbar_setNoRestore(int no)=0;
+};
+
+// {242CFAA4-31B3-4b01-97C8-2F0A9FFDEF79}
+static const GUID appBarGuid =
+{ 0x242cfaa4, 0x31b3, 0x4b01, { 0x97, 0xc8, 0x2f, 0xa, 0x9f, 0xfd, 0xef, 0x79 } };
+
+class api_region;
+
+// TODO: benski> only class making active use of being derived from this seems to be Layout and GuiObjectWnd
+// maybe just layout ...
+
+class AppBarWnd : public APPBARWND_PARENT, public AppBar {
+ public:
+ AppBarWnd();
+ virtual ~AppBarWnd();
+
+ void appbar_dock(int side);
+ int appbar_isDocked();
+ int appbar_getSide();
+
+ void appbar_setEnabledSides(int mask);
+ int appbar_getEnabledSides();
+ int appbar_isSideEnabled(int side);
+
+ int appbar_testDock(int x, int y, RECT *dockrect=NULL);
+
+ int appbar_updateAutoHide();
+ int appbar_updateAlwaysOnTop();
+
+ int appbar_isSideAutoHideSafe(int side);
+
+ virtual int appbar_wantAutoHide() { return 1; }
+ virtual int appbar_wantAlwaysOnTop() { return 1; }
+
+ int appbar_isHiding();
+ int appbar_isAutoHiding();
+
+ void appbar_posChanged();
+ void appbar_setNoRestore(int no);
+ virtual int appbar_getAutoHideWidthHeight() { return 2; }
+
+ virtual LRESULT wndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+ virtual void onAfterReinit();
+ virtual void onSetVisible(int show);
+
+ virtual void onRatioChanged();
+
+ private:
+
+ void appBarCallback(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ int registerWinAppBar();
+ void unregisterWinAppBar();
+ void notifyWinAppBarPosition(int side, RECT rect);
+
+ OSWINDOWHANDLE getCurAutoHide(int side);
+
+ void getDockRect(int side, RECT *rc);
+ void getEdge(int side, RECT *rc);
+ void straightenRect(int side, RECT *r);
+ void updateDocking();
+ void updateSide();
+ void updateTimers();
+ void resetAutoHideSide(int side);
+ void setAutoHideSide(int side);
+ void setAutoHideTimer();
+ void setAutoUnHideTimer();
+ void resetAutoHideTimer();
+ void resetAutoUnHideTimer();
+ void onAutoHideTimer();
+ void onAutoUnHideTimer();
+ void autoHide();
+ void autoUnHide();
+ void slideWindow(RECT *prc);
+ int screenCorner(POINT *pt);
+ void snapAdjust(RECT *r, int way);
+
+ void dock(int side);
+ void unDock();
+
+ void unOwn();
+ void reOwn();
+
+ int m_registered;
+ int m_side;
+ int m_enabled;
+ int m_cur_autohide;
+ int m_cur_side;
+ int m_cur_hiding;
+ OSWINDOWHANDLE m_oldZOrder;
+ int m_destroying;
+ int m_norestore;
+ int m_autohide_timer_set;
+ int m_autounhide_timer_set;
+ int m_sliding;
+ int m_suspended;
+ int m_fs;
+ int m_wahidden;
+};
+
+#endif //_APPBARWND_H \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/backbufferwnd.cpp b/Src/Wasabi/api/wnd/wndclass/backbufferwnd.cpp
new file mode 100644
index 00000000..10e0a04a
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/backbufferwnd.cpp
@@ -0,0 +1,86 @@
+#include <precomp.h>
+#include "backbufferwnd.h"
+#include <tataki/canvas/bltcanvas.h>
+#include <api/api.h>
+#include <tataki/region/region.h>
+
+// -----------------------------------------------------------------------
+BackBufferWnd::BackBufferWnd() {
+ backbuffer = 0;
+ canvas_w = -1;
+ canvas_h = -1;
+ back_buffer = NULL;
+}
+
+// -----------------------------------------------------------------------
+BackBufferWnd::~BackBufferWnd() {
+ delete back_buffer;
+}
+
+//------------------------------------------------------------------------
+BltCanvas *BackBufferWnd::getBackBuffer() {
+ return back_buffer;
+}
+
+// -----------------------------------------------------------------------
+int BackBufferWnd::onPaint(Canvas *canvas) {
+
+ BBWND_PARENT::onPaint(canvas);
+
+ if (!canvas) return 1;
+
+ RECT r;
+ getClientRect(&r);
+
+ if (back_buffer && r.right-r.left > 0 && r.bottom -r.top > 0) {
+
+ int w = r.right-r.left;
+ int h = r.bottom-r.top;
+
+ if (canvas_w != w || canvas_h != h) {
+ delete back_buffer;
+ back_buffer = new BltCanvas(w, h, getOsWindowHandle());
+ canvas_w = w;
+ canvas_h = h;
+ }
+
+#ifdef _WIN32
+ RegionI reg;
+ canvas->getClipRgn(&reg);
+ back_buffer->selectClipRgn(&reg);
+#else
+#warning port me
+#endif
+ canvas->blit(r.left, r.top, back_buffer, 0, 0, w, h);
+ back_buffer->selectClipRgn(NULL);
+ }
+
+ return 1;
+}
+
+int BackBufferWnd::onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx) {
+ if (who_idx >= my_idx || !wantBackBuffer()) return 0;
+
+ RECT rr;
+ getClientRect(&rr);
+
+ api_region *_r = getRegion();
+ RegionI *__r=NULL;
+
+ if (!_r) {
+ __r = new RegionI();
+ _r = __r;
+ _r->setRect(&rr);
+ } else {
+ _r->offset(rr.left, rr.top);
+ }
+
+ int intersect = _r->doesIntersectRgn(r);
+ if (intersect)
+ r->addRegion(_r);
+
+ delete __r;
+
+ return intersect;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/backbufferwnd.h b/Src/Wasabi/api/wnd/wndclass/backbufferwnd.h
new file mode 100644
index 00000000..1f536ba1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/backbufferwnd.h
@@ -0,0 +1,53 @@
+#ifndef __BBWND_H
+#define __BBWND_H
+
+#include <api/wnd/wndclass/abstractwndhold.h>
+
+#ifdef WASABI_COMPILE_SKIN
+#define BBWND_PARENT AbstractWndHolder
+#else
+#define BBWND_PARENT ServiceWndHolder
+#endif
+
+/**
+ class BackBufferWnd
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class BackBufferWnd : public BBWND_PARENT {
+
+ public:
+
+ BackBufferWnd();
+ virtual ~BackBufferWnd();
+
+ virtual int onPaint(Canvas *c);
+
+ /**
+ BackBufferWnd method wantBackBuffer .
+
+ @ret 0
+ @param None
+ */
+ virtual int wantBackBuffer() { return 0; }
+ virtual BltCanvas *getBackBuffer();
+ virtual int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx);
+
+ /**
+ BackBufferWnd method wantSiblingInvalidations .
+
+ @ret 0
+ @param None
+ */
+ virtual int wantSiblingInvalidations() { return wantBackBuffer(); }
+
+ private:
+
+ int backbuffer;
+ BltCanvas *back_buffer;
+ int canvas_w, canvas_h;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/blankwnd.cpp b/Src/Wasabi/api/wnd/wndclass/blankwnd.cpp
new file mode 100644
index 00000000..beeddfd5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/blankwnd.cpp
@@ -0,0 +1,24 @@
+#include "precomp.h"
+
+#include "blankwnd.h"
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/PaintCanvas.h>
+
+BlankWnd::BlankWnd(RGB32 _color) : color(_color)
+{
+}
+
+int BlankWnd::onPaint(Canvas *canvas)
+{
+ PaintCanvas pc;
+ if (canvas == NULL)
+ {
+ if (!pc.beginPaint(this)) return 0;
+ canvas = &pc;
+ }
+
+ canvas->fillRect(&clientRect(), color);
+
+ return 1;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/blankwnd.h b/Src/Wasabi/api/wnd/wndclass/blankwnd.h
new file mode 100644
index 00000000..56f44139
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/blankwnd.h
@@ -0,0 +1,41 @@
+#ifndef _BLANKWND_H
+#define _BLANKWND_H
+
+#include <bfc/common.h>
+#include <api/wnd/virtualwnd.h>
+
+#define BLANKWND_PARENT VirtualWnd
+
+/**
+ Class BlankWnd provides blank windows. The initial color can be set in the
+ constructor, with a default of black. There is a method for painting the window from a Canvas.
+
+ @short Blank Window with background color.
+ @author Nullsoft
+ @ver 1.0
+ @see VirtualWnd
+*/
+class BlankWnd : public BLANKWND_PARENT {
+public:
+ /**
+ You can set the background color for the window via an RGB value.
+ The RGB value is contructed using RGB(), like so RGB(Red, Green, Blue);
+
+ @param color The RGB value of the background color to use.
+ */
+ BlankWnd(RGB32 color=RGB(0,0,0));
+
+ /**
+ This event is triggered when the window needs to be repainted.
+ Override it to implement your own handling of this event.
+
+ @ret 1, If you handle the event;
+ @param canvas A pointer to the canvas on which will we paint.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+private:
+ RGB32 color;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.cpp b/Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.cpp
new file mode 100644
index 00000000..a32d29c5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.cpp
@@ -0,0 +1,113 @@
+#include <precomp.h>
+#include "bufferpaintwnd.h"
+#include <tataki/canvas/bltcanvas.h>
+
+// -----------------------------------------------------------------------
+BufferPaintWnd::BufferPaintWnd() {
+ canvas_w = -1;
+ canvas_h = -1;
+ render_canvas = NULL;
+ invalidated = 1;
+}
+
+// -----------------------------------------------------------------------
+BufferPaintWnd::~BufferPaintWnd() {
+ delete render_canvas;
+}
+
+// -----------------------------------------------------------------------
+int BufferPaintWnd::onInit() {
+ BUFFERPAINTWND_PARENT::onInit();
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void BufferPaintWnd::bufferPaint() {
+ updateCanvas();
+ if (render_canvas != NULL)
+ onBufferPaint(render_canvas, canvas_w, canvas_h);
+}
+
+void BufferPaintWnd::invalidateBuffer() {
+ invalidated = 1;
+ invalidate();
+}
+
+// -----------------------------------------------------------------------
+void BufferPaintWnd::getBufferPaintSize(int *w, int *h) {
+ RECT r;
+ getClientRect(&r);
+ if (w) *w = r.right-r.left;
+ if (h) *h = r.bottom-r.top;
+}
+
+// -----------------------------------------------------------------------
+void BufferPaintWnd::getBufferPaintSource(RECT *r) {
+ ASSERT(r != NULL);
+ r->left = 0;
+ r->right = canvas_w;
+ r->top = 0;
+ r->bottom = canvas_h;
+}
+
+// -----------------------------------------------------------------------
+void BufferPaintWnd::getBufferPaintDest(RECT *r) {
+ ASSERT(r != NULL);
+ getClientRect(r);
+}
+
+// -----------------------------------------------------------------------
+int BufferPaintWnd::onPaint(Canvas *canvas) {
+
+ BUFFERPAINTWND_PARENT::onPaint(canvas);
+
+ if (invalidated) bufferPaint();
+ invalidated = 0;
+
+ RECT r;
+ getBufferPaintDest(&r);
+ RECT sr;
+ getBufferPaintSource(&sr);
+
+ render_canvas->/*getSkinBitmap()->*/stretchToRectAlpha(canvas, &sr, &r, getPaintingAlpha());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int BufferPaintWnd::onResize() {
+ if (!BUFFERPAINTWND_PARENT::onResize()) return 0;
+ if (updateCanvas()) {
+ invalidated = 1;
+ invalidate();
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+int BufferPaintWnd::updateCanvas() {
+ int w, h;
+ getBufferPaintSize(&w, &h);
+
+ if (wantEvenAlignment()) {
+ if (w & 1) w++;
+ if (h & 1) h++;
+ }
+
+ if (w == 0 || h == 0) return 0;
+
+ int newone = 0;
+
+ if (canvas_w != w || canvas_h != h) {
+ if (render_canvas)
+ render_canvas->DestructiveResize(w, wantNegativeHeight() ? -h : h);
+ else
+ render_canvas = new BltCanvas(w, wantNegativeHeight() ? -h : h, getOsWindowHandle());
+ canvas_w = w;
+ canvas_h = h;
+ newone = 1;
+ onNewBuffer(canvas_w, canvas_h);
+ }
+
+ return newone;
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.h b/Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.h
new file mode 100644
index 00000000..778fb751
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/bufferpaintwnd.h
@@ -0,0 +1,40 @@
+#ifndef __BPAINTWND_H
+#define __BPAINTWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define BUFFERPAINTWND_PARENT GuiObjectWnd
+
+class BufferPaintWnd : public BUFFERPAINTWND_PARENT {
+
+ public:
+ BufferPaintWnd();
+ virtual ~BufferPaintWnd();
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *c);
+
+ virtual int onBufferPaint(BltCanvas *c, int w, int h) { return 1; }
+ virtual int wantEvenAlignment() { return 0; } // if you need even coordinates for your framebuffer, return 1 here
+ virtual void getBufferPaintSize(int *w, int *h); // by default returns client width/height
+ virtual void getBufferPaintSource(RECT *r); // by default returns the size of the quickpaint canvas
+ virtual void getBufferPaintDest(RECT *r); // by default returns the size of client area
+ virtual int wantNegativeHeight() { return 0; }
+ virtual void invalidateBuffer();
+ virtual int onResize();
+ virtual void onNewBuffer(int w, int h) {}
+
+ protected:
+ BltCanvas *render_canvas;
+
+ private:
+ void bufferPaint();
+ int updateCanvas();
+
+ int canvas_w, canvas_h;
+
+ int invalidated;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/buttbar.cpp b/Src/Wasabi/api/wnd/wndclass/buttbar.cpp
new file mode 100644
index 00000000..ffb491cf
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/buttbar.cpp
@@ -0,0 +1,208 @@
+#include "precomp.h"
+//PORTABLE
+#include <bfc/wasabi_std.h>
+#include <api/wnd/wndclass/buttbar.h>
+#include <api/wnd/notifmsg.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <api/wnd/popup.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/objects/c_script/h_button.h>
+
+
+class ButtHooker : public H_Button {
+public:
+ ButtHooker(ButtBar *hangout, ScriptObject *butt) : bb(hangout), H_Button(butt) { }
+
+ void hook_onLeftClick() {
+ bb->onLeftPush(0, 0);
+ }
+
+private:
+ ButtBar *bb;
+};
+
+ButtBar::ButtBar(int resizemode) {
+ spacer = 0;
+ resize_mode = resizemode;
+ hooker = NULL;
+ if (resize_mode == STACK) {
+ setContent(L"wasabi.buttonbar.stack");
+ }
+}
+
+ButtBar::~ButtBar() {
+ buttons.deleteAll();
+ delete hooker;
+}
+
+void ButtBar::setResizeMode(int resizemode) {
+ if (resize_mode == resizemode) return;
+ resize_mode = resizemode;
+ if (isPostOnInit()) onResize();
+}
+
+int ButtBar::onInit() {
+ int i;
+
+ BUTTBAR_PARENT::onInit();
+
+ // create the buttons
+ for (i = 0; i < buttons.getNumItems(); i++) {
+ buttons[i]->init(this);
+ if (resize_mode == STACK) {
+ if (i != 0) buttons[i]->setVisible(FALSE);
+ if (i == 0) setGroupLabel(buttons[i]->getButtonText());
+ }
+ }
+
+ return 1;
+}
+
+int ButtBar::addChild(ButtonWnd *child) {
+ buttons.addItem(child);
+ if (isInited()) {
+ child->init(this);
+ child->setParent(this);
+ onResize();
+ if (buttons.getNumItems() == 1)
+ setGroupLabel(child->getButtonText());
+ }
+ return 1;
+}
+
+int ButtBar::removeChild(ButtonWnd *child) {
+ if (!buttons.haveItem(child)) return 0;
+ if (isInited()) onResize();
+ return 1;
+}
+
+int ButtBar::getNumChildren() {
+ return buttons.getNumItems();
+}
+
+ButtonWnd *ButtBar::enumChild(int n) {
+ return buttons[n];
+}
+
+int ButtBar::getWidth() {
+ int w = 0;
+ for (int i = 0; i < buttons.getNumItems(); i++) {
+ w += buttons[i]->getWidth()+spacer;
+ }
+ return w;
+}
+
+int ButtBar::getHeight() {
+ if (resize_mode == STACK) {
+ ifc_window *rw = getContentRootWnd();
+ return rw->getPreferences(SUGGESTED_H);
+ } else {
+ int h = 0;
+ for (int i = 0; i < buttons.getNumItems(); i++) {
+ h = MAX(h, buttons[i]->getHeight()+1);
+ }
+ return h;
+ }
+}
+
+void ButtBar::onLeftPush(int x, int y)
+{
+ if (resize_mode == STACK)
+ {
+ PopupMenu pop(this);
+ foreach(buttons)
+ pop.addCommand(buttons.getfor()->getButtonText(), foreach_index);
+ endfor
+ int r = pop.popAnchored();
+ if (r >= 0) {
+ buttons[r]->onLeftPush(0, 0);
+ setGroupLabel(buttons[r]->getButtonText());
+ }
+ }
+}
+
+int ButtBar::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) {
+ switch (msg) {
+ case ChildNotify::BUTTON_LEFTPUSH: {
+ int ret;
+ if (ret = onLeftPush(child->getNotifyId())) {
+ return ret;
+ } else {
+// This won't fit the current notification schema.
+// We _must_ change it -- too many interfaces assume that the
+// button notification is called back through the parent.
+// return notifyParent(msg, p1, p2);
+
+// So, I made a new basewnd method passNotifyUp() to defer a notification
+// to the current object's notification target.
+ return passNotifyUp(child, msg, p1, p2);
+ }
+ }
+ break;
+ }
+ return BUTTBAR_PARENT::childNotify(child, msg, p1, p2);
+}
+
+int ButtBar::onResize() {
+ BUTTBAR_PARENT::onResize(); // calling your parent is good(tm) =)
+ if (!isPostOnInit()) return 0; // that's just an optim, in case someone's dumb and calling us directly when it shouldnt
+ switch (resize_mode) {
+ case NORMAL: {
+ RECT r = clientRect();
+ int height = r.bottom - r.top;
+ int x = r.left;
+ for (int i = 0; i < buttons.getNumItems(); i++) {
+ int w = buttons[i]->getWidth()+spacer;
+ buttons[i]->resize(x, r.top, w, height);
+ x += w;
+ if (x > r.right) break;
+ }
+ }
+ break;
+ case STRETCH: {
+ if (buttons.getNumItems() > 0) {
+ RECT r = clientRect();
+ int height = r.bottom - r.top;
+ int w = (r.right - r.left) / buttons.getNumItems();
+ int x = r.left;
+ for (int i = 0; i < buttons.getNumItems(); i++) {
+ if (i == buttons.getNumItems()-1) w = (r.right - r.left) - x;
+ buttons[i]->resize(x, r.top, w, height);
+ x += w;
+ }
+ }
+ }
+ break;
+ case STACK: // no point
+ break;
+ }
+
+ return 1;
+}
+
+int ButtBar::onPaint(Canvas *canvas) {
+ ASSERT(canvas != NULL);
+ if (resize_mode != STACK) {
+ BUTTBAR_PARENT::onPaint(canvas);
+ renderBaseTexture(canvas, clientRect());
+ }
+ return 1;
+}
+
+void ButtBar::setGroupLabel(const wchar_t *l) {
+ setName(l);
+ onNewContent();
+}
+
+void ButtBar::onNewContent()
+{
+ if (resize_mode != STACK) return;
+ ScriptObject *text = findScriptObject(L"buttonbar.text");
+ if (text == NULL) return;
+ C_Text(text).setText(getNameSafe(L"no tabs"));
+
+ // hook the clicks
+ delete hooker;
+ ScriptObject *mousetrap = findScriptObject(L"mousetrap");
+ hooker = new ButtHooker(this, mousetrap);
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/buttbar.h b/Src/Wasabi/api/wnd/wndclass/buttbar.h
new file mode 100644
index 00000000..473ddd58
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/buttbar.h
@@ -0,0 +1,168 @@
+#ifndef _BUTTBAR_H
+#define _BUTTBAR_H
+
+#include <bfc/common.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/ptrlist.h>
+
+class ButtonWnd;
+class ButtHooker;
+
+#define BUTTBAR_PARENT GuiObjectWnd
+/**
+ A resizable button bar control.
+
+ @short A resizable button bar
+ @author Nullsoft
+ @ver 1.0
+ @see ButtonWnd
+*/
+class ButtBar : public BUTTBAR_PARENT {
+public:
+ // resize modes
+ /**
+ Resize modes for the button bar.
+ */
+ enum { NORMAL, STRETCH, STACK };
+
+ /**
+ You can set the resize mode for the button bar by specifying it
+ via the contructor.
+
+ @see ~ButtBar() setResizeMode()
+ @param resizemode The default resize mode.
+ */
+ ButtBar(int resizemode=NORMAL);
+
+ /**
+ Deletes all the buttons present in the button bar.
+
+ @see ButtBar()
+ */
+ virtual ~ButtBar();
+
+ /**
+ This event is triggered when the button bar is being initialized.
+ If you override this, please call up the parent chain first, then
+ do your initialization.
+
+ @ret 1
+ */
+ virtual int onInit();
+
+ /**
+ This event is triggered when the button bar is being resized.
+ If you override this, please call up the parent chain first, then
+ do your own resize handling.
+
+ @ret 1
+ */
+ virtual int onResize();
+
+ /**
+ This event is triggered when the button bar is being painted.
+ If you override this, please call up the parent chain first, then
+ do your painting.
+
+ @ret 1
+ @param canvas The canvas upon which we will paint ourself.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ Sets the resize mode for the button bar.
+
+ @param resizemode NORMAL, Normal Resize; STRETCH, Stretch the button bar to window width; STACK, ?;
+ */
+ virtual void setResizeMode(int resizemode);
+
+ /**
+ Enables you to add a child window to your button bar.
+ Since this is a button bar, the windows you can add must be
+ derived or be ButtonWnd's.
+
+ @see removeChild()
+ @see getNumChildren()
+ @see enumChild()
+ @see ButtonWnd
+ @ret 1
+ @param child A pointer to the child window to add.
+ */
+ int addChild(ButtonWnd *child);
+
+ /**
+ */
+ int removeChild(ButtonWnd *child); // does not delete, just removes
+
+ /**
+ Get the number of children (buttons) that the button bar has.
+
+ @ret The number of children (buttons).
+ */
+ int getNumChildren();
+
+ /**
+ Get a pointer to a child (button) in the button bar, by button index number.
+ The first button added is at index 0.
+
+ @ret !NULL, a pointer the requested button; NULL, The button does not exist;
+ */
+ ButtonWnd *enumChild(int n);
+
+ /**
+ Get the width of the button bar (in pixels).
+
+ @see getHeight()
+ @ret Width of the button bar (in pixels).
+ */
+ int getWidth();
+
+ /**
+ Get the height of the button bar (in pixels).
+
+ @see getWidth()
+ @ret Height of the button bar (in pixels).
+ */
+ int getHeight();
+
+ /**
+ Event is triggered when the left mouse button is used to click on the
+ button bar. Override this to implement your own handling of the event.
+ If you override this method, call up the parent chain.
+
+ @param x The x coordinate of the mouse cursor in the button bar.
+ @param y The y coordinate of the mouse cursor in the button bar.
+ */
+ virtual void onLeftPush(int x, int y);
+
+ /**
+ Notify a child window via a generic message system.
+
+ @see addChild()
+ @ret
+ @param child A pointer to the child window which will receive the notify.
+ @param msg The message you want to send to the child.
+ @param p1 A user parameter.
+ @param p2 A user parameter.
+ */
+ virtual int childNotify(ifc_window *child, int msg,
+ intptr_t param1=0, intptr_t param2=0);
+
+ // GuiObjectWnd
+ virtual void onNewContent();
+
+ void setSpacer(int sp) { spacer = sp; }
+
+ void setGroupLabel(const wchar_t *l);
+
+protected:
+ virtual int onLeftPush(int id) { return 0; }
+
+ PtrList<ButtonWnd> buttons;
+private:
+ int resize_mode;
+ int spacer;
+ ButtHooker *hooker;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/buttwnd.cpp b/Src/Wasabi/api/wnd/wndclass/buttwnd.cpp
new file mode 100644
index 00000000..ddd500e5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/buttwnd.cpp
@@ -0,0 +1,761 @@
+#include <precomp.h>
+// bitmap-style buttons
+
+#include "buttwnd.h"
+#include <bfc/wasabi_std.h>
+#include <tataki/canvas/bltcanvas.h>
+#include <tataki/region/region.h>
+#include <api/wnd/notifmsg.h>
+
+
+#include <api/wndmgr/msgbox.h>
+#include <api/wnd/PaintCanvas.h>
+#define DEFAULT_BUTTON_HEIGHT 20
+
+ButtonWnd::ButtonWnd(const wchar_t *button_text)
+{
+ if (button_text != NULL)
+ setName(button_text);
+ currgn = NULL;
+ hirgn = NULL;
+ normalrgn = NULL;
+ pushedrgn = NULL;
+ activatedrgn = NULL;
+ base_texture = NULL;
+ xShift=0;
+ yShift=0;
+ textsize = DEFAULT_BUTTON_TEXT_SIZE;
+ alignment = TEXTALIGN_CENTER;
+ activated = 0;
+ userhilite = 0;
+ userdown = 0;
+ use_base_texture = 0;
+ center_bitmap = 0;
+ enabled = 1;
+ checked=0;
+ autodim=0;
+ borders = 1;
+ borderstyle = 0;
+ setBorderStyle(L"button_normal");
+ iwantfocus = 1;
+ color_text = L"wasabi.button.text";
+ color_hilite = L"wasabi.button.hiliteText";
+ color_dimmed = L"wasabi.button.dimmedText";
+ checkbmp = L"wasabi.popup.menu.check";
+ inactivealpha = 255;
+ activealpha = 255;
+ setRectRgn(1);
+ retcode = MSGBOX_ABORTED;
+ forcedown=0;
+}
+
+ButtonWnd::~ButtonWnd() {
+ delete normalrgn;
+ delete pushedrgn;
+ delete hirgn;
+ delete activatedrgn;
+}
+
+void ButtonWnd::checkState(POINT *pt) {
+ POINT pt2;
+ if (pt == NULL) {
+ pt = &pt2;
+ Wasabi::Std::getMousePos(pt);
+ }
+
+ api_region *old = currgn;
+
+ if (getDown()) { // button is down
+ if (pushedrgn)
+ currgn = pushedrgn;
+ else
+ currgn = normalrgn;
+ } else { // button is not down
+ if (hirgn && getHilite())
+ currgn = hirgn;
+ else
+ currgn = normalrgn;
+ }
+
+ if (old != currgn) invalidateWindowRegion();
+}
+
+void ButtonWnd::onCancelCapture() {
+ BUTTONWND_PARENT::onCancelCapture();
+ checkState();
+}
+
+int ButtonWnd::onMouseMove(int x, int y) {
+ POINT pt;
+ checkState(&pt);
+ return BUTTONWND_PARENT::onMouseMove(x, y);
+}
+
+api_region *ButtonWnd::getRegion() {
+ if (borders) return NULL;
+ return currgn;
+}
+
+void ButtonWnd::setModalRetCode(int r) { retcode = r; }
+int ButtonWnd::getModalRetCode() const { return retcode; }
+
+void ButtonWnd::onLeaveArea() {
+ BUTTONWND_PARENT::onLeaveArea();
+ if (hirgn || getDown()) invalidate();
+}
+
+void ButtonWnd::onEnterArea() {
+ BUTTONWND_PARENT::onEnterArea();
+ if (hirgn) invalidate();
+}
+
+/*BOOL ButtonWnd::mouseInRegion(int x, int y) {
+ POINT pos={x,y};
+ POINT p2=pos;
+
+ RECT r;
+ getClientRect(&r);
+ pos.x-=r.left;
+ pos.y-=r.top;
+
+ return (((!currgn || rectrgn) && PtInRect(&r, p2)) || (currgn && currgn->ptInRegion(&pos)));
+}*/
+
+int ButtonWnd::setBitmaps(const wchar_t *_normal, const wchar_t *_pushed, const wchar_t *_hilited, const wchar_t *_activated) {
+
+ if (_normal) { delete normalrgn; normalrgn = NULL; }
+ if (_pushed) { delete pushedrgn; pushedrgn = NULL; }
+ if (_hilited) { delete hirgn; hirgn = NULL; }
+ if (_activated) { delete activatedrgn; activatedrgn = NULL; }
+
+ if (_normal) {
+ normalbmp = _normal;
+ normalrgn = new RegionI(normalbmp.getBitmap());
+ currgn = normalrgn;
+ }
+
+ if (_pushed) {
+ pushedbmp = _pushed;
+ pushedrgn = new RegionI(pushedbmp.getBitmap());
+ }
+
+ if (_hilited) {
+ hilitebmp = _hilited;
+ hirgn = new RegionI(hilitebmp.getBitmap());
+ }
+
+ if (_activated) {
+ activatedbmp = _activated;
+ activatedrgn = new RegionI(activatedbmp.getBitmap());
+ }
+
+ if (isPostOnInit())
+ invalidate();
+
+ return 1;
+}
+
+SkinBitmap *ButtonWnd::getNormalBitmap() {
+ return normalbmp.getBitmap();
+}
+
+void ButtonWnd::freeResources() {
+ BUTTONWND_PARENT::freeResources();
+ delete normalrgn;
+ delete pushedrgn;
+ delete hirgn;
+ delete activatedrgn;
+ pushedrgn=NULL;
+ normalrgn=NULL;
+ hirgn=NULL;
+ activatedrgn=NULL;
+ currgn=NULL;
+}
+
+void ButtonWnd::reloadResources() {
+ BUTTONWND_PARENT::reloadResources();
+ if (normalbmp.getBitmap())
+ normalrgn = new RegionI(normalbmp.getBitmap());
+ if (pushedbmp.getBitmap())
+ pushedrgn = new RegionI(pushedbmp.getBitmap());
+ if (hilitebmp.getBitmap())
+ hirgn = new RegionI(hilitebmp.getBitmap());
+ if (activatedbmp.getBitmap())
+ activatedrgn = new RegionI(activatedbmp.getBitmap());
+ currgn = normalrgn;
+}
+
+int ButtonWnd::setBitmapCenter(int centerit) {
+ return center_bitmap = !!centerit;
+}
+
+int ButtonWnd::setBitmaps(OSMODULEHANDLE hInst, int _normal, int _pushed, int _hilited, int _activated, const wchar_t *_colorgroup)
+{
+ if (_normal) { delete normalrgn; normalrgn = NULL; }
+ if (_pushed) { delete pushedrgn; pushedrgn = NULL; }
+ if (_hilited) { delete hirgn; hirgn = NULL; }
+ if (_activated) { delete activatedrgn; activatedrgn = NULL; }
+
+ if (_colorgroup == NULL)
+ _colorgroup = colorgroup;
+
+ if (_normal)
+ {
+ normalbmp.setHInstanceBitmapColorGroup(_colorgroup);
+#ifdef _WIN32
+ normalbmp.setHInstance(hInst);
+#else
+#warning port me?
+#endif
+ normalbmp = _normal;
+ normalrgn = new RegionI(normalbmp.getBitmap());
+ }
+
+ if (_pushed) {
+ pushedbmp.setHInstanceBitmapColorGroup(_colorgroup);
+#ifdef _WIN32
+ pushedbmp.setHInstance(hInst);
+#else
+#warning port me?
+#endif
+ pushedbmp = _pushed;
+ pushedrgn = new RegionI(pushedbmp.getBitmap());
+ }
+
+ if (_hilited) {
+ hilitebmp.setHInstanceBitmapColorGroup(_colorgroup);
+#ifdef _WIN32
+ hilitebmp.setHInstance(hInst);
+#else
+#warning port me?
+#endif
+ hilitebmp = _hilited;
+ hirgn = new RegionI(hilitebmp.getBitmap());
+ }
+
+ if (_activated) {
+ activatedbmp.setHInstanceBitmapColorGroup(_colorgroup);
+ #ifdef _WIN32
+ activatedbmp.setHInstance(hInst);
+#else
+#warning port me?
+#endif
+ activatedbmp = _activated;
+ activatedrgn = new RegionI(activatedbmp.getBitmap());
+ }
+
+ return 1;
+}
+
+void ButtonWnd::setUseBaseTexture(int useit)
+{
+ if (use_base_texture == useit) return;
+ use_base_texture = useit;
+ invalidate();
+}
+
+void ButtonWnd::setBaseTexture(SkinBitmap *bmp, int x, int y, int tile)
+{
+ base_texture = bmp;
+ use_base_texture = TRUE;
+ tile_base_texture=tile;
+ xShift=x;
+ yShift=y;
+ invalidate();
+}
+
+int ButtonWnd::setButtonText(const wchar_t *text, int size)
+{
+ textsize = size;
+ ASSERT(textsize > 0);
+ setName(text);
+ invalidate();
+ return 1;
+}
+
+const wchar_t * ButtonWnd::getButtonText()
+{
+ return getName();
+}
+
+void ButtonWnd::setTextAlign(TextAlign align)
+{
+ alignment = align;
+ invalidate();
+}
+
+int ButtonWnd::getWidth()
+{
+ int addl=0;
+ if (checked) {
+ addl=checkbmp.getWidth()+3;
+ }
+ if (rightbmp.getBitmap())
+ addl+=rightbmp.getWidth()+3;
+ if (normalbmp == NULL)
+ {
+ TextInfoCanvas blt(this);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = textsize;
+ StringPrintfW lstr(L"j%sj", getNameSafe(L""));
+ if (wcschr(lstr, '\t')) lstr.cat(L" ");
+ int a=MAX((blt.getTextWidth(lstr, &fontInfo)*11)/10,8)+addl;
+ return a;
+ }
+ return normalbmp.getWidth()+addl;
+}
+
+int ButtonWnd::getHeight()
+{
+ int minh=0;
+ if (checked>0)
+ minh=checkbmp.getHeight();
+ if (rightbmp.getBitmap())
+ minh=MAX(rightbmp.getHeight(),minh);
+ if (normalbmp == NULL)
+ {
+ TextInfoCanvas blt(this);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = textsize;
+ int r = MAX(MAX((blt.getTextHeight(getName(), &fontInfo)*11)/10,minh),4);
+ return r;
+ }
+ return MAX(normalbmp.getHeight(),minh);
+}
+
+void ButtonWnd::enableButton(int _enabled) {
+ _enabled = !!_enabled;
+ if (enabled != _enabled) invalidate();
+ enabled = _enabled;
+ onEnable(enabled);
+}
+
+int ButtonWnd::getEnabled() const {
+ return enabled;
+}
+
+int ButtonWnd::onPaint(Canvas *canvas)
+{
+ PaintBltCanvas paintcanvas;
+ SkinBitmap *bmp;
+ RECT r;
+ int labelxoffs=0;
+ int offset = (enabled&&(getPushed()||getDown())) ? 1 : 0;
+
+ if (checked) labelxoffs+=3+checkbmp.getWidth();
+
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ BUTTONWND_PARENT::onPaint(canvas);
+
+ bmp = normalbmp;
+ if (pushedbmp && (getDown() || getPushed())) bmp = pushedbmp;
+ else if ((getHilite() || userhilite) && hilitebmp) bmp = hilitebmp;
+ else if (activatedbmp && getActivatedButton()) bmp = activatedbmp;
+
+ getClientRect(&r);
+
+ RECT nr = r;
+// RECT fcr = r;
+ if (use_base_texture)
+ {
+ if (!base_texture)
+ renderBaseTexture(canvas, r);
+ else {
+ RECT cr;
+ cr.left = xShift;
+ cr.top = yShift;
+ cr.right = cr.left + (r.right-r.left);
+ cr.bottom = cr.top + (r.bottom-r.top);
+ if (tile_base_texture) base_texture->blitTile(canvas, &r,xShift,yShift);
+ else base_texture->stretchToRectAlpha(canvas, &cr, &r, getPaintingAlpha());
+ }
+ }
+ else
+ {
+ if (borders)
+ {
+ int sysobj = -1;
+ if (!enabled)
+ sysobj = dsoDisabled;
+ else
+ sysobj = (getPushed() || getDown()) ? dsoPushed : dsoNormal;
+ if (sysobj != -1) canvas->drawSysObject(&nr, sysobj, getPaintingAlpha());
+ }
+ }
+
+ if (checked>0)
+ {
+ RECT ar;
+ int c=(r.top+r.bottom)/2;
+ ar.left=r.left;
+ ar.top=c-checkbmp.getHeight()/2;
+ ar.bottom=ar.top+checkbmp.getHeight();
+ ar.right=r.left+checkbmp.getWidth();
+ checkbmp.getBitmap()->stretchToRectAlpha(canvas,&ar,getPaintingAlpha());
+ }
+ if (rightbmp.getBitmap()) {
+ RECT ar;
+ int c=(r.top+r.bottom)/2;
+ ar.top=c-rightbmp.getHeight()/2;
+ ar.bottom=ar.top+rightbmp.getHeight();
+ ar.right=r.right;
+ ar.left=ar.right-rightbmp.getWidth();
+
+ int alpha = getPaintingAlpha();
+ if (!getEnabled()) alpha /= 2;
+ rightbmp.getBitmap()->stretchToRectAlpha(canvas, &ar, alpha);
+ }
+
+ if (bmp != NULL) {
+ RECT br = r;
+ if (center_bitmap) {
+ int w = (r.right - r.left) - getWidth() - labelxoffs;
+ int h = (r.bottom - r.top) - getHeight();
+ br.top = r.top + h/2 + offset;
+ br.bottom = br.top + getHeight();
+ br.left = r.left + w/2 + labelxoffs + offset;
+ br.right = br.left + getWidth() - (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
+ } else {
+ br.left += labelxoffs;
+ br.right -= (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
+ }
+ int alpha2;
+ if (!hilitebmp && enabled && autodim) {
+ alpha2=128;
+ if (getHilite() || userhilite) alpha2=255;
+ } else alpha2 = enabled ? 255 : 64;
+ bmp->stretchToRectAlpha(canvas, &br,autodim ? (getPaintingAlpha()+alpha2)>>1 : getPaintingAlpha());
+ }
+
+ if (getName() != NULL)
+ {
+ Wasabi::FontInfo fontInfo;
+ fontInfo.opaque = false;
+ fontInfo.pointSize = textsize;;
+
+ int textw, texth;
+ canvas->getTextExtent(getName(), &textw, &texth, &fontInfo);
+
+ if (!enabled)
+ fontInfo.color = color_dimmed;
+ else if (userhilite)
+ fontInfo.color = color_hilite;
+ else
+ fontInfo.color = color_text;
+ int h=(r.bottom-r.top-texth)/2;
+ if (h<0) h=0;
+
+ r.left += offset + labelxoffs;
+ r.right += offset - (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
+ r.top += offset+h;
+ r.bottom = r.top+texth;
+
+ switch (alignment)
+ {
+ case TEXTALIGN_CENTER:
+ canvas->textOutCentered(&r, getName(), &fontInfo);
+ break;
+
+ case TEXTALIGN_RIGHT:
+ canvas->textOut(r.right-textw, r.top, textw, texth, getName(), &fontInfo);
+ break;
+
+ case TEXTALIGN_LEFT:
+ if (!wcsstr(getName(), L"\t"))
+ {
+ canvas->textOut(r.left, r.top, r.right-r.left, r.bottom-r.top, getName(), &fontInfo);
+ }
+ else
+ {
+ StringW lstr(getName());
+ wchar_t *p=wcsstr(lstr.getNonConstVal(),L"\t");
+ if (p) *p++=0;
+ else p=L"";
+ int tw=canvas->getTextWidth(p, &fontInfo);
+ canvas->textOut(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr, &fontInfo);
+ canvas->textOut(r.right-tw, r.top, tw, r.bottom-r.top, p, &fontInfo);
+ }
+ break;
+
+ case TEXTALIGN_LEFT_ELLIPSIS:
+ if (!wcsstr(getName(),L"\t"))
+ {
+ canvas->textOutEllipsed(r.left, r.top, r.right-r.left, r.bottom-r.top, getName(), &fontInfo);
+ }
+ else
+ {
+ StringW lstr(getName());
+ wchar_t *p=wcsstr(lstr.getNonConstVal(),L"\t");
+ if (p) *p++=0;
+ else p=L"";
+ int tw=canvas->getTextWidth(p, &fontInfo);
+ canvas->textOutEllipsed(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr, &fontInfo);
+ canvas->textOutEllipsed(r.right-tw, r.top, tw, r.bottom-r.top, p, &fontInfo);
+ }
+ break;
+ }
+/*
+ if (textjustify == BUTTONJUSTIFY_CENTER)
+ canvas->textOutCentered(&r, getName());
+ else if (textjustify == BUTTONJUSTIFY_LEFT)
+ {
+ if (!STRSTR(getName(),"\t"))
+ canvas->textOutEllipsed(r.left, r.top, r.right-r.left, r.bottom-r.top, getName());
+ else
+ {
+ char *lstr=STRDUP(getName());
+ char *p=STRSTR(lstr,"\t");
+ if (p) *p++=0;
+ else p="";
+ int tw=canvas->getTextWidth(p);
+ canvas->textOutEllipsed(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr);
+ canvas->textOutEllipsed(r.right-tw, r.top, tw, r.bottom-r.top, p);
+ FREE(lstr);
+ }
+ }
+*/
+ }
+
+
+/* if (enabled && gotFocus() && wantFocus()) { // SKIN ME
+ fcr.left+=3;
+ fcr.right-=3;
+ fcr.top+=3;
+ fcr.bottom-=3;
+ DrawFocusRect(canvas->getHDC(), &fcr);
+ }*/
+
+ return 1;
+}
+
+void ButtonWnd::onLeftPush(int x, int y)
+{
+ notifyParent(ChildNotify::BUTTON_LEFTPUSH);
+ invalidate();
+}
+void ButtonWnd::onRightPush(int x, int y) {
+ notifyParent(ChildNotify::BUTTON_RIGHTPUSH);
+ invalidate();
+}
+void ButtonWnd::onLeftDoubleClick(int x, int y) {
+ notifyParent(ChildNotify::BUTTON_LEFTDOUBLECLICK);
+}
+void ButtonWnd::onRightDoubleClick(int x, int y) {
+ notifyParent(ChildNotify::BUTTON_RIGHTDOUBLECLICK);
+}
+
+void ButtonWnd::setHilite(int h) {
+ h = !!h;
+ if (userhilite != h) {
+ userhilite = h;
+ invalidate();
+ }
+}
+
+int ButtonWnd::getHilite() {
+ return userhilite || BUTTONWND_PARENT::getHilite();
+}
+
+int ButtonWnd::getPushed() const {
+ return userdown || forcedown;
+}
+
+void ButtonWnd::setPushed(int p) {
+ p = !!p;
+ if (userdown != p)
+ {
+ userdown=p;
+ invalidate();
+ }
+}
+
+int ButtonWnd::onResize() {
+ BUTTONWND_PARENT::onResize();
+// invalidate();
+ return 1;
+}
+
+void ButtonWnd::setCheckBitmap(const wchar_t *checkbm) {
+ checkbmp = checkbm;
+}
+
+int ButtonWnd::setRightBitmap(const wchar_t *bitmap) {
+ rightbmp=bitmap;
+ return 1;
+}
+
+void ButtonWnd::setActivatedButton(int a) {
+ if (activated != a) {
+ activated = a;
+ invalidate();
+ onActivateButton(activated);
+ }
+}
+
+void ButtonWnd::setActivatedNoCallback(int a) {
+ // also force invalidate.
+ activated = a;
+ invalidate();
+}
+
+int ButtonWnd::onActivateButton(int active) {
+ return 1;
+}
+
+int ButtonWnd::getActivatedButton() {
+ return activated;
+}
+
+void ButtonWnd::setBorders(int b) {
+ b = !!b;
+ if (borders != b) {
+ borders = b;
+ setRectRgn(borders);
+ invalidate();
+ }
+}
+
+void ButtonWnd::setBorderStyle(const wchar_t *style) {
+ if (style == NULL) style = L"";
+ if (borderstyle && !WCSICMP(borderstyle, style)) return;
+
+// borderstyle = style;
+
+ using namespace DrawSysObj;
+ static struct {
+ const wchar_t *style;
+ int normal, pushed, disabled;
+ } chart[] = {
+ { L"button_normal", BUTTON, BUTTON_PUSHED, BUTTON_DISABLED },
+ { L"osbutton_normal", OSBUTTON, OSBUTTON_PUSHED, OSBUTTON_DISABLED },
+ { L"osbutton_close", OSBUTTON_CLOSE, OSBUTTON_CLOSE_PUSHED, OSBUTTON_CLOSE_DISABLED },
+ { L"osbutton_minimize", OSBUTTON_MINIMIZE, OSBUTTON_MINIMIZE_PUSHED, OSBUTTON_MINIMIZE_DISABLED },
+ { L"osbutton_maximize", OSBUTTON_MAXIMIZE, OSBUTTON_MAXIMIZE_PUSHED, OSBUTTON_MAXIMIZE_DISABLED },
+ { NULL, BUTTON, BUTTON_PUSHED, BUTTON_DISABLED },
+ };
+ dsoNormal = dsoPushed = dsoDisabled = -1;
+ for (int i = 0; ; i++) {
+ if (chart[i].style == NULL) return;
+ if (!WCSICMP(chart[i].style, style)) {
+ borderstyle = chart[i].style;
+ dsoNormal = chart[i].normal;
+ dsoPushed = chart[i].pushed;
+ dsoDisabled = chart[i].disabled;
+ }
+ }
+
+ invalidate();
+}
+
+const wchar_t *ButtonWnd::getBorderStyle() {
+ return borderstyle;
+}
+
+void ButtonWnd::setInactiveAlpha(int a) {
+ inactivealpha=a;
+}
+
+void ButtonWnd::setActiveAlpha(int a) {
+ activealpha=a;
+}
+
+int ButtonWnd::onGetFocus() {
+ BUTTONWND_PARENT::onGetFocus();
+// invalidate();
+ return 1;
+}
+
+int ButtonWnd::onKillFocus() {
+ BUTTONWND_PARENT::onKillFocus();
+// invalidate();
+ return 1;
+}
+
+void ButtonWnd::setColors(const wchar_t *text, const wchar_t *hilite, const wchar_t *dimmed) {
+ color_text=text;
+ color_hilite=hilite;
+ color_dimmed=dimmed;
+ invalidate();
+}
+
+void ButtonWnd::setTextColor(const wchar_t *text) {
+ color_text=text;
+ invalidate();
+}
+
+void ButtonWnd::setTextHoverColor(const wchar_t *hilite) {
+ color_hilite=hilite;
+ invalidate();
+}
+
+void ButtonWnd::setTextDimmedColor(const wchar_t *dimmed) {
+ color_dimmed=dimmed;
+ invalidate();
+}
+
+int ButtonWnd::onEnable(int is) {
+ return BUTTONWND_PARENT::onEnable(is);
+}
+
+int ButtonWnd::getPreferences(int what) {
+ switch (what) {
+ case SUGGESTED_W: {
+ if (!normalBmpStr.isempty()) return normalbmp.getWidth();
+ return getWidth();
+ }
+ case SUGGESTED_H: {
+ if (!normalBmpStr.isempty()) return normalbmp.getHeight();
+ return getHeight();
+ }
+ }
+ return BUTTONWND_PARENT::getPreferences(what);
+}
+
+int ButtonWnd::onInit() {
+ int r = BUTTONWND_PARENT::onInit();
+ currgn = normalrgn;
+ return r;
+}
+
+int ButtonWnd::onChar(unsigned int c)
+{
+ switch (c) {
+#ifdef _WIN32
+ case VK_RETURN:
+ case VK_SPACE:
+ postDeferredCallback(DEFEREDCB_DOWN, 0, 0);
+ postDeferredCallback(DEFEREDCB_UP, 0, 250);
+ //return BUTTONWND_PARENT::onChar(c);
+ break;
+#else
+#warning port me
+#endif
+ default:
+ return BUTTONWND_PARENT::onChar(c);
+ }
+ return 1;
+}
+
+
+int ButtonWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ switch (p1) {
+ case DEFEREDCB_DOWN:
+ forcedown = 1;
+ invalidate();
+ break;
+ case DEFEREDCB_UP:
+ forcedown = 0;
+ invalidate();
+ RECT r;
+ getClientRect(&r);
+ onLeftPush(r.left+(r.right-r.left)/2, r.top+(r.bottom-r.top)/2);
+ default:
+ return BUTTONWND_PARENT::onDeferredCallback(p1, p2);
+ }
+ return 1;
+}
+
+
diff --git a/Src/Wasabi/api/wnd/wndclass/buttwnd.h b/Src/Wasabi/api/wnd/wndclass/buttwnd.h
new file mode 100644
index 00000000..d0367573
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/buttwnd.h
@@ -0,0 +1,602 @@
+#ifndef _BUTTWND_H
+#define _BUTTWND_H
+
+#include <wasabicfg.h>
+
+#include <bfc/common.h>
+#include <tataki/canvas/canvas.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <tataki/color/skinclr.h>
+#include <api/wnd/accessible.h>
+#include <api/wnd/textalign.h>
+
+class api_region;
+
+#define DEFAULT_BUTTON_TEXT_SIZE 14
+/**
+ Button Text Alignment
+ Darkain: this was changed to use TextAlign
+*/
+/*
+typedef enum {
+ BUTTONJUSTIFY_LEFT,
+ BUTTONJUSTIFY_CENTER
+} ButtonJustify;
+*/
+
+#define DEFEREDCB_DOWN 0x450
+#define DEFEREDCB_UP 0x451
+
+#define BUTTONWND_PARENT GuiObjectWnd
+
+/**
+ A fully skinnable button. Has images for normal, hilited, activated states.
+ Plus images for a checked state. It may also be used to draw OS style buttons.
+ See setBorderStyle() for more details.
+
+ @short Button control.
+ @author Nullsoft
+ @ver 1.0
+ @see ButtBar
+*/
+class ButtonWnd : public BUTTONWND_PARENT {
+public:
+ /**
+ Sets defaults for ButtonWnd objects.
+
+ @see ~ButtonWnd()
+ @param button_text The button's caption.
+ */
+ ButtonWnd(const wchar_t *button_text=NULL);
+
+ /**
+ Deletes components of ButtonWnd.
+
+ @see ButtonWnd()
+ */
+ virtual ~ButtonWnd();
+
+ /**
+ Paints the bitmap on canvas according
+ to current options (centering, tiling, stretching, title).
+
+ @ret 0 for failure, 1 for success
+ @param canvas The canvas on which to paint.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ Sets the bitmaps that will be used to render the button.
+ This includes bitmaps for various button states. Also enables
+ you to set the colorgroup (gammagroup) for the bitmaps.
+
+ @ret 1
+ @param _normal Bitmap for normal state.
+ @param _pushed Bitmap for pushed state.
+ @param _hilited Bitmap for hilited state.
+ @param _activated Bitmap for activated state.
+ @param colorgroup The colorgroup for the bitmaps (gammagroup).
+ */
+ int setBitmaps(const wchar_t *normal, const wchar_t *pushed=NULL, const wchar_t *hilited=NULL, const wchar_t *activated=NULL);
+
+ SkinBitmap *getNormalBitmap();
+
+ /**
+ Sets the bitmaps that will be used to render the button.
+ This includes bitmaps for various button states. Also enables
+ you to set the colorgroup (gammagroup) for the bitmaps.
+
+ @ret 1
+ @param hInst The parent window's instance handle.
+ @param _normal Bitmap for normal state.
+ @param _pushed Bitmap for pushed state.
+ @param _hilited Bitmap for hilited state.
+ @param _activated Bitmap for activated state.
+ @param colorgroup The colorgroup for the bitmaps (gammagroup).
+ */
+ int setBitmaps(OSMODULEHANDLE hInst, int normal, int pushed, int hilited, int activated, const wchar_t *colorgroup=NULL);
+
+ /**
+ Set the right bitmap to be used.
+
+ @see setBitmaps()
+ @ret 1
+ @param bitmap The name of the bitmap to use.
+ */
+ int setRightBitmap(const wchar_t *bitmap);
+
+ /**
+ Center the bitmap?
+
+ @see setBitmaps()
+ @ret Normalized flag
+ @param centerit A non zero value will center the bitmap.
+ */
+ int setBitmapCenter(int centerit);
+
+ /**
+ Sets base texture and causes rerendering.
+
+ @see setBaseTexture()
+ @param useit A non zero value will use the base texture.
+ */
+ void setUseBaseTexture(int useit);
+
+ /**
+ Sets bitmap for button, sets position for button, flags whether to tile the bitmap
+
+ @see setUseBaseTexture()
+ @param bmp Skin bitmap for button
+ @param x Button position on x-coordinate
+ @param yButton position on y-coordinate
+ @param tile Flag
+ */
+ void setBaseTexture(SkinBitmap *bmp, int x, int y, int tile=0);
+
+ /**
+ Sets the colorgroup (gammagroup) for all the bitmaps associated with
+ this button.
+
+ @param _colorgroup The colorgroup for the bitmaps.
+ */
+ void setHInstanceColorGroup(const wchar_t *_colorgroup) { colorgroup = _colorgroup; }
+
+ /**
+ Writes given text to button in given size and triggers rendering.
+
+ @see getButtonText()
+ @assert Text string is not empty
+ @ret 1
+ @param text Label text
+ @param size Size to render label text
+ */
+ int setButtonText(const wchar_t *text, int size=DEFAULT_BUTTON_TEXT_SIZE);
+
+ /**
+ Gets text from button.
+
+ @see setButtonText()
+ @ret Button text string
+ */
+ const wchar_t * getButtonText();
+
+ /**
+ Sets text to render at left, in center, or at right.
+
+ @see setButtonText()
+ @see getButtonText()
+ @see ButtonJustify
+ @param jus BUTTONJUSTIFY_LEFT, left justified; BUTTONJUSTIFY_CENTER, centered;
+ */
+// void setTextJustification(ButtonJustify jus);
+ void setTextAlign(TextAlign align);
+
+ TextAlign getTextAlign() { return alignment; }
+
+ /**
+ Enables and disables wantfocus for the button. When disabled, the button can
+ never receive focus.
+
+ @param want !0, enable focus; 0, disable focus;
+ */
+ void setWantFocus(int want) { iwantfocus = !!want; }
+
+ /**
+ Return the wantfocus
+ */
+ virtual int wantFocus() const { return iwantfocus; }
+
+ /**
+ Event is triggered when the mouse leaves the button's region.
+ Override this event to implement your own behavior.
+ */
+ virtual void onLeaveArea();
+ virtual void onEnterArea();
+
+ /**
+ Gets width of button, allowing for length of text plus button margin, if any.
+
+ @see getHeight()
+ @ret Button width (in pixels).
+ */
+ int getWidth(); // our preferred width and height (from bitmaps)
+
+ /**
+ Gets height of button, allowing for height of text plus button margin, if any.
+
+ @see getWidth()
+ @ret Button height (in pixels).
+ */
+ int getHeight();
+
+ /**
+ Event is triggered when focus is given to the button.
+ Override this event to implement your own behavior.
+
+ @see onKillFocus()
+ @ret 1
+ */
+ virtual int onGetFocus();
+
+ /**
+ Event is triggered when the button focus is lost.
+ Override this event to implement your own behavior.
+
+ @see onGetFocus()
+ @ret 1
+ */
+ virtual int onKillFocus();
+
+ /**
+ Event is triggered when a key is pressed and the button
+ has focus.
+
+ @ret 1, if you handle the event;
+ @param c The value of the key that was pressed.
+ */
+ virtual int onChar(unsigned int c);
+
+ /**
+ Saves new status and rerenders, if button enabled status changes.
+
+ @see getEnabled()
+ @see onEnable()
+ @param _enabled 0, disabled; !0 enabled;
+ */
+ void enableButton(int enabled); // can be pushed
+
+ /**
+ Tells parent to handle left button click.
+
+ @see onRightPush()
+ @param x Mouse click x-coordinate
+ @param y Mouse click y-coordinate
+ */
+ virtual void onLeftPush(int x, int y);
+
+ /**
+ Passes right mouse clicks to the parent.
+
+ @see onLeftPush()
+ @param x Mouse click x-coordinate
+ @param y Mouse click y-coordinate
+ */
+ virtual void onRightPush(int x, int y);
+
+ /**
+ Passes left double click to parent.
+
+ @see onRightDoubleClick()
+ @param x Mouse click x-coordinate
+ @param y Mouse click y-coordinate
+ */
+ virtual void onLeftDoubleClick(int x, int y);
+
+ /**
+ Passes right double click to parent
+
+ @see onLeftDoubleClick()
+ @param x Mouse click x-coordinate
+ @param y Mouse click y-coordinate
+ */
+ virtual void onRightDoubleClick(int x, int y);
+
+ /**
+ Event is triggered when the button will be resized.
+ Override this event to implement your own behavior.
+
+ The default behavior is to cause a repaint.
+
+ @ret 1
+ */
+ virtual int onResize();
+
+ /**
+ Sets the region pointed at after each mouse move.
+ If the region has changed, it invalidate the region
+ so that it will be updated on the screen.
+
+ @ret Status from parent class
+ @param x New x-coordinate of mouse cursor
+ @param y New y-coordinate of mouse cursor
+ */
+ virtual int onMouseMove(int x, int y); // need to catch region changes
+
+ /**
+ Event is triggered when the button is enabled or disabled.
+ Override this event to implement your own behavior.
+
+ @see getEnabled()
+ @ret 1
+ @param is The enable state (nonzero is enabled).
+ */
+ virtual int onEnable(int is);
+
+ /**
+ Returns the value of the enabled flag.
+
+ @see enableButton()
+ @see onEnable()
+ @ret enabled
+ */
+ virtual int getEnabled() const;
+
+ /**
+ Get the preferences for this button.
+ This will enable you to read the suggested width and height
+ for the button.
+
+ @ret Width or height of the normal bitmap, as requested, or a property from the parent class.
+ @param what SUGGESTED_W, will return the width; SUGGESTED_H, will return the height;
+ */
+ virtual int getPreferences(int what);
+
+ /**
+ Get the button state. This is the state caused by user interaction.
+
+ @ret !0, pushed; 0, not pushed;
+ */
+ virtual int userDown() { return userdown; }
+
+ /**
+
+ */
+ virtual int wantClicks() { return getEnabled(); }
+
+ /**
+ Set the bitmap to use when the button will be "checked".
+ This enables you to have checked buttons and menu items.
+
+ @see setChecked()
+ @see getChecked()
+ @param checkbm The name of the bitmap to use.
+ */
+ void setCheckBitmap(const wchar_t *checkbm);
+
+ /**
+ Set the checked state of the button.
+
+ @param c <0, not checked; 0, none, >0 checked;
+ */
+ void setChecked(int c) { checked=c; }; // <0=nocheck, 0=none, >0=checked
+
+ /**
+ Get the checked state of the button.
+
+ @ret <0, not checked; 0, none; >0 checked;
+ */
+ int getChecked() const { return checked; }
+
+ /**
+ Triggers rerendering in the opposite
+ highlight state if the hilighting flag is changed.
+
+ @see getHilite()
+ @param h
+ */
+ void setHilite(int h);
+
+ /**
+
+
+ @see setHilite()
+ @ret Is either highlighting flag set?
+ */
+ int getHilite();
+
+ /**
+ Simulate a button push. You can use this method to simulate
+ menu pushing also.
+
+ @see getPushed()
+ @param p A nonzero value will simulate a push.
+ */
+ void setPushed(int p); // used by menus to simulate pushing
+
+ /**
+ Get the pushed state of a button.
+
+ @see setPushed()
+ @ret 0, not pushed; !0, pushed;
+ */
+ int getPushed() const; // used by menus to simulate pushing
+
+ /**
+ Sets the auto dim state. Autodim will dim the normal
+ bitmap if no hilite bitmap is provided.
+
+ @param ad !0, autodim on; 0, autodim off;
+ */
+ void setAutoDim(int ad) { autodim=!!ad; } // nonzero makes it dim if there's no hilite bitmap
+
+ /**
+ Get the autodim state.
+
+ @see setAutoDim()
+ @ret 0, autodim off; !0 autodim on;
+ */
+ int getAutoDim() const { return autodim; } // nonzero makes it dim if there's no hilite bitmap
+
+ /**
+ Set the active state of the button.
+
+ @see getActivatedButton()
+ @see setActivatedNoCallback()
+ @param a !0, activate the button; 0, deactivate the button;
+ */
+ virtual void setActivatedButton(int a);
+
+ /**
+ Set the active state of the button, without generating a callback.
+ This means that the onActivated event will not fire for this button.
+
+ @see getActivatedButton()
+ @see setActivatedButton()
+ @param a !0, activate the button; 0, deactivate the button;
+ */
+ virtual void setActivatedNoCallback(int a);
+
+ /**
+ Get the active state of the button.
+
+ @see setActivatedButton()
+ @ret activated !0, active; 0, inactive;
+ */
+ virtual int getActivatedButton();
+
+ /**
+ Render borders around the button?
+
+ @param b !0, borders; 0, no borders;
+ */
+ void setBorders(int b);
+
+ /**
+ Sets the border style for the button. This
+ has no effect if no borders are being drawn.
+
+ "button_normal" A normal button.
+ "osbutton_normal" A normal OS button (if in Windows, will show a std win32 button).
+ "osbutton_close" An OS close button.
+ "osbutton_minimize" An OS minimize button.
+ "osbutton_maximize" An OS maximize button.
+
+ @see getBorderStyle()
+ @param style The style of button you want.
+ */
+ void setBorderStyle(const wchar_t *style);
+
+ /**
+ Get the border style of the button (if there is one).
+ If no border is drawn, this method always returns NULL.
+
+ @see setBorderStyle()
+ @ret The border style.
+ */
+ const wchar_t *getBorderStyle();
+
+ /**
+ Set the inactive alpha blending value. This is the alpha blending
+ value that will be used for blending when the button does NOT have focus.
+
+ @param a The alpha value, range is from 0 (fully transparent) to 255 (fully opaque).
+ */
+ void setInactiveAlpha(int a);
+
+ /**
+ Set the active alpha blending value. This is the alpha blending value
+ that will be used for blending when the button HAS focus.
+
+ @param a The alpha value, range is from 0 (fully transparent) to 255 (fully opaque).
+ */
+ void setActiveAlpha(int a);
+
+ /**
+ Sets the colors for various states of our button. This is
+ done via element id's which are in the skin xml or registered
+ as seperate xml.
+
+ @param text Normal text color (window has focus but button is not active).
+ @param hilite Hilited text color (button has focus).
+ @param dimmed Dimmed text color (parent window doesn't even have focus).
+ */
+ void setColors(const wchar_t *text=L"studio.button.text", const wchar_t *hilite=L"studio.button.hiliteText", const wchar_t *dimmed=L"studio.button.dimmedText");
+
+ /**
+ Deletes the regions and resets them to NULL.
+
+ @see reloadResources()
+ */
+ virtual void freeResources();
+
+ /**
+ Reinitializes regions for which there are bitmaps available.
+
+ @see freeResources()
+ */
+ virtual void reloadResources();
+
+ /**
+ Event is triggered when the is being activated.
+ Override this event to implement your own behavior.
+
+ @see setActivatedButton()
+ @ret 1
+ @param active The button's state (nonzero is active).
+ */
+ virtual int onActivateButton(int active);
+
+ /**
+ Returns the current region of the button.
+
+ @see api_region
+ @ret The region of the button.
+ */
+ virtual api_region *getRegion();
+
+ /**
+ Set the modal return. This is what will be returned
+ when the window is closed and the window is set to modal.
+
+ @param r The return code you wish to set.
+ */
+ virtual void setModalRetCode(int r);
+
+ /**
+ Get the modal return code for the window.
+
+ @ret The modal return code.
+ */
+ virtual int getModalRetCode() const;
+
+ /**
+ Event is triggered when the button is about to be initialized.
+ Override this event to implement your own behavior.
+
+ @ret 1
+ */
+ virtual int onInit();
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ virtual void setTextColor(const wchar_t *text);
+ virtual void setTextHoverColor(const wchar_t *text);
+ virtual void setTextDimmedColor(const wchar_t *text);
+
+ virtual void checkState(POINT *pt=NULL);
+ virtual void onCancelCapture();
+
+private:
+ AutoSkinBitmap normalbmp, pushedbmp, hilitebmp, checkbmp, rightbmp, activatedbmp;
+ SkinBitmap *base_texture;
+ RegionI *normalrgn, *pushedrgn, *hirgn, *currgn, *activatedrgn;
+ int textsize;
+ TextAlign alignment;
+ SkinColor color_text, color_hilite, color_dimmed;
+ int retcode;
+
+ StringW normalBmpStr, pushedBmpStr, hilitedBmpStr, activatedBmpStr;
+
+ int folderstyle;
+ int autodim;
+ int userhilite;
+ int userdown;
+ int activated;
+ int enabled;
+ int borders;
+ const wchar_t *borderstyle;
+ int dsoNormal, dsoPushed, dsoDisabled;
+
+ int iwantfocus;
+ int center_bitmap;
+ int use_base_texture;
+
+ int checked;
+ int xShift, yShift, tile_base_texture;
+
+ int inactivealpha, activealpha;
+ StringW colorgroup;
+ int forcedown;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/clickwnd.cpp b/Src/Wasabi/api/wnd/wndclass/clickwnd.cpp
new file mode 100644
index 00000000..054915a2
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/clickwnd.cpp
@@ -0,0 +1,319 @@
+#include "precomp.h"
+#include <api/wnd/api_wnd.h>
+
+#include "clickwnd.h"
+#include <api/wnd/notifmsg.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+
+enum
+{
+ CLICKWND_LBUTTONDOWN = 0,
+ CLICKWND_LBUTTONUP,
+ CLICKWND_RBUTTONDOWN,
+ CLICKWND_RBUTTONUP,
+};
+
+ClickWnd::ClickWnd()
+{
+ handleRight = TRUE;
+ button = -1;
+ mousedown = 0;
+ mcaptured = 0;
+ hilite = 0;
+ down = 0;
+ areacheck = 0;
+}
+
+ClickWnd::~ClickWnd()
+{
+ BaseWnd::hintDestroying(); // so basewnd doesn't call onCancelCapture
+ if (getCapture()) endCapture();
+}
+
+void ClickWnd::setHandleRightClick(int tf)
+{
+ handleRight=tf;
+}
+
+int ClickWnd::getHandleRightClick()
+{
+ return handleRight;
+}
+
+int ClickWnd::onLeftButtonDown(int x, int y)
+{
+ notifyParent(ChildNotify::CLICKWND_LEFTDOWN, x, y);
+ CLICKWND_PARENT::onLeftButtonDown(x, y);
+ abortTip();
+#ifdef _WIN32
+ ifc_window *dp = getDesktopParent();
+ if (dp != NULL)
+ {
+ if (dp->wantActivation())
+ {
+ SetActiveWindow(getRootParent()->gethWnd());
+ SetFocus(getRootParent()->gethWnd());
+ }
+ else
+ {
+ HWND w = dp->gethWnd();
+ HWND owner = GetWindow(w, GW_OWNER);
+ if (owner != NULL) {
+ SetActiveWindow(owner);
+ SetFocus(owner);
+ }
+ }
+ }
+ else
+ {
+ SetActiveWindow(getRootParent()->gethWnd());
+ }
+#else
+#warning port me or remove me
+#endif
+ if (ptInRegion(x, y))
+ return onButtonDown(CLICKWND_LBUTTONDOWN, x, y);
+ else
+ return 1;
+}
+
+int ClickWnd::onRightButtonDown(int x, int y)
+{
+ notifyParent(ChildNotify::CLICKWND_RIGHTDOWN, x, y);
+ CLICKWND_PARENT::onRightButtonDown(x, y);
+ abortTip();
+ if (!handleRight) return 1;
+ if (ptInRegion(x, y))
+ return onButtonDown(CLICKWND_RBUTTONDOWN, x, y);
+ else
+ return 1;
+}
+
+int ClickWnd::onLeftButtonUp(int x, int y)
+{
+ notifyParent(ChildNotify::CLICKWND_LEFTUP, x, y);
+ CLICKWND_PARENT::onLeftButtonUp(x, y);
+//jf
+// if (ptInRegion())
+ return onButtonUp(CLICKWND_LBUTTONUP, x, y);
+// else
+// return 1;
+}
+
+int ClickWnd::onRightButtonUp(int x, int y)
+{
+ notifyParent(ChildNotify::CLICKWND_RIGHTUP, x, y);
+ CLICKWND_PARENT::onRightButtonUp(x, y);
+ //jf
+ //if (ptInRegion())
+ if (!handleRight) {
+ onRightPush(x, y);
+ return 1;
+ }
+ return onButtonUp(CLICKWND_RBUTTONUP, x, y);
+// else
+// return 1;
+}
+
+int ClickWnd::onMouseMove(int x, int y)
+{
+ POINT pos, rpos={x,y};
+ int mouseover;
+
+ CLICKWND_PARENT::onMouseMove(x, y);
+
+ pos=rpos;
+ clientToScreen(&pos);
+
+ int lasthilite = hilite;
+
+ mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == static_cast<ifc_window *>(this) && ptInRegion(x, y));
+ if (!mouseover && (!mousedown
+#ifdef _WIN32
+ || !Std::keyDown(button?MK_RBUTTON:MK_LBUTTON)
+#else
+#warning port me
+#endif
+ )) {
+ if (mcaptured || getCapture()) {
+ endCapture();
+ mcaptured = 0;
+ }
+ mousedown = 0;
+ down = 0;
+ if (wantClickWndAutoInvalidate()) invalidate();
+ if (hilite) _onLeaveArea();
+ hilite = 0;
+ return 1;
+ } else if (!mouseover && hilite) {
+ hilite = 0;
+ _onLeaveArea();
+ } else if (mouseover && !hilite) {
+ hilite = 1;
+ _onEnterArea();
+ }
+
+ if (!getCapture() && mouseover) { // capture to see when leave
+ _enterCapture();
+ }
+
+ int lastdown = down;
+ hilite = mouseover;
+#ifdef WASABI_COMPILE_WNDMGR
+ int m = getGuiObject() ? getGuiObject()->guiobject_getMover() : 0;
+#else
+ int m = 0;
+#endif
+ if (!m) {
+ down = userDown() || (mouseover && mousedown);
+ } else
+ down = userDown() || mousedown;
+
+ // FG> note to self now that i finally fixed this... :
+ // there is a potential bottleneck here, if for some reason this test is always true when moving the windows around like crazy.
+ if (down != lastdown || (hilite != lasthilite && !m)) {
+ if (wantClickWndAutoInvalidate()) invalidate();
+ }
+
+//invalidate();
+ return 1;
+}
+
+void ClickWnd::_enterCapture()
+{
+ //gee!! if (!hilite) _onEnterArea();
+ if (!getCapture()) beginCapture();
+ mcaptured = 1;
+}
+
+int ClickWnd::onButtonDown(int which, int x, int y)
+{
+ if (!wantClicks()) return 1;
+
+ if (!getCapture()) {
+ _enterCapture();
+ }
+ mousedown = 1;
+ down = 1;
+ button = -1;
+ if (which == CLICKWND_LBUTTONDOWN) button = 0;
+ else if (which == CLICKWND_RBUTTONDOWN) button = 1;
+ if (wantClickWndAutoInvalidate()) invalidate();
+
+ return 1;
+}
+
+int ClickWnd::onButtonUp(int which, int x, int y)
+{
+ // make sure same button
+ if (button == 0 && which == CLICKWND_RBUTTONUP) return 1;
+ if (button == 1 && which == CLICKWND_LBUTTONUP) return 1;
+
+ if (!down) {
+ if (mcaptured) {
+ endCapture();
+ mcaptured = 0;
+ }
+ if (hilite) _onLeaveArea();
+ hilite = 0;
+ mousedown = 0;
+ return 1;
+ }
+
+ POINT pos={x,y};
+ clientToScreen(&pos);
+
+ int mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y));
+ if (!mouseover) {
+ if (mcaptured) {
+ endCapture();
+ mcaptured = 0;
+ }
+ if (hilite) _onLeaveArea();
+ hilite = 0;
+ }
+
+ // it was down, process the event
+ int a = down;
+ down = 0;
+ mousedown = 0;
+ if (wantClickWndAutoInvalidate()) invalidate();
+
+ if (a) {
+ if (button == 0) onLeftPush(x, y);
+ else if (button == 1) onRightPush(x, y);
+ }
+
+ // we need to do this again (and get the new mouse pos) because onLeft/RightPush may have called a
+ // message loop and let the mouse leave without us being aware of it
+ Wasabi::Std::getMousePos(&x, &y);
+ pos.x = x;
+ pos.y = y;
+ screenToClient(&x, &y);
+ mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y));
+ if (!mouseover && hilite) _onLeaveArea();
+ else if (mouseover && !hilite) _onEnterArea();
+ hilite = mouseover;
+
+ return 1;
+}
+
+void ClickWnd::onSetVisible( int show )
+{
+ CLICKWND_PARENT::onSetVisible( show );
+ if ( !show )
+ {
+ if ( getCapture() )
+ {
+ mcaptured = 0;
+ endCapture();
+ }
+ down = 0;
+ mousedown = 0;
+
+ if ( hilite )
+ _onLeaveArea();
+
+ hilite = 0;
+ }
+}
+
+void ClickWnd::_onEnterArea()
+{
+ if (areacheck == 0) {
+ areacheck++;
+ onEnterArea();
+ } else
+ DebugString("onEnterArea check failed %08X \n", this);
+}
+
+void ClickWnd::_onLeaveArea()
+{
+ if (areacheck == 1) {
+ areacheck--;
+ onLeaveArea();
+ } else
+ DebugString("onLeaveArea check failed %08X\n", this);
+}
+
+void ClickWnd::onEnterArea()
+{
+// DebugString("onEnterArea %08X\n", this);
+}
+
+void ClickWnd::onLeaveArea()
+{
+// DebugString("onLeaveArea %08X\n", this);
+}
+
+void ClickWnd::onCancelCapture()
+{
+ CLICKWND_PARENT::onCancelCapture();
+ mcaptured=0;
+ down = 0;
+ mousedown = 0;
+ if (hilite) _onLeaveArea();
+ hilite = 0;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/clickwnd.h b/Src/Wasabi/api/wnd/wndclass/clickwnd.h
new file mode 100644
index 00000000..101e8445
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/clickwnd.h
@@ -0,0 +1,74 @@
+#ifndef _CLICKWND_H
+#define _CLICKWND_H
+
+// this class defines clicking behavior, i.e. detecting mouse downs and ups
+// and doing captures to determine clicks
+
+#include <bfc/common.h>
+// benski> CUT: #include <api/wnd/wndclass/backbufferwnd.h>
+#include <api/wnd/wndclass/abstractwndhold.h>
+
+#ifdef WASABI_COMPILE_SKIN
+#define CLICKWND_PARENT AbstractWndHolder
+#else
+#define CLICKWND_PARENT ServiceWndHolder
+#endif
+// benski> CUT: #define CLICKWND_PARENT BackBufferWnd
+
+class NOVTABLE ClickWnd : public CLICKWND_PARENT {
+
+public:
+ ClickWnd();
+ virtual ~ClickWnd();
+
+ void setHandleRightClick(int tf);
+ int getHandleRightClick();
+
+ // override these to get clicks!
+ virtual void onLeftPush(int x, int y) {}
+ virtual void onRightPush(int x, int y) {}
+ virtual void onLeftDoubleClick(int x, int y) {}
+ virtual void onRightDoubleClick(int x, int y) {}
+
+ virtual void onEnterArea();
+ virtual void onLeaveArea();
+
+ virtual void onSetVisible(int show);
+ virtual void onCancelCapture();
+ virtual int isInClick() { return mousedown; }
+
+protected:
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onRightButtonDown(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onRightButtonUp(int x, int y);
+ virtual int onMouseMove(int x, int y);
+
+ // override this and return 0 to ignore clicks
+ virtual int wantClicks() { return 1; }
+ // override this and return 1 to force down-ness
+ virtual int userDown() { return 0; }
+
+ virtual int getHilite() { return hilite; } // mouse is over, period
+ virtual int getDown() { return down; } // mouse is over and pushing down
+
+ int onButtonDown(int which, int x, int y);
+ int onButtonUp(int which, int x, int y);
+ void _enterCapture();
+
+ virtual int wantClickWndAutoInvalidate() { return 1; }
+
+private:
+ void _onEnterArea();
+ void _onLeaveArea();
+
+ int button; // 0 == left, 1 == right, which button was pushed
+ int handleRight:1;
+ int mousedown:1;
+ int mcaptured:1; // we are capturing the mouse
+ int hilite:1; // mouse is over but not down
+ int down:1;
+ int areacheck;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/ddrawwnd.cpp b/Src/Wasabi/api/wnd/wndclass/ddrawwnd.cpp
new file mode 100644
index 00000000..d095da03
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/ddrawwnd.cpp
@@ -0,0 +1,219 @@
+#include "precomp.h"
+#include <process.h>
+
+#include "ddrawwnd.h"
+#include "../bfc/canvas.h"
+#include "../bfc/region.h"
+
+DDrawWnd::DDrawWnd() {
+ m_lpDD = NULL;
+ lpClipper = NULL;
+ m_lpRenderSurf = NULL;
+ m_lpPrimSurf = NULL;
+}
+
+DDrawWnd::~DDrawWnd() {
+ deleteFrameBuffer(NULL);
+}
+
+void DDrawWnd::deleteFrameBuffer(Canvas *canvas) {
+ if (m_lpRenderSurf) m_lpRenderSurf->Release();
+ if (m_lpPrimSurf) m_lpPrimSurf->Release();
+ if (lpClipper) lpClipper->Release();
+ if (m_lpDD) m_lpDD->Release();
+ m_lpRenderSurf = NULL;
+ m_lpPrimSurf = NULL;
+ m_lpDD = NULL;
+ lpClipper = NULL;
+ ddlist.removeItem(this);
+}
+
+int DDrawWnd::onInit() {
+ DDRAWWND_PARENT::onInit();
+ if (!allow_dd) return 1;
+ return 1;
+}
+
+Canvas *DDrawWnd::createFrameBuffer(int _w, int _h) {
+
+ if (!allow_dd) return DDRAWWND_PARENT::createFrameBuffer(_w, _h);
+
+ if (virtualCanvas && !m_lpPrimSurf)
+ DDRAWWND_PARENT::deleteFrameBuffer(virtualCanvas);
+
+ deleteFrameBuffer(NULL);
+
+ int resize_h = 8;
+ int resize_w = 8;
+
+ w = _w;
+ h = _h;
+
+ if (DirectDrawCreate(NULL,&m_lpDD,NULL) != DD_OK) {
+ m_lpDD=NULL;
+ MessageBox(gethWnd(),"Error creating ddraw object","DDraw",0);
+ return NULL;
+ }
+
+ int dbl=0;
+
+ m_lpDD->SetCooperativeLevel(gethWnd(), DDSCL_NORMAL);
+ resize_w=(((w>>dbl)+3)&~3);
+// g_noshoww=resize_w-(w>>dbl);
+ resize_h=h>>dbl;
+
+ DDSURFACEDESC DDsd={sizeof(DDsd),};
+
+ DDsd.dwFlags = DDSD_CAPS;
+ DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ if (m_lpDD->CreateSurface(&DDsd, &m_lpPrimSurf, NULL) != DD_OK) {
+ m_lpPrimSurf=0;
+ return NULL;
+ }
+
+ if (m_lpDD->CreateClipper(0, &lpClipper, NULL) != DD_OK ) {
+ m_lpPrimSurf->Release();
+ m_lpPrimSurf=0;
+ return NULL;
+ }
+
+ lpClipper->SetHWnd(0, gethWnd());
+ m_lpPrimSurf->SetClipper(lpClipper);
+
+ DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT;
+ DDsd.dwWidth=resize_w;
+ DDsd.dwHeight=resize_h;
+ DDsd.lPitch=resize_w*sizeof(int);
+ DDsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
+ DDsd.ddpfPixelFormat.dwSize = sizeof(DDsd.ddpfPixelFormat);
+ DDsd.ddpfPixelFormat.dwFlags=DDPF_RGB;
+ DDsd.ddpfPixelFormat.dwRGBBitCount = 32;
+ DDsd.ddpfPixelFormat.dwRBitMask=0xff0000;
+ DDsd.ddpfPixelFormat.dwGBitMask=0x00ff00;
+ DDsd.ddpfPixelFormat.dwBBitMask=0x0000ff;
+ if (m_lpDD->CreateSurface(&DDsd, &m_lpRenderSurf, NULL) != DD_OK) {
+ m_lpRenderSurf->Release();
+ m_lpPrimSurf->Release();
+ lpClipper->Release();
+ m_lpRenderSurf=0;
+ m_lpPrimSurf=0;
+ lpClipper=0;
+ return NULL;
+ }
+ fb_canvas = new DDSurfaceCanvas(m_lpRenderSurf, w, h);
+
+ ddlist.addItem(this);
+
+ if (!thread)
+ startThread();
+
+ return fb_canvas;
+}
+
+int DDrawWnd::virtualBeforePaint(api_region *r) {
+ if (!allow_dd) return DDRAWWND_PARENT::virtualBeforePaint(r);
+ EnterCriticalSection(&DDrawWnd::cs);
+ fb_canvas->enter();
+ return 1;
+}
+
+int DDrawWnd::virtualAfterPaint(api_region *r) {
+ if (!allow_dd) return DDRAWWND_PARENT::virtualAfterPaint(r);
+ fb_canvas->exit();
+ LeaveCriticalSection(&DDrawWnd::cs);
+ return 1;
+}
+
+void DDrawWnd::virtualCanvasCommit(Canvas *canvas, RECT *internalrect, double ra) {
+ if (!allow_dd) { DDRAWWND_PARENT::commitFrameBuffer(canvas, internalrect, ra); return; }
+
+ internalrect->left = MAX(0, (int)internalrect->left);
+ internalrect->top = MAX(0, (int)internalrect->top);
+ internalrect->right = MAX(w, (int)internalrect->right);
+ internalrect->bottom = MAX(h, (int)internalrect->bottom);
+
+ RECT wr;
+ RECT screenrect = *internalrect;
+
+ getWindowRect(&wr);
+ screenrect.left += wr.left;
+ screenrect.top += wr.top;
+ screenrect.right += wr.left;
+ screenrect.bottom += wr.top;
+
+ if (ra == 1.0) {
+ if (m_lpPrimSurf->Blt(&screenrect,m_lpRenderSurf,internalrect,DDBLT_WAIT,NULL) == DDERR_SURFACELOST) {
+ m_lpPrimSurf->Restore();
+ }
+ } else {
+ RECT rcr=screenrect;
+ rcr.left = wr.left + (int)((double)internalrect->left*ra);
+ rcr.top = wr.top + (int)((double)internalrect->top*ra);
+ rcr.right = rcr.left + (int)((double)(internalrect->right-internalrect->left)*ra);
+ rcr.bottom = rcr.top + (int)((double)(internalrect->bottom-internalrect->top)*ra);
+
+ if (m_lpPrimSurf->Blt(&rcr,m_lpRenderSurf,internalrect,DDBLT_WAIT,NULL) == DDERR_SURFACELOST)
+ m_lpPrimSurf->Restore();
+ }
+}
+
+void DDrawWnd::startThread() {
+ DWORD id;
+ quitthread=0;
+ InitializeCriticalSection(&cs);
+ thread = (HANDLE)_beginthreadex(NULL,0,renderThread,0,0,(unsigned int *)&id);
+}
+
+void DDrawWnd::stopThread() {
+ quitthread = 1;
+}
+
+unsigned int WINAPI DDrawWnd::renderThread(void *) {
+ while (!quitthread) {
+ for (int i=0;i<ddlist.getNumItems();i++)
+ ddlist.enumItem(i)->flushPaint();
+ Sleep(MIN(MAX(sleep_val,1),100));
+ }
+ _endthreadex(0);
+ return 1;
+}
+
+void DDrawWnd::invalidate() {
+ if (!allow_dd) { DDRAWWND_PARENT::invalidate(); return; }
+ DDRAWWND_PARENT::deferedInvalidate();
+}
+
+void DDrawWnd::invalidateRect(RECT *r) {
+ if (!allow_dd) { DDRAWWND_PARENT::invalidateRect(r); return; }
+ DDRAWWND_PARENT::deferedInvalidateRect(r);
+}
+
+void DDrawWnd::invalidateRgn(api_region *rgn) {
+ if (!allow_dd) { DDRAWWND_PARENT::invalidateRgn(rgn); return; }
+ DDRAWWND_PARENT::deferedInvalidateRgn(rgn);
+}
+
+void DDrawWnd::validate() {
+ if (!allow_dd) { DDRAWWND_PARENT::validate(); return; }
+ DDRAWWND_PARENT::deferedValidate();
+}
+
+void DDrawWnd::validateRect(RECT *r) {
+ if (!allow_dd) { DDRAWWND_PARENT::validateRect(r); return; }
+ DDRAWWND_PARENT::deferedValidateRect(r);
+}
+
+void DDrawWnd::validateRgn(api_region *rgn) {
+ if (!allow_dd) { DDRAWWND_PARENT::validateRgn(rgn); return; }
+ DDRAWWND_PARENT::deferedValidateRgn(rgn);
+}
+
+
+CRITICAL_SECTION DDrawWnd::cs;
+HANDLE DDrawWnd::thread=NULL;
+int DDrawWnd::quitthread=0;
+PtrList<DDrawWnd> DDrawWnd::ddlist;
+int DDrawWnd::allow_dd = 1;
+int DDrawWnd::sleep_val = 10;
+
+
diff --git a/Src/Wasabi/api/wnd/wndclass/ddrawwnd.h b/Src/Wasabi/api/wnd/wndclass/ddrawwnd.h
new file mode 100644
index 00000000..3863131c
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/ddrawwnd.h
@@ -0,0 +1,60 @@
+#ifndef __DDRAWWND_H
+#define __DDRAWWND_H
+
+#include <ddraw.h>
+#include "../bfc/basewnd.h"
+
+class DDSurfaceCanvas;
+class DDrawWnd;
+class api_region;
+
+#define DDRAWWND_PARENT BaseWnd
+
+class NOVTABLE DDrawWnd : public DDRAWWND_PARENT {
+
+public:
+
+ DDrawWnd();
+ virtual ~DDrawWnd();
+
+ virtual int virtualBeforePaint(api_region *r);
+ virtual int virtualAfterPaint(api_region *r);
+
+ virtual void virtualCanvasCommit(Canvas *canvas, RECT *r, double ratio);
+
+ virtual Canvas *createFrameBuffer(int w, int h);
+ virtual void deleteFrameBuffer(Canvas *canvas);
+
+ virtual int onInit();
+
+ virtual void invalidate();
+ virtual void invalidateRect(RECT *r);
+ virtual void invalidateRgn(api_region *rgn);
+ virtual void validate();
+ virtual void validateRect(RECT *r);
+ virtual void validateRgn(api_region *rgn);
+
+private:
+
+ void initDDraw();
+ void startThread();
+ void stopThread();
+
+ LPDIRECTDRAW m_lpDD;
+ LPDIRECTDRAWSURFACE m_lpRenderSurf, m_lpPrimSurf;
+
+ DDSurfaceCanvas *fb_canvas;
+ int w, h;
+ LPDIRECTDRAWCLIPPER lpClipper;
+ static int allow_dd;
+ static int sleep_val;
+ static CRITICAL_SECTION cs;
+ static HANDLE thread;
+ static int quitthread;
+ static PtrList<DDrawWnd> ddlist;
+
+ static unsigned int WINAPI renderThread(void *);
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/wnd/wndclass/editwnd.cpp b/Src/Wasabi/api/wnd/wndclass/editwnd.cpp
new file mode 100644
index 00000000..8bde39d8
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/editwnd.cpp
@@ -0,0 +1,1001 @@
+#include <precomp.h>
+#include "editwnd.h"
+
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/notifmsg.h>
+
+#include <bfc/assert.h>
+
+#define ID_EDITCHILD 12
+
+enum { IDLETIMER = 8, DELETETIMER = 10 };
+#define IDLETIME 350 // comprimises suck ;)
+
+
+#if UTF8
+#ifdef WANT_UTF8_WARNINGS
+#pragma CHAT("mig", "all", "UTF8 is enabled in editwnd.cpp -- Things might be screwy till it's all debugged?")
+#endif
+# include <bfc/string/encodedstr.h>
+#endif
+
+#ifdef WIN32
+#include <commctrl.h>
+#endif
+
+
+#ifdef WIN32
+static LRESULT CALLBACK static_editWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ EditWnd *editwnd = (EditWnd *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
+ if (editwnd == NULL) return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+ return editwnd->editWndProc(hWnd, uMsg, wParam, lParam);
+}
+#endif
+
+EditWnd::EditWnd(wchar_t *buffer, int buflen)
+{
+ wantfocus = 1;
+ nextenterfaked = 0;
+ idleenabled = 1;
+ beforefirstresize = 1;
+ editWnd = NULL;
+ prevWndProc = NULL;
+ setBuffer(buffer, buflen);
+ maxlen = 0;
+ retcode = EDITWND_RETURN_NOTHING;
+ modal = 0;
+ autoenter = 0;
+ autoselect = 0;
+ outbuf = NULL;
+ // bordered = 0;
+ idletimelen = IDLETIME;
+ multiline = 0;
+ readonly = 0;
+ password = 0;
+ autohscroll = 1;
+ autovscroll = 1;
+ vscroll = 0;
+#ifdef WIN32
+ oldbrush = NULL;
+#endif
+#ifdef LINUX
+ selstart = selend = 0;
+ cursorpos = 0;
+ selectmode = 0;
+ viewstart = 0;
+#endif
+#ifdef WASABI_EDITWND_LISTCOLORS
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.text"))
+ textcolor = L"wasabi.list.text";
+ else
+ textcolor = L"wasabi.edit.text";
+ if (WASABI_API_SKIN->skin_getColorElementRef(L"wasabi.list.background"))
+ backgroundcolor = L"wasabi.list.background";
+ else
+ textcolor.setColor(WASABI_API_SKIN->skin_getBitmapColor(L"wasabi.list.background"));
+#else
+ backgroundcolor = "wasabi.edit.background";
+ textcolor = "wasabi.edit.text";
+#endif
+ selectioncolor = L"wasabi.edit.selection";
+ setVirtual(0);
+}
+
+EditWnd::~EditWnd()
+{
+ killTimer(IDLETIMER);
+#ifdef WIN32
+ if (oldbrush != NULL)
+ DeleteObject(oldbrush);
+ oldbrush = NULL;
+ if (editWnd != NULL)
+ {
+ SetWindowLong(editWnd, GWLP_USERDATA, (LONG_PTR)0);
+ SetWindowLongPtrW(editWnd, GWLP_WNDPROC, (LONG_PTR)prevWndProc);
+ DestroyWindow(editWnd);
+ }
+#endif
+ notifyParent(ChildNotify::RETURN_CODE, retcode);
+}
+
+int EditWnd::onInit()
+{
+ EDITWND_PARENT::onInit();
+
+#ifdef WIN32
+ RECT r = clientRect();
+
+ editWnd = CreateWindowW(L"EDIT", NULL,
+ WS_CHILD
+ | (autohscroll ? ES_AUTOHSCROLL : 0)
+ | (readonly ? ES_READONLY : 0)
+ | (multiline ? ES_MULTILINE : 0)
+ | (password ? ES_PASSWORD : 0)
+ | (autovscroll ? ES_AUTOVSCROLL : 0)
+ | (vscroll ? WS_VSCROLL : 0),
+ r.left, r.top, r.right - r.left, r.bottom - r.top,
+ gethWnd(), (HMENU)ID_EDITCHILD,
+ getOsModuleHandle(), NULL);
+ ASSERT(editWnd != NULL);
+
+ if ((maxlen != 0) && (outbuf != NULL))
+ {
+ setBuffer(outbuf, maxlen);
+ }
+
+ // stash a pointer to us
+ SetWindowLongPtrW(editWnd, GWLP_USERDATA, (LONG_PTR)this);
+ // subclass the edit control -- either by 8 or by 16
+
+ prevWndProc = (WNDPROC)SetWindowLongPtrW(editWnd, GWLP_WNDPROC, (LONG_PTR)static_editWndProc);
+
+
+ SendMessageW(editWnd, WM_SETFONT, (WPARAM)GetStockObject(ANSI_VAR_FONT), FALSE);
+ ShowWindow(editWnd, !getStartHidden() ? SW_NORMAL : SW_HIDE);
+#endif
+
+ return 1;
+}
+
+void EditWnd::onSetVisible(int show)
+{
+ EDITWND_PARENT::onSetVisible(show);
+ if (editWnd == NULL) return ;
+#ifdef WIN32
+ ShowWindow(editWnd, show ? SW_NORMAL : SW_HIDE);
+#endif
+}
+
+int EditWnd::onPaint(Canvas *canvas)
+{
+ // if (!bordered) return EDITWND_PARENT::onPaint(canvas);
+
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ EDITWND_PARENT::onPaint(canvas);
+
+ RECT r;
+ getClientRect(&r);
+ canvas->fillRect(&r, backgroundcolor); //SKIN
+
+#ifdef LINUX
+ char *str = STRDUP((const char *)inbuf + viewstart);
+ canvas->setTextColor(textcolor);
+ canvas->setTextSize(r.bottom - r.top);
+ canvas->setTextOpaque(FALSE);
+ char save;
+ if (selstart != selend)
+ {
+ RECT selrect = r;
+ int start = MAX(MIN(selstart, selend) - viewstart, 0);
+ int end = MAX(MAX(selstart, selend) - viewstart, 0);
+
+ save = str[ start ];
+ str[start] = '\0';
+ selrect.left = r.left + canvas->getTextWidth(str);
+ str[start] = save;
+
+ save = str[ end ];
+ str[end] = '\0';
+ selrect.right = r.left + canvas->getTextWidth(str);
+ str[end] = save;
+
+ canvas->fillRect(&selrect, selectioncolor);
+ }
+
+ save = str[cursorpos - viewstart];
+ str[cursorpos - viewstart] = '\0';
+ RECT cursor = r;
+ cursor.left = cursor.right = r.left + canvas->getTextWidth(str);
+ str[cursorpos - viewstart] = save;
+ canvas->drawRect(&cursor, TRUE, 0xffffff);
+
+ canvas->textOut(r.left, r.top, r.right - r.left, r.bottom - r.top, str);
+
+ FREE(str);
+#endif
+
+ return 1;
+}
+
+int EditWnd::onResize()
+{
+ EDITWND_PARENT::onResize();
+#ifdef WIN32
+ RECT r = clientRect();
+ if (1 /*bordered*/)
+ {
+ r.top++;
+ r.bottom--;
+ r.left++;
+ r.right--;
+ }
+ MoveWindow(editWnd, r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
+
+ if (beforefirstresize)
+ {
+ ShowWindow(editWnd, SW_NORMAL); beforefirstresize = 0;
+ if (modal)
+ {
+ SetFocus(editWnd);
+ if (getAutoSelect())
+ SendMessageW(editWnd, EM_SETSEL, 0, -1);
+ }
+ }
+#endif
+
+ return TRUE;
+}
+
+#ifdef WIN32
+LRESULT EditWnd::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_CTLCOLOREDIT:
+ {
+ HDC hdc = (HDC)wParam;
+ SetTextColor(hdc, textcolor);
+ SetBkColor(hdc, backgroundcolor);
+ if (oldbrush != NULL)
+ {
+ DeleteObject(oldbrush);
+ oldbrush = NULL;
+ }
+ oldbrush = CreateSolidBrush(backgroundcolor);
+ return (LRESULT)oldbrush;
+ }
+
+ case WM_MOUSEACTIVATE:
+ WASABI_API_WND->popupexit_check(this);
+ break;
+
+ case WM_COMMAND:
+ {
+ switch (HIWORD(wParam))
+ {
+ case EN_CHANGE:
+ {
+ if (maxlen > 0)
+ {
+ GetWindowTextW(editWnd, outbuf, maxlen);
+ onEditUpdate();
+ }
+ }
+ break;
+ case EN_SETFOCUS:
+ if (getAutoSelect())
+ SendMessageW(editWnd, EM_SETSEL, (WPARAM)0, (LPARAM) - 1);
+ break;
+ case EN_KILLFOCUS:
+ onLoseFocus();
+ break;
+ }
+ }
+ break;
+ }
+
+ return EDITWND_PARENT::wndProc(hWnd, uMsg, wParam, lParam);
+}
+#endif
+
+void EditWnd::setBuffer(wchar_t *buffer, int len)
+{
+#ifdef LINUX
+ if (buffer == NULL || len <= 1)
+ {
+ inbuf = "";
+ return ;
+ }
+#endif
+ if (buffer == NULL || len <= 1) return ;
+ ASSERT(len > 1);
+ ASSERT(len < 0x7ffe);
+ ASSERT((int)wcslen(buffer) <= len);
+
+#ifdef WIN32
+#define USE_INTERNAL_BUFFER 0
+
+#if USE_INTERNAL_BUFFER
+ buffer8.setSize(len + 1);
+ outbuf = buffer8.getMemory();
+ if (len)
+ {
+ STRNCPY(outbuf, buffer, len);
+ }
+ outbuf[len] = 0;
+#else
+ outbuf = buffer;
+#endif
+
+ if (editWnd != NULL)
+ {
+ SetWindowTextW(editWnd, buffer);
+
+ // This is going to be problematic. This is where utf8 sucks.
+ // Just how many characters CAN we save in our buffer, eh?
+ // (shrug) Oh well. Can't be helped. At most this many.
+ SendMessageW(editWnd, EM_LIMITTEXT, (WPARAM)len - 1, (LPARAM)0);
+ // hooray for halcyon7
+
+ /* if (getAutoSelect()) {
+ SetFocus(editWnd);
+ SendMessageW(editWnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
+ }*/
+ }
+
+ maxlen = len;
+#else
+ outbuf = buffer;
+ maxlen = len;
+ inbuf = buffer;
+ cursorpos = len;
+ invalidate();
+#endif
+}
+
+void EditWnd::selectAll()
+{
+#ifdef WIN32
+ PostMessage(editWnd, EM_SETSEL, 0, -1);
+#else
+ selstart = 0; selend = inbuf.len();
+#endif
+}
+
+void EditWnd::enter()
+{
+ onEnter();
+}
+
+void EditWnd::getBuffer(wchar_t *buf, int _len)
+{
+ if (_len > maxlen) _len = maxlen;
+ // SendMessageW(editWnd, WM_GETTEXT, (WPARAM)_len, (LPARAM)buf);
+ WCSCPYN(buf, outbuf, _len);
+}
+
+void EditWnd::setModal(int _modal)
+{
+ modal = _modal;
+}
+
+void setBorder(int border)
+{
+ // bordered = border;
+}
+
+int EditWnd::isEditorKey(int vk)
+{
+ if (vk >= VK_F1) return 0;
+ if ((vk == VK_UP || vk == VK_DOWN) || ((Std::keyDown(VK_CONTROL) || Std::keyDown(VK_MENU)) && (vk == VK_LEFT || vk == VK_RIGHT)))
+ return 0;
+ if (vk == VK_RETURN && Std::keyDown(VK_CONTROL)) return 0;
+ if (vk == VK_CONTROL || vk == VK_MENU) return 0;
+ return 1;
+}
+
+LRESULT EditWnd::editWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_KEYDOWN:
+ if (!isEditorKey((int)wParam) && !onKeyDown((int)wParam))
+ {
+#ifdef WASABI_COMPILE_WND
+ WASABI_API_WND->forwardOnKeyDown(this, (int) wParam, (int)lParam);
+#endif
+
+ }
+ break;
+ case WM_KEYUP:
+ if (!isEditorKey((int)wParam) && !onKeyUp((int)wParam))
+ {
+#ifdef WASABI_COMPILE_WND
+ WASABI_API_WND->forwardOnKeyUp(this, (int) wParam, (int)lParam);
+#endif
+
+ }
+ break;
+ case WM_CHAR:
+ if (!(wParam == VK_RETURN && nextenterfaked && !autoenter))
+ {
+ notifyParent(ChildNotify::EDITWND_KEY_PRESSED, wParam);
+ onChar((TCHAR)wParam);
+ }
+ if (wParam == VK_RETURN)
+ {
+ if (!(nextenterfaked && !autoenter))
+ if (onEnter()) return 0;
+ nextenterfaked = 0;
+ return 0;
+ }
+ else if (wParam == VK_ESCAPE)
+ {
+ if (onAbort()) return 0;
+ }
+ else if (wParam == VK_TAB && multiline)
+ {
+ return 0;
+ }
+ break;
+ case WM_SETFOCUS:
+ onSetRootFocus(this);
+ // fall thru
+ case WM_KILLFOCUS:
+ invalidate();
+ break;
+ }
+#ifdef WIN32
+ return CallWindowProc(prevWndProc, hWnd, uMsg, wParam, lParam);
+#else
+ DebugString("portme -- EditWnd::editWndProc\n");
+ return 0;
+#endif
+}
+
+void EditWnd::timerCallback(int id)
+{
+ switch (id)
+ {
+ case IDLETIMER:
+ killTimer(IDLETIMER);
+ if (idleenabled) onIdleEditUpdate();
+ break;
+ case DELETETIMER:
+ killTimer(DELETETIMER);
+ delete this;
+ break;
+ default:
+ EDITWND_PARENT::timerCallback(id);
+ }
+}
+
+void EditWnd::onEditUpdate()
+{
+#ifdef LINUX
+ STRNCPY(outbuf, inbuf, maxlen);
+ outbuf[maxlen] = '\0';
+
+ RECT r;
+ getClientRect(&r);
+
+ SysCanvas sysc;
+ sysc.setTextSize(r.bottom - r.top);
+ sysc.getTextWidth(inbuf);
+
+ char *str = STRDUP(inbuf);
+
+ if (cursorpos < viewstart)
+ viewstart = cursorpos;
+
+ char save = str[cursorpos];
+ str[cursorpos] = '\0';
+ while (sysc.getTextWidth(str + viewstart) > r.right - r.left)
+ {
+ viewstart++;
+ }
+ str[cursorpos] = save;
+
+ invalidate();
+#endif
+ killTimer(IDLETIMER);
+ setTimer(IDLETIMER, idletimelen);
+ notifyParent(ChildNotify::EDITWND_DATA_MODIFIED);
+}
+
+void EditWnd::onIdleEditUpdate()
+{
+ notifyParent(ChildNotify::EDITWND_DATA_MODIFIED_ONIDLE);
+}
+
+int EditWnd::onEnter()
+{
+ notifyParent(ChildNotify::EDITWND_ENTER_PRESSED);
+ if (modal)
+ {
+ retcode = EDITWND_RETURN_OK;
+ delete this;
+ //CUT setTimer(DELETETIMER, 1);
+ return 1;
+ }
+ return 0;
+}
+
+int EditWnd::onAbort()
+{
+ notifyParent(ChildNotify::EDITWND_CANCEL_PRESSED);
+ if (modal)
+ {
+ retcode = EDITWND_RETURN_CANCEL;
+ delete this;
+ //CUT setTimer(DELETETIMER, 1);
+ return 1;
+ }
+ return 0;
+}
+
+int EditWnd::onLoseFocus()
+{ // fake an onEnter()
+#ifdef WIN32
+ if (autoenter)
+ {
+ nextenterfaked = 1;
+ PostMessage(editWnd, WM_CHAR, VK_RETURN, 0);
+ }
+#else
+ invalidate();
+ selstart = selend = 0;
+#endif
+ return 0;
+}
+
+void EditWnd::setAutoEnter(int a)
+{
+ autoenter = a;
+}
+
+void EditWnd::setAutoSelect(int a)
+{
+ autoselect = a;
+};
+
+void EditWnd::setIdleTimerLen(int ms)
+{
+ if (ms < 0) ms = 0;
+ idletimelen = ms;
+}
+
+int EditWnd::getTextLength()
+{ // TOTALLY NONPORTABLE AND TOTALLY DIRTY
+#ifdef WIN32
+ HFONT font = (HFONT)SendMessageW(editWnd, WM_GETFONT, 0, 0);
+
+ HDC sdc = GetDC(NULL);
+ HDC dc = CreateCompatibleDC(sdc);
+ ReleaseDC(NULL, sdc);
+
+ HFONT oldfont = (HFONT)SelectObject(dc, font);
+
+ SIZE s;
+ GetTextExtentPoint32W(dc, outbuf, wcslen(outbuf), &s);
+ SelectObject(dc, oldfont);
+ DeleteDC(dc);
+ return s.cx + SendMessageW(editWnd, EM_GETMARGINS, 0, 0)*2 + 2;
+#else
+ if (inbuf.isempty())
+ return 0;
+
+ RECT r;
+ getClientRect(&r);
+
+ SysCanvas sysc;
+ sysc.setTextSize(r.bottom - r.top);
+ return sysc.getTextWidth(inbuf);
+#endif
+}
+
+HWND EditWnd::getEditWnd()
+{
+ return editWnd;
+}
+
+#ifndef WIN32
+enum {
+ ES_MULTILINE,
+ ES_WANTRETURN,
+ ES_AUTOHSCROLL,
+ ES_AUTOVSCROLL,
+ WS_VSCROLL,
+};
+#endif
+
+void EditWnd::setMultiline(int ml)
+{
+ multiline = ml;
+ setStyle(ES_MULTILINE | ES_WANTRETURN, ml);
+}
+
+void EditWnd::setReadOnly(int ro)
+{
+ readonly = ro;
+ setStyle(ES_READONLY, ro);
+}
+
+void EditWnd::setPassword(int pw)
+{
+ password = pw;
+ setStyle(ES_PASSWORD, pw);
+}
+
+void EditWnd::setAutoHScroll(int hs)
+{
+ autohscroll = hs;
+ setStyle(ES_AUTOHSCROLL, hs);
+}
+
+void EditWnd::setAutoVScroll(int vs)
+{
+ autovscroll = vs;
+ setStyle(ES_AUTOVSCROLL, vs);
+}
+
+void EditWnd::setVScroll(int vs)
+{
+ vscroll = vs;
+ setStyle(WS_VSCROLL, vs);
+}
+
+void EditWnd::setStyle(LONG style, int set)
+{
+#ifdef WIN32
+ if (editWnd)
+ {
+ LONG s = GetWindowLong(editWnd, GWL_STYLE);
+ if (set) s |= style;
+ else s &= ~style;
+ SetWindowLong(editWnd, GWL_STYLE, s);
+ }
+#else
+ DebugString("portme -- EditWnd::setStyle\n");
+#endif
+}
+
+int EditWnd::onGetFocus()
+{
+ int r = EDITWND_PARENT::onGetFocus();
+#ifdef WIN32
+ if (editWnd != NULL)
+ SetFocus(editWnd);
+#endif
+ return r;
+}
+
+int EditWnd::wantFocus()
+{
+ return wantfocus;
+}
+
+int EditWnd::gotFocus()
+{
+ return (GetFocus() == editWnd);
+}
+
+void EditWnd::setBackgroundColor(COLORREF c)
+{
+ backgroundcolor.setColor(c);
+}
+
+void EditWnd::setTextColor(COLORREF c)
+{
+ textcolor.setColor(c);
+}
+
+void EditWnd::invalidate()
+{
+ EDITWND_PARENT::invalidate();
+ InvalidateRect(editWnd, NULL, TRUE);
+}
+
+#ifdef LINUX
+int EditWnd::textposFromCoord(int x, int y)
+{
+ RECT r;
+ getClientRect(&r);
+
+ SysCanvas canvas;
+
+ canvas.setTextColor(textcolor);
+ canvas.setTextSize(r.bottom - r.top);
+ canvas.setTextOpaque(FALSE);
+
+ x -= r.left;
+
+ int i;
+
+ char *str = STRDUP(inbuf);
+
+ if (x > canvas.getTextWidth(str + viewstart))
+ return inbuf.len();
+
+ for (i = viewstart + 1; str[i]; i++)
+ {
+ char save = str[i];
+ str[i] = '\0';
+ if (x < canvas.getTextWidth(str + viewstart))
+ {
+ str[i] = save;
+ break;
+ }
+ str[i] = save;
+ }
+
+ FREE(str);
+
+ return i - 1;
+}
+
+int EditWnd::onLeftButtonDown(int x, int y)
+{
+ EDITWND_PARENT::onLeftButtonDown(x, y);
+
+ // Add check for double/triple click...
+
+ cursorpos = textposFromCoord(x, y);
+ selstart = selend = cursorpos;
+
+ selectmode = 1;
+
+ return 1;
+}
+
+int EditWnd::onLeftButtonUp(int x, int y)
+{
+ EDITWND_PARENT::onLeftButtonUp(x, y);
+
+ selectmode = 0;
+
+ return 1;
+}
+
+int EditWnd::onMouseMove(int x, int y)
+{
+ EDITWND_PARENT::onMouseMove(x, y);
+
+ switch (selectmode)
+ {
+ case 0:
+ // Do nothing
+ break;
+ case 1:
+ selend = textposFromCoord(x, y);
+ cursorpos = selend;
+ onEditUpdate();
+ break;
+ default:
+ DebugString("selectmode %d not available\n", selectmode);
+ break;
+ }
+
+ return selectmode;
+}
+
+int EditWnd::onKeyDown(int key)
+{
+ EDITWND_PARENT::onKeyDown(key);
+
+ if (Std::keyDown(VK_CONTROL))
+ {
+ switch (key)
+ {
+ case 'a':
+ case 'A':
+ selectAll();
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ else
+ {
+ switch (key)
+ {
+ case XK_Home:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ if (selstart == selend)
+ {
+ selstart = selend = cursorpos;
+ }
+ selend = 0;
+ }
+ else
+ {
+ selstart = selend = 0;
+ }
+ cursorpos = 0;
+ break;
+
+ case XK_End:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ if (selstart == selend)
+ {
+ selstart = selend = cursorpos;
+ }
+ selend = inbuf.len();
+ }
+ else
+ {
+ selstart = selend = 0;
+ }
+ cursorpos = inbuf.len();
+ break;
+
+ case XK_Right:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ if (selstart == selend)
+ {
+ selstart = selend = cursorpos;
+ }
+ selend++;
+ if (selend > inbuf.len()) selend = inbuf.len();
+ }
+ else
+ {
+ selstart = selend = 0;
+ }
+ cursorpos++;
+ if (cursorpos > inbuf.len()) cursorpos = inbuf.len();
+ break;
+
+ case XK_Left:
+ if (Std::keyDown(VK_SHIFT))
+ {
+ if (selstart == selend)
+ {
+ selstart = selend = cursorpos;
+ }
+ selend--;
+ if (selend < 0) selend = 0;
+ }
+ else
+ {
+ selstart = selend = 0;
+ }
+ cursorpos--;
+ if (cursorpos < 0) cursorpos = 0;
+ break;
+
+ case XK_Escape:
+ onAbort();
+ break;
+
+ case XK_Return:
+ onEnter();
+ break;
+
+ case XK_Delete:
+ if (selstart != selend)
+ {
+ int start = MIN(selstart, selend);
+ int end = MAX(selstart, selend);
+
+ String add;
+
+ if (end < inbuf.len())
+ {
+ add = (const char *)inbuf + end;
+ }
+ else
+ {
+ add = "";
+ }
+
+ inbuf.trunc(start);
+ inbuf += add;
+
+ cursorpos = start;
+ selstart = selend = 0;
+
+ }
+ else
+ {
+ if (cursorpos >= 0)
+ {
+ if (cursorpos < inbuf.len() - 1)
+ {
+ String tmp = inbuf;
+ tmp.trunc(cursorpos);
+ inbuf = tmp + ((const char *)inbuf + cursorpos + 1);
+ }
+ else if (cursorpos == inbuf.len() - 1)
+ {
+ inbuf.trunc(cursorpos);
+ }
+ }
+ }
+ break;
+
+ case VK_BACK:
+ if (selstart != selend)
+ {
+ int start = MIN(selstart, selend);
+ int end = MAX(selstart, selend);
+
+ String add;
+
+ if (end < inbuf.len())
+ {
+ add = (const char *)inbuf + end;
+ }
+ else
+ {
+ add = "";
+ }
+
+ inbuf.trunc(start);
+ inbuf += add;
+
+ cursorpos = start;
+ selstart = selend = 0;
+ }
+ else
+ {
+ if (cursorpos > 0)
+ {
+ if (cursorpos >= inbuf.len())
+ {
+ inbuf.trunc(cursorpos - 1);
+ cursorpos--;
+ }
+ else
+ {
+ String tmp = inbuf;
+ tmp.trunc(cursorpos - 1);
+ inbuf = tmp + ((const char *)inbuf + cursorpos);
+ cursorpos--;
+ }
+ }
+ }
+ break;
+
+ default:
+ if (key < 0x20 || key > 0x7e)
+ return 0;
+
+ if (selstart != selend)
+ {
+ int start = MIN(selstart, selend);
+ int end = MAX(selstart, selend);
+
+ String add;
+
+ if (end < inbuf.len())
+ {
+ add = (const char *)inbuf + end;
+ }
+ else
+ {
+ add = "";
+ }
+
+ inbuf.trunc(start);
+ inbuf += add;
+
+ cursorpos = start;
+ selstart = selend = 0;
+ }
+
+ String tmp;
+
+ if (cursorpos >= inbuf.len())
+ {
+ tmp = "";
+ }
+ else
+ {
+ tmp = (const char *)inbuf + cursorpos;
+ }
+
+ inbuf.trunc(cursorpos);
+
+ inbuf += (char)key;
+ inbuf += tmp;
+
+ cursorpos++;
+ }
+ }
+
+ onEditUpdate();
+
+ return 1;
+}
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/editwnd.h b/Src/Wasabi/api/wnd/wndclass/editwnd.h
new file mode 100644
index 00000000..735debc2
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/editwnd.h
@@ -0,0 +1,134 @@
+//NONPORTABLE
+#ifndef _EDITWND_H
+#define _EDITWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <tataki/color/skinclr.h>
+#include <api/wnd/usermsg.h>
+#include <bfc/common.h>
+
+#define EDITWND_PARENT GuiObjectWnd
+class EditWnd : public EDITWND_PARENT {
+public:
+ EditWnd(wchar_t *buffer=NULL, int buflen=0);
+ virtual ~EditWnd();
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *canvas);
+ virtual int onResize();
+#ifdef WIN32
+ virtual LRESULT wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+
+ // mig: Made these virtual to allow to be accessed by
+ // EditWndString object in editwndstring.h
+ virtual void setBuffer(wchar_t *buffer, int len);
+ virtual void getBuffer(wchar_t *outbuf, int len);
+
+ virtual const wchar_t *getBufferPtr() { return outbuf; }
+ virtual int getBufferLength() { return maxlen; }
+ virtual void setBackgroundColor(ARGB32 c);
+ virtual void setTextColor(ARGB32 c);
+
+ void setModal(int modal); //if modal, deletes self on enter
+ void setAutoEnter(int a); //fake an onEnter event when lose focus
+ int getAutoEnter() { return autoenter; }
+ void setAutoSelect(int a); //true==grab the focus on init
+ void setIdleTimerLen(int ms); // how many ms keys are idle before send msg
+ virtual void onSetVisible(int show);
+ virtual int onGetFocus();
+ virtual int wantFocus();
+ virtual void setWantFocus(int w) { wantfocus = w; }
+ virtual void selectAll();
+ virtual void enter();
+ virtual void setIdleEnabled(int i) { idleenabled = i; }
+ virtual int getIdleEnabled() { return idleenabled; }
+
+ void setBorder(int border);
+ int getTextLength();
+
+ HWND getEditWnd();
+ virtual int handleRatio() { return 0; }
+ virtual int getAutoSelect() { return autoselect; }
+
+ void setMultiline(int ml);
+ void setReadOnly(int ro);
+ void setPassword(int pw);
+ void setAutoHScroll(int hs);
+ void setAutoVScroll(int vs);
+ void setVScroll(int vs);
+ int isEditorKey(int vk);
+ virtual void invalidate();
+
+ virtual int gotFocus();
+
+ // the wndproc for the edit box
+ virtual LRESULT editWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+protected:
+ virtual void timerCallback(int id);
+
+ // call down on these if you override them
+ virtual void onEditUpdate();
+ virtual void onIdleEditUpdate();
+ virtual int onEnter(); // user hit enter.. return 1 to close window
+ virtual int onAbort(); // user hit escape.. return 1 to close window
+ virtual int onLoseFocus(); // different from onKillFocus() from BaseWnd!
+
+ void setStyle(LONG style, int set);
+
+#ifdef LINUX
+ virtual int onLeftButtonDown( int x, int y );
+ virtual int onLeftButtonUp( int x, int y );
+ virtual int onMouseMove( int x, int y );
+ virtual int onKeyDown(int key);
+#endif
+
+private:
+#ifdef LINUX
+ int textposFromCoord( int x, int y );
+#endif
+
+ HWND editWnd;
+ WNDPROC prevWndProc;
+ int maxlen;
+ int retcode;
+ int idletimelen;
+ int modal;
+ int bordered;
+ int autoenter;
+ int beforefirstresize;
+ int autoselect;
+ int multiline;
+ int readonly;
+ int password;
+ int idleenabled;
+ int autohscroll,autovscroll,vscroll;
+ int nextenterfaked;
+ SkinColor backgroundcolor, textcolor, selectioncolor;
+#ifdef LINUX
+ int selstart, selend;
+ int cursorpos;
+ int selectmode;
+ int viewstart;
+#endif
+#ifdef WIN32
+ HBRUSH oldbrush;
+#endif
+
+ // Basically, we're redoing the functionality of EditWndString
+ // (the bigger version), so we'll probably erase EditWndString
+ // completely as an object.
+ MemBlock<wchar_t> buffer8;
+ wchar_t *outbuf;
+ int wantfocus;
+#ifdef LINUX
+ StringW inbuf;
+#endif
+};
+
+#define EDITWND_RETURN_NOTHING 0 // user didn't do nothing
+#define EDITWND_RETURN_OK 1 // user hit return
+#define EDITWND_RETURN_CANCEL 2 // user hit escape or something
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/editwndstring.cpp b/Src/Wasabi/api/wnd/wndclass/editwndstring.cpp
new file mode 100644
index 00000000..f296bda8
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/editwndstring.cpp
@@ -0,0 +1,17 @@
+#include <precomp.h>
+#include "editwndstring.h"
+
+// ===========================================================================
+//
+// NULLSOFT WASABI SDK MODULE & EXAMPLE CODE
+//
+// File: editwndstring.cpp
+//
+//!## Purpose: The EditWndString object both extends the EditWnd object to
+//!## simplify and streamline the use of an EditWnd in your wasabi
+//!## components. In addition, this module serves as a tutorial
+//!## to instruct wasabi developers on how to properly extend our
+//!## current objects to provide new functionality.
+//
+//
+
diff --git a/Src/Wasabi/api/wnd/wndclass/editwndstring.h b/Src/Wasabi/api/wnd/wndclass/editwndstring.h
new file mode 100644
index 00000000..843524bf
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/editwndstring.h
@@ -0,0 +1,24 @@
+#ifndef _EDITWNDSTRING_H
+#define _EDITWNDSTRING_H
+
+#include <api/wnd/wndclass/editwnd.h>
+#include <bfc/memblock.h>
+
+class EditWndString : public EditWnd
+{
+public:
+ void setBuffer(wchar_t *buffer, int len=0)
+ {
+ b.setSize(len+1);
+ wchar_t *bufmem=b.getMemory();
+ if(len)
+ wcsncpy(bufmem,buffer,len);
+ bufmem[len]=0;
+ EditWnd::setBuffer(bufmem,len);
+ }
+ const wchar_t *getBuffer() { return b.getMemory(); }
+private:
+ MemBlock<wchar_t> b;
+};
+
+#endif//_EDITWNDSTRING_H \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/embeddedxui.cpp b/Src/Wasabi/api/wnd/wndclass/embeddedxui.cpp
new file mode 100644
index 00000000..8e47f29e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/embeddedxui.cpp
@@ -0,0 +1,143 @@
+#include "precomp.h"
+#include "embeddedxui.h"
+
+EmbeddedXuiObject::EmbeddedXuiObject() {
+ embedded = NULL;
+ myxuihandle = newXuiHandle();
+ getScriptObject()->vcpu_setInterface(embeddedXuiGuid, (void *)static_cast<EmbeddedXuiObject *>(this));
+ getScriptObject()->vcpu_setClassName(L"ObjectEmbedded"); // this is the script class name
+ getScriptObject()->vcpu_setController(embeddedXuiController);
+}
+
+EmbeddedXuiObject::~EmbeddedXuiObject() {
+ paramlist.deleteAll();
+}
+
+void EmbeddedXuiObject::onNewContent() {
+ embeddedxui_onNewEmbeddedContent();
+}
+
+void EmbeddedXuiObject::embeddedxui_onNewEmbeddedContent() {
+ embedded = NULL;
+ const wchar_t *id = embeddedxui_getEmbeddedObjectId();
+ if (id != NULL && *id) {
+ GuiObject *myself = getGuiObject();
+ embedded = myself->guiobject_findObject(id);
+ if (embedded != NULL && embedded != myself) {
+ foreach(paramlist)
+ EmbeddedXuiObjectParam *p = paramlist.getfor();
+ embedded->guiobject_setXmlParam(p->param, p->value);
+ endfor;
+#ifdef WASABI_COMPILE_CONFIG
+ syncCfgAttrib();
+#endif
+ }
+ }
+}
+
+int EmbeddedXuiObject::onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value) {
+ int r = EMBEDDEDXUIOBJECT_PARENT::onUnknownXuiParam(xmlattributename, value);
+ paramlist.addItem(new EmbeddedXuiObjectParam(xmlattributename, value));
+ if (embedded)
+ r = embedded->guiobject_setXmlParam(xmlattributename, value);
+ return r;
+}
+
+int EmbeddedXuiObject::onInit()
+{
+ int r = EMBEDDEDXUIOBJECT_PARENT::onInit();
+ const wchar_t *id = embeddedxui_getContentId();
+ if (id != NULL && *id)
+ setContent(id);
+ return r;
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+int EmbeddedXuiObject::onReloadConfig() {
+ int r = EMBEDDEDXUIOBJECT_PARENT::onReloadConfig();
+ syncCfgAttrib();
+ return r;
+}
+#endif
+
+#ifdef WASABI_COMPILE_CONFIG
+void EmbeddedXuiObject::syncCfgAttrib()
+{
+ if (embedded == NULL) return;
+ CfgItem *item = getGuiObject()->guiobject_getCfgItem();
+ const wchar_t *attrib = getGuiObject()->guiobject_getCfgAttrib();
+ if (item != embedded->guiobject_getCfgItem() ||
+ attrib != embedded->guiobject_getCfgAttrib()) {
+ embedded->guiobject_setCfgAttrib(item, attrib);
+ }
+}
+#endif
+
+// -----------------------------------------------------------------------
+// Script Object
+
+EmbeddedXuiScriptController _embeddedXuiController;
+EmbeddedXuiScriptController *embeddedXuiController = &_embeddedXuiController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct EmbeddedXuiScriptController::exportedFunction[] = {
+ {L"getEmbeddedObject", 0, (void*)EmbeddedXuiScriptController::EmbeddedXui_getEmbeddedObject},
+};
+
+ScriptObject *EmbeddedXuiScriptController::instantiate() {
+ EmbeddedXuiObject *ex = new EmbeddedXuiObject;
+ ASSERT(ex != NULL);
+ return ex->getScriptObject();
+}
+
+void EmbeddedXuiScriptController::destroy(ScriptObject *o) {
+ EmbeddedXuiObject *ex= static_cast<EmbeddedXuiObject *>(o->vcpu_getInterface(embeddedXuiGuid));
+ ASSERT(ex != NULL);
+ delete ex;
+}
+
+void *EmbeddedXuiScriptController::encapsulate(ScriptObject *o) {
+ return NULL; // no encapsulation for DropDownlist yet
+}
+
+void EmbeddedXuiScriptController::deencapsulate(void *o) {
+}
+
+int EmbeddedXuiScriptController::getNumFunctions() {
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *EmbeddedXuiScriptController::getExportedFunctions() {
+ return exportedFunction;
+}
+
+
+scriptVar EmbeddedXuiScriptController::EmbeddedXui_getEmbeddedObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
+ SCRIPT_FUNCTION_INIT
+ EmbeddedXuiObject *ex = static_cast<EmbeddedXuiObject*>(o->vcpu_getInterface(embeddedXuiGuid));
+ ScriptObject *_o = NULL;
+ if (ex) {
+ GuiObject *go = ex->embeddedxui_getEmbeddedObject();
+ if (go != NULL)
+ _o = go->guiobject_getScriptObject();
+ }
+ return MAKE_SCRIPT_OBJECT(_o);
+}
+
+ScriptObject *EmbeddedXuiScriptController::cast(ScriptObject *o, GUID g) {
+ EmbeddedXuiObject *exo = static_cast<EmbeddedXuiObject *>(o->vcpu_getInterface(embeddedXuiGuid));
+ if (!exo) return NULL;
+ GuiObject *go = exo->embeddedxui_getEmbeddedObject();
+ if (go != NULL) {
+ ScriptObject *eo = go->guiobject_getScriptObject();
+ if (eo != NULL) {
+ void *i = eo->vcpu_getInterface(g);
+ if (i != NULL)
+ return eo;
+ }
+ }
+ return NULL;
+}
+
+
+ScriptObjectController *EmbeddedXuiScriptController::getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); } \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/embeddedxui.h b/Src/Wasabi/api/wnd/wndclass/embeddedxui.h
new file mode 100644
index 00000000..38b187d5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/embeddedxui.h
@@ -0,0 +1,88 @@
+#ifndef __EMBEDDEDXUIOBJECT_H
+#define __EMBEDDEDXUIOBJECT_H
+
+#include <wasabicfg.h>
+#include <api/script/api_maki.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptguid.h>
+#include <api/script/scriptobj.h>
+#include <api/script/objcontroller.h>
+
+#define EMBEDDEDXUIOBJECT_PARENT GuiObjectWnd
+
+
+class EmbeddedXuiObjectParam {
+ public:
+
+
+ EmbeddedXuiObjectParam(const wchar_t *p, const wchar_t *v) : param(p), value(v) {}
+
+ virtual ~EmbeddedXuiObjectParam() {}
+
+ StringW param;
+ StringW value;
+};
+
+
+class EmbeddedXuiObject : public EMBEDDEDXUIOBJECT_PARENT {
+ public:
+
+ EmbeddedXuiObject();
+
+
+ virtual ~EmbeddedXuiObject();
+
+ virtual void onNewContent();
+
+ virtual int onInit();
+
+
+ virtual void embeddedxui_onNewEmbeddedContent();
+ virtual const wchar_t *embeddedxui_getContentId() { return NULL; }
+ virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return NULL; }
+
+ virtual int onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value);
+
+
+#ifdef WASABI_COMPILE_CONFIG
+ virtual int onReloadConfig();
+#endif
+ virtual GuiObject *embeddedxui_getEmbeddedObject() { return embedded; }
+
+ private:
+
+#ifdef WASABI_COMPILE_CONFIG
+ void syncCfgAttrib();
+#endif
+
+ int myxuihandle;
+ PtrList<EmbeddedXuiObjectParam> paramlist;
+ GuiObject *embedded;
+};
+
+// -----------------------------------------------------------------------
+class EmbeddedXuiScriptController: public ScriptObjectControllerI
+{
+public:
+ virtual const wchar_t *getClassName() { return L"ObjectEmbedder"; }
+ virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid() { return embeddedXuiGuid; }
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual ScriptObject *cast(ScriptObject *o, GUID g);
+
+private:
+
+ static function_descriptor_struct exportedFunction[];
+ static scriptVar EmbeddedXui_getEmbeddedObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+};
+
+extern COMEXP EmbeddedXuiScriptController *embeddedXuiController;
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/foreignwnd.cpp b/Src/Wasabi/api/wnd/wndclass/foreignwnd.cpp
new file mode 100644
index 00000000..e6e490e3
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/foreignwnd.cpp
@@ -0,0 +1,60 @@
+#include "precomp.h"
+#include "foreignwnd.h"
+
+PtrListQuickSorted<ForeignWndProc, ForeignWndProcComparator> ForeignWnd::foreignwndprocs;
+
+LRESULT CALLBACK foreignWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ForeignWndProc *wp = ForeignWnd::foreignwndprocs.findItem((const wchar_t *)hwnd);
+ if (wp)
+ {
+ if (uMsg == WM_SHOWWINDOW) // more ?
+ wp->wnd->wndProc(hwnd, uMsg, wParam, lParam);
+ return CallWindowProc(wp->oldWindowProc, hwnd, uMsg, wParam, lParam);
+ }
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+ForeignWnd::ForeignWnd(OSWINDOWHANDLE wndhandle, OSMODULEHANDLE module, int subclass)
+{
+ thishwnd = wndhandle;
+ setOSModuleHandle(module);
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ DebugString("ForeignWnd::ForeignWnd(OSWINDOWHANDLE wndhandle): There might be problems with GWL_USERDATA assumptions when EXPERIMENTAL_INDEPENDENT_AOT is on, lone should audit\n");
+#endif
+
+ // access protected basewnd member
+ hwnd = wndhandle;
+
+ setForeignWnd(1);
+
+ if (subclass)
+ {
+ oldWindowProc = (WNDPROC) GetWindowLongPtrW(wndhandle, GWLP_WNDPROC);
+ wndprocentry = new ForeignWndProc;
+ wndprocentry->wnd = this;
+ wndprocentry->hwnd = thishwnd;
+ wndprocentry->oldWindowProc = oldWindowProc;
+ foreignwndprocs.addItem(wndprocentry);
+ SetWindowLongPtrW(thishwnd, GWLP_WNDPROC, (LONG_PTR)foreignWindowProc);
+ }
+ else
+ {
+ oldWindowProc = NULL;
+ wndprocentry = NULL;
+ }
+}
+
+ForeignWnd::~ForeignWnd()
+{
+ if (wndprocentry && oldWindowProc)
+ {
+ foreignwndprocs.removeItem(wndprocentry);
+ delete wndprocentry;
+ wndprocentry = NULL;
+ SetWindowLongPtrW(thishwnd, GWLP_WNDPROC, (LONG_PTR)oldWindowProc);
+ oldWindowProc = NULL;
+ }
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/foreignwnd.h b/Src/Wasabi/api/wnd/wndclass/foreignwnd.h
new file mode 100644
index 00000000..023cb6b1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/foreignwnd.h
@@ -0,0 +1,56 @@
+#ifndef __FOREIGNWND_H
+#define __FOREIGNWND_H
+
+#ifdef _WIN32
+#include <api/wnd/basewnd.h>
+
+class ForeignWnd;
+
+class ForeignWndProc
+{
+public:
+ ForeignWnd *wnd;
+ HWND hwnd;
+ WNDPROC oldWindowProc;
+};
+
+class ForeignWndProcComparator
+{
+public:
+ // comparator for sorting
+ static int compareItem(ForeignWndProc *p1, ForeignWndProc* p2)
+ {
+ return CMP3(p1->hwnd, p2->hwnd);
+ }
+ // comparator for searching
+ static int compareAttrib(const wchar_t *attrib, ForeignWndProc *item)
+ {
+ return CMP3((HWND)attrib, item->hwnd);
+ }
+};
+
+class ForeignWnd : public BaseWnd
+{
+public:
+ // takes over an existing OSWINDOWHANDLE and wraps a BaseWnd around it
+ // but does not changes the windowproc, nor does it inserts the wnd
+ // into the system list. It does not either (under windows anyway)
+ // sets the userdata windowlong to the object pointer.
+ // if subclass is true, we subclas the windowproc and process events
+ // as if the window was a real rootwnd
+
+ ForeignWnd(OSWINDOWHANDLE w, OSMODULEHANDLE m, int subclass = 0);
+
+ virtual ~ForeignWnd();
+
+ static PtrListQuickSorted<ForeignWndProc, ForeignWndProcComparator> foreignwndprocs;
+
+private:
+ WNDPROC oldWindowProc;
+ HWND thishwnd;
+ ForeignWndProc *wndprocentry;
+};
+#else
+#warning port me
+#endif
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/framewnd.cpp b/Src/Wasabi/api/wnd/wndclass/framewnd.cpp
new file mode 100644
index 00000000..26e56537
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/framewnd.cpp
@@ -0,0 +1,777 @@
+#include <precomp.h>
+
+#include "framewnd.h"
+#include <api/wnd/notifmsg.h>
+#include <bfc/bfc_assert.h>
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/PaintCanvas.h>
+#include <bfc/wasabi_std_wnd.h>
+
+#define DC_FWFOCUS 0x5122
+
+FrameWnd::FrameWnd()
+{
+// sizer = NULL;
+ SNAP=1;
+ snapoffsety=0;
+ snapoffsetx=0;
+ nchild = 0;
+ for (int i = 0; i < MAXCHILD; i++) {
+ children[i] = NULL;
+ rwchildren[i] = NULL;
+ hidey[i] = 0;
+ windowshaded[i] = 0;
+ }
+ vert = DIVIDER_UNDEFINED;
+ divideside = SDP_FROMLEFT;
+ pullbarpos = PULLBAR_HALF;
+ minwidth = PULLBAR_QUARTER-PULLBAR_EIGHTH;
+ maxwidth = PULLBAR_HALF;
+ resizeable = 0;
+ slidemode = FRAMEWND_SQUISH;
+ prevpullbarpos = -1;
+ maxpixels=0;
+ minpixels=0;
+ noMaxRestriction = false;
+ ZERO(sizerRect);
+
+ h_bitmap = L"wasabi.framewnd.horizontaldivider";
+ v_bitmap = L"wasabi.framewnd.verticaldivider";
+ h_grabber = L"wasabi.framewnd.horizontalgrabber";
+ v_grabber = L"wasabi.framewnd.verticalgrabber";
+ ws_bitmap = L"wasabi.framewnd.windowshade";
+ resizing = 0;
+}
+
+void FrameWnd::Set_v_bitmap(const wchar_t *new_v_bitmap)
+{
+ v_bitmap=new_v_bitmap;
+ if (isInited())
+ {
+ invalidate();
+ onResize();
+ }
+}
+
+void FrameWnd::Set_v_grabber(const wchar_t *new_v_grabber)
+ {
+ v_grabber=new_v_grabber;
+ if (isInited())
+ {
+ invalidate();
+ onResize();
+ }
+}
+
+FrameWnd::~FrameWnd() {
+#ifdef WASABI_COMPILE_CONFIG
+ if (getId() != NULL) {
+ StringPrintfW buf(L"FrameWnd/ws,%s", getId());
+ WASABI_API_CONFIG->setIntPrivate(buf, windowshaded[0]);
+ }
+#endif
+
+ if (children[0]) // do we have any basewnd ?
+ for (int i = 0; i < nchild; i++) delete children[i];
+}
+
+int FrameWnd::onInit() {
+ int i;
+
+ FRAMEWND_PARENT::onInit();
+
+ ASSERT(vert != DIVIDER_UNDEFINED || nchild == 0);
+
+ // have to set children for frame windows
+
+ // fill in members
+ nchild = 0;
+
+ // make children create their windows
+ for (i = 0; i < MAXCHILD; i++) {
+ if (rwchildren[i] != NULL) {
+ if (rwchildren[i]->init(this) != 0) {
+ rwchildren[i]->setParent(this);
+ nchild++;
+ }
+ }
+ }
+ prevpullbarpos = pullbarpos;
+
+ if (nchild >= MAXCHILD) {
+ int which = (divideside == SDP_FROMLEFT) ? 0 : 1;
+ rwchildren[which]->bringToFront();
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (getId() != NULL) {
+ StringPrintfW buf(L"FrameWnd/ws,%s", getId());
+ int ws = WASABI_API_CONFIG->getIntPrivate(buf, /*rwchildren[0] && rwchildren[0]->childNotify(NULL, CHILD_WINDOWSHADE_CAPABLE)*/ 0);
+ if (ws) {
+ windowshade(0, !ws);
+ windowshade(0, ws);
+ pullbarpos = 0;
+ }
+ }
+#endif
+
+ return 1;
+}
+
+int FrameWnd::getCursorType(int x, int y) {
+ RECT r;
+ getClientRect(&r);
+ POINT pt={x,y};
+ if (y > r.top + getLabelHeight() && Wasabi::Std::pointInRect(sizerRect, pt)) {
+ if (vert == DIVIDER_HORIZONTAL) return BASEWND_CURSOR_NORTHSOUTH;
+ else return BASEWND_CURSOR_EASTWEST;
+ }
+ return BASEWND_CURSOR_POINTER;
+}
+
+int FrameWnd::setChildren(BaseWnd *newchild1, BaseWnd *newchild2) {
+ return _setChildren(newchild1, newchild2, newchild1, newchild2);
+}
+
+int FrameWnd::setChildrenRootWnd(ifc_window *child1, ifc_window *child2/* =NULL */) {
+ return _setChildren(child1, child2, NULL, NULL);
+}
+
+int FrameWnd::_setChildren(ifc_window *child1, ifc_window *child2, BaseWnd *child1b, BaseWnd *child2b) {
+ if (child1b) { // we can delete them later
+ children[0] = child1b;
+ children[1] = child2b;
+ }
+ rwchildren[0] = child1;
+ rwchildren[1] = child2;
+ nchild = 0;
+ if (rwchildren[0] != NULL) nchild++;
+ if (rwchildren[1] != NULL) nchild++;
+
+ ASSERTPR(nchild >= 1, "framewnd must have one or more children");
+
+ if (isInited()) {
+ invalidate();
+ onResize();
+ }
+ return nchild;
+}
+
+ifc_window *FrameWnd::enumChild(int which) {
+ if (which < 0 || which >= MAXCHILD) return NULL;
+ return rwchildren[which];
+}
+
+int FrameWnd::childNotify(ifc_window *which, int msg, intptr_t param1, intptr_t param2) {
+// ASSERT(which == rwchildren[0] || which == rwchildren[1] || which == NULL);
+ switch (msg) {
+ case ChildNotify::FRAMEWND_SETTITLEWIDTH:
+ if (pullbarpos == param1) return 0;
+ ASSERT(param1 >= 0);
+ if (which == rwchildren[0]) {
+ // rwchildren[1]->invalidate(); //FG> removed due to change in redraw layout
+ // rwchildren[1]->repaint();
+ ASSERT(divideside == SDP_FROMLEFT);
+ } else {
+ // rwchildren[0]->invalidate();
+ // rwchildren[0]->repaint();
+ ASSERT(divideside == SDP_FROMRIGHT);
+ }
+ pullbarpos = param1;
+ // do it
+ onResize();
+ return 1;
+
+ case ChildNotify::HIDEYHIDEY:
+ if (which == rwchildren[0]) hidey[0] = 1;
+ else if (which == rwchildren[1]) hidey[1] = 1;
+ which->setVisible(FALSE);
+ onResize();
+ return 1;
+
+ case ChildNotify::UNHIDEYHIDEY:
+ if (which == rwchildren[0]) hidey[0] = 0;
+ else if (which == rwchildren[1]) hidey[1] = 0;
+ which->setVisible(TRUE);
+ onResize();
+ return 1;
+
+ case ChildNotify::FRAMEWND_QUERY_SLIDE_MODE:
+ return getSlideMode();
+
+ case ChildNotify::FRAMEWND_SET_SLIDE_MODE:
+ setSlideMode((FrameWndSlideMode)param1);
+ break;
+ case ChildNotify::GOTFOCUS:
+ case ChildNotify::KILLFOCUS:
+ invalidateLabel();
+ break;
+ }
+
+ return FRAMEWND_PARENT::childNotify(which, msg, param1, param2);
+}
+
+/*int FrameWnd::forceFocus() {
+ if (!canShowFocus()) return 0; // we aren't showing a label
+ int v = 0;
+ if (nchild > 0 && rwchildren[0] != NULL) {
+ if (!rwchildren[0]->canShowFocus()) v |= rwchildren[0]->gotFocus();
+ }
+ if (nchild > 1 && rwchildren[1] != NULL) {
+ if (!rwchildren[1]->canShowFocus()) v |= rwchildren[1]->gotFocus();
+ }
+ return v;
+}*/
+
+void FrameWnd::setDividerType(FrameWndDividerType type) {
+ vert = type;
+ ASSERT(vert == DIVIDER_VERTICAL || vert == DIVIDER_HORIZONTAL);
+ if (isInited())
+ onResize();
+}
+
+FrameWndDividerType FrameWnd::getDividerType() {
+ return vert;
+}
+
+int FrameWnd::ConvertPixToProp() {
+ RECT r;
+ int w;
+ getClientRect(&r);
+ if(vert == DIVIDER_VERTICAL) {
+ w = r.right-r.left;
+ } else {
+ w = r.bottom-r.top;
+ }
+ w = (pullbarpos * PULLBAR_FULL) / w;
+ return w;
+}
+
+int FrameWnd::convertPropToPix(int prop) {
+ RECT r;
+ int w;
+
+ getClientRect(&r);
+ if(vert == DIVIDER_VERTICAL) {
+ w = r.right-r.left;
+ } else {
+ w = r.bottom-r.top;
+ }
+ return (w * prop) / PULLBAR_FULL;
+}
+
+int FrameWnd::setDividerPosNoCfg(int from, int pos) {
+ divideside = from;
+
+ ASSERT(pos >= 0);
+ pullbarpos = pos;
+ if (isInited())
+ onResize();
+
+ StringPrintfW buf(L"FrameWnd/%s,p", getId());
+ WASABI_API_CONFIG->setIntPrivate(buf, pullbarpos);
+
+ return 1;
+}
+
+int FrameWnd::setDividerPos(int from, int pos) {
+#ifdef WASABI_COMPILE_CONFIG
+ if (getId() != NULL) {
+ StringPrintfW buf(L"FrameWnd/%s,p", getId());
+ pos = WASABI_API_CONFIG->getIntPrivate(buf, pos);
+ if (pos <= 0) pos = 0;
+ else if (pos >= PULLBAR_FULL) pos = PULLBAR_FULL;
+ }
+#endif
+ return setDividerPosNoCfg(from, pos);
+}
+
+void FrameWnd::getDividerPos(int *from, int *pos) {
+ if (from != NULL) *from = divideside;
+ if (pos != NULL) *pos = pullbarpos;
+}
+
+int FrameWnd::setResizeable(int is) {
+ int prev = resizeable;
+ resizeable = is;
+ return prev;
+}
+
+void FrameWnd::setMinWidth(int min) {
+ //ASSERT(min >= 0);
+ minpixels = min;
+}
+
+void FrameWnd::setMaxWidth(int max)
+{
+ //ASSERT(max >= 0);
+ maxpixels=max;
+ noMaxRestriction = (max == 0);
+ //maxwidth = max;
+}
+
+void FrameWnd::setSlideMode(FrameWndSlideMode mode) {
+ slidemode = mode;
+ if (isInited())
+ onResize();
+}
+
+FrameWndSlideMode FrameWnd::getSlideMode() {
+ return slidemode;
+}
+
+int FrameWnd::dragEnter(ifc_window *sourceWnd) {
+ ifc_window *ch = getWindowShadedChild();
+ if (ch == NULL) return FRAMEWND_PARENT::dragEnter(sourceWnd);
+ return ch->getDragInterface()->dragEnter(sourceWnd);
+}
+
+int FrameWnd::dragOver(int x, int y, ifc_window *sourceWnd) {
+ ifc_window *ch = getWindowShadedChild();
+ if (ch == NULL) return FRAMEWND_PARENT::dragOver(x, y, sourceWnd);
+ return ch->getDragInterface()->dragOver(-1, -1, sourceWnd);
+}
+
+int FrameWnd::dragLeave(ifc_window *sourceWnd) {
+ ifc_window *ch = getWindowShadedChild();
+ if (ch == NULL) return FRAMEWND_PARENT::dragLeave(sourceWnd);
+ return ch->getDragInterface()->dragLeave(sourceWnd);
+}
+
+int FrameWnd::dragDrop(ifc_window *sourceWnd, int x, int y) {
+ ifc_window *ch = getWindowShadedChild();
+ if (ch == NULL) return FRAMEWND_PARENT::dragDrop(sourceWnd, x, y);
+ return ch->getDragInterface()->dragDrop(sourceWnd, x, y);
+}
+
+int FrameWnd::onResize()
+{
+ int rt = FRAMEWND_PARENT::onResize();
+ if (!isInited()) return rt;
+ RECT r;
+ int sizerwidth = SIZERWIDTH;
+
+ if (!isInited()) {
+ prevpullbarpos = pullbarpos;
+ return 1; // no window to resize
+ }
+
+ getClientRect(&r);
+
+ ASSERT(nchild >= 0);
+ if (nchild == 0) {
+ prevpullbarpos = pullbarpos;
+ return 1;
+ }
+
+ if (hidey[0] && hidey[1]) return 0; // both windows are hiding
+
+ // if we have only one child, it takes up all the room
+ if (hidey[0]) {
+ rwchildren[1]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ return 1;
+ } else if (hidey[1]) {
+ rwchildren[0]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ return 1;
+ }
+
+ if (nchild == 1) {
+ if (rwchildren[0] != NULL) rwchildren[0]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ else if (rwchildren[1] != NULL) rwchildren[1]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ return 1;
+ }
+
+#ifdef ASSERTS_ENABLED
+ for (int i = 0; i < nchild; i++) {
+ ASSERT(rwchildren[i] != NULL);
+ }
+#endif
+
+ if (!resizeable) sizerwidth = 0;
+
+ // resize the subwindows
+
+ int w;
+ if (vert == DIVIDER_VERTICAL) {
+ w = r.right-r.left;
+ } else {
+ w = r.bottom-r.top;
+ }
+ int clientwidth = w; // the logical width
+
+ switch (pullbarpos) {
+ case PULLBAR_FULL: /*w = w;*/ break;
+ case PULLBAR_HALF: w = w/2; break;
+ case PULLBAR_QUARTER: w = w/4; break;
+ case PULLBAR_THREEQUARTER: w = w - w/4; break;
+ case PULLBAR_EIGHTH: w = w/8; break;
+ default: w = pullbarpos; break;
+ }
+
+ // maxpixels holds normally a negative or zero value!
+ if (divideside == SDP_FROMRIGHT)
+ {
+ w = (clientwidth - w);
+ if (maxpixels < 1 && w < -maxpixels) w = -maxpixels; // Martin> This fixes an ugly drawing overlap
+ // TODO: check non-relative width as well, imoh we should rewrite this function from scrap.
+ }
+ else // FROMLEFT
+ {
+ if (maxpixels < 1 && w > clientwidth + maxpixels)
+ w = clientwidth + maxpixels;
+ if (w < minpixels)
+ w = minpixels;
+ }
+
+ RECT r1, r2;
+
+ if (slidemode == FRAMEWND_COVER) { // cover mode
+
+ ASSERTPR(vert == DIVIDER_VERTICAL, "finish implementing");
+
+ if (divideside == SDP_FROMRIGHT) {
+ Wasabi::Std::setRect(&r1, r.left, r.top, r.right-r.left, r.bottom-r.top); //FG> delay resize
+ Wasabi::Std::setRect(&r2, r.left+w, r.top, r.left+clientwidth - w, r.bottom-r.top);
+ } else {
+ Wasabi::Std::setRect(&r1, r.left, r.top, r.left+w, r.bottom-r.top); //FG> delay resize
+ Wasabi::Std::setRect(&r2, r.left, r.top, r.right-r.left, r.bottom-r.top);
+ }
+
+ sizerRect.top = r.top;
+ sizerRect.bottom = r.bottom;
+ sizerRect.left = r.left + w;
+ sizerRect.right = r.left + w + sizerwidth;
+
+ } else { // squish mode
+ // left-right
+ if (vert == DIVIDER_VERTICAL) {
+ sizerRect.top = r.top;
+ sizerRect.bottom = r.bottom;
+ if (divideside == SDP_FROMLEFT) { // from left
+
+ //FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
+ Wasabi::Std::setRect(&r1, r.left, r.top, w, r.bottom-r.top);
+ Wasabi::Std::setRect(&r2, r.left+w+sizerwidth, r.top, (r.right-r.left)-(w+sizerwidth), r.bottom-r.top);
+
+ sizerRect.left = r.left+w;
+ sizerRect.right = sizerRect.left + sizerwidth;
+ }
+ else { // from right
+
+ //FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
+ Wasabi::Std::setRect(&r1, r.left, r.top, w-sizerwidth, r.bottom-r.top);
+ Wasabi::Std::setRect(&r2, r.left+w, r.top, (r.right-r.left)-w, r.bottom-r.top);
+
+ sizerRect.left = r.left+w-sizerwidth;
+ sizerRect.right = r.left+w;
+ }
+ } else {
+ // top-bottom
+
+ //FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
+ Wasabi::Std::setRect(&r1, r.left, r.top, r.right-r.left, w);
+ Wasabi::Std::setRect(&r2, r.left, r.top+w+sizerwidth, r.right-r.left, (r.bottom-r.top)-(w+sizerwidth));
+
+ sizerRect.top = r.top+w;
+ sizerRect.bottom = r.top+w+sizerwidth;
+ sizerRect.left = r.left;
+ sizerRect.right = r.right;
+ }
+ }
+
+ //FG> Choose resizing order. optimizes redraw by avoiding temporary overlap of rwchildren
+ bool reverse = false;
+ if (vert == DIVIDER_VERTICAL) {
+ RECT o;
+ rwchildren[0]->getNonClientRect(&o);
+ reverse = (r1.right > o.right);
+ } else {
+ RECT o;
+ rwchildren[0]->getNonClientRect(&o);
+ reverse = (r1.bottom > o.bottom);
+ }
+
+ //FG> actually resize rwchildren
+ //FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
+ if (reverse) {
+ rwchildren[1]->resize(r2.left, r2.top, r2.right, r2.bottom);
+ rwchildren[0]->resize(r1.left, r1.top, r1.right, r1.bottom);
+ } else {
+ rwchildren[0]->resize(r1.left, r1.top, r1.right, r1.bottom);
+ rwchildren[1]->resize(r2.left, r2.top, r2.right, r2.bottom);
+ }
+
+ onResizeChildren(r1, r2);
+
+// RECT ri = sizerRect;
+#if 0
+ if (vert == DIVIDER_HORIZONTAL) {
+ ri.left -= 2;
+ ri.right += 2;
+ } else {
+ ri.top -= 2;
+ ri.bottom += 2;
+ }
+#endif
+// invalidateRect(&ri);
+ invalidate();
+ repaint();
+
+ prevpullbarpos = pullbarpos;
+
+ return 1;
+}
+
+void FrameWnd::onResizeChildren(RECT leftr, RECT rightr) {
+}
+
+int FrameWnd::onPaint(Canvas *canvas) {
+
+ RECT d;
+ getClientRect(&d);
+ if ((d.left >= d.right) || (d.top >= d.bottom)) {
+ return FRAMEWND_PARENT::onPaint(canvas);
+ }
+
+ RECT cr;
+// PaintBltCanvas paintcanvas;
+ PaintCanvas paintcanvas;
+
+ // if only 1 child, we don't paint anything
+ if (nchild <= 1) return FRAMEWND_PARENT::onPaint(canvas);
+
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ FRAMEWND_PARENT::onPaint(canvas);
+
+ getClientRect(&cr);
+
+ if (wantRenderBaseTexture() || !isVirtual())
+ renderBaseTexture(canvas, cr);
+
+ if (resizeable) {
+ RECT r = sizerRect;
+ if (vert == DIVIDER_HORIZONTAL) {
+ r.left -= 2;
+ r.right += 2;
+ } else {
+ r.top -= 2;
+ r.bottom += 2;
+ }
+
+ AutoSkinBitmap &bitmap = (vert == DIVIDER_VERTICAL) ? v_bitmap : h_bitmap;
+ bitmap.stretchToRectAlpha(canvas, &r);
+
+ if (vert == DIVIDER_VERTICAL) {
+ int h = sizerRect.bottom - sizerRect.top;
+ int gh = v_grabber.getHeight();
+ if (h > gh) {
+ RECT rr = sizerRect;
+ rr.top += (h - gh) / 2;
+ rr.bottom -= (h - gh) / 2;
+ v_grabber.stretchToRectAlpha(canvas, &rr);
+ }
+ } else {
+ int w = sizerRect.right - sizerRect.left;
+ int gw = h_grabber.getWidth();
+ if (w > gw) {
+ RECT rr = sizerRect;
+ rr.left += (w - gw) / 2;
+ rr.right -= (w - gw) / 2;
+ h_grabber.stretchToRectAlpha(canvas, &rr);
+ }
+ }
+
+ if (windowshaded[0]) {
+ RECT wr = cr;
+ if (vert == DIVIDER_VERTICAL) {
+ wr.right = r.left;
+ } else if (vert == DIVIDER_HORIZONTAL) {
+ wr.bottom = r.top;
+ }
+
+ ws_bitmap.stretchToRect(canvas, &wr);
+ }
+
+ }
+
+ return 1;
+}
+
+int FrameWnd::onLeftButtonDown(int x, int y) {
+ FRAMEWND_PARENT::onLeftButtonDown(x, y);
+ if (!resizeable) return 1;
+ POINT p = { x, y };
+ if (Wasabi::Std::pointInRect(sizerRect, p)) {
+ beginCapture();
+ RECT r;
+ getClientRect(&r);
+ x -= r.left;
+ y -= r.top;
+ snapoffsety= y - (y % SNAP);
+ snapoffsetx= x - (x % SNAP);
+ resizing = 1;
+ return 1;
+ }
+ return 0;
+}
+
+int FrameWnd::onMouseMove(int x, int y) {
+ int pos, mpos;
+ RECT r;
+
+ if (!resizing) return 1;
+
+ FRAMEWND_PARENT::onMouseMove(x,y);
+
+ prevpullbarpos = pullbarpos;
+
+ getClientRect(&r);
+ x -= r.left;
+ y -= r.top;
+
+ if (vert == DIVIDER_VERTICAL) {
+ pos = r.right - r.left;
+ if ((x - (x % SNAP)) == snapoffsetx)
+ return 1;
+ mpos=x;
+ snapoffsetx=(x - (x % SNAP));
+ } else {
+ pos = r.bottom - r.top;
+ if ((y - (y % SNAP)) == snapoffsety)
+ return 1;
+ mpos=y;
+ snapoffsety=y - (y % SNAP);
+ }
+ ASSERT(pos != 0);
+ if (mpos < 0) mpos = 0;
+ if (mpos > pos) mpos = pos;
+
+ if(divideside == SDP_FROMLEFT) {
+ pullbarpos = mpos;
+ } else {
+ pullbarpos = pos-mpos;
+ }
+
+ int realMinPixels;
+ if (minpixels)
+ {
+ realMinPixels=minpixels;
+ if (minpixels<0)
+ realMinPixels = (r.bottom - r.top) + minpixels;
+ }
+ else
+ realMinPixels = convertPropToPix(minwidth);
+
+ if (divideside == SDP_FROMLEFT)
+ {
+ if (pullbarpos < realMinPixels)
+ {
+ if (rwchildren[0] != NULL && rwchildren[0]->childNotify(NULL, ChildNotify::FRAMEWND_WINDOWSHADE_CAPABLE, 0, 0)) {
+ pullbarpos = 0;
+ windowshade(0, TRUE);
+ } else {
+ pullbarpos = realMinPixels;
+ }
+ } else {
+ windowshade(0, FALSE);
+ }
+ } else if (divideside == SDP_FROMRIGHT) {
+ if (pullbarpos < realMinPixels) {
+ if (rwchildren[1] != NULL /* && rwchildren[1]->childNotify(NULL, CHILD_WINDOWSHADE_CAPABLE) */) {
+ pullbarpos = /*convertPropToPix(PULLBAR_FULL)-*/0;
+ windowshade(1, TRUE);
+ } else {
+ pullbarpos = realMinPixels;
+ }
+ } else {
+ windowshade(1, FALSE);
+ }
+ }
+
+ if (!windowshaded[0] && !windowshaded[1]) {
+// if (pullbarpos > pos-convertPropToPix(minwidth))
+// pullbarpos = pos-convertPropToPix(minwidth);
+ int realMaxPixels;
+ if (maxpixels || noMaxRestriction)
+ {
+ realMaxPixels=maxpixels;
+ if (maxpixels<0 || noMaxRestriction)
+ {
+ if (vert == DIVIDER_VERTICAL)
+ realMaxPixels = (r.right - r.left) + maxpixels;
+ else
+ realMaxPixels = (r.bottom - r.top) + maxpixels;
+ }
+
+ }
+ else
+ realMaxPixels=convertPropToPix(maxwidth);
+
+ if (pullbarpos > realMaxPixels)
+ pullbarpos = realMaxPixels;
+ }
+
+ ASSERT(pullbarpos >= 0);
+
+ if (pullbarpos != prevpullbarpos && isInited())
+ onResize();
+
+ return 1;
+}
+
+int FrameWnd::onLeftButtonUp(int x, int y) {
+ FRAMEWND_PARENT::onLeftButtonUp(x, y);
+ if (resizing) {
+ endCapture();
+ resizing = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ if (getId() != NULL) {
+ StringPrintfW buf(L"FrameWnd/%s,p", getId());
+ WASABI_API_CONFIG->setIntPrivate(buf, pullbarpos);
+ }
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+void FrameWnd::windowshade(int which, int shaded) {
+ ASSERT(which == 0 || which == 1);
+ if (!!windowshaded[which] == !!shaded) return;
+ if (rwchildren[which] == NULL) return;
+ rwchildren[which]->childNotify(NULL, ChildNotify::FRAMEWND_WINDOWSHADE_ENABLE, shaded, 0);
+ windowshaded[which] = shaded;
+ rwchildren[which]->setVisible(!shaded);
+}
+
+ifc_window *FrameWnd::getWindowShadedChild() {
+ if (nchild != 2) return NULL;
+ if (!(windowshaded[0] | windowshaded[1])) return NULL;
+ return windowshaded[0] ? rwchildren[0] : rwchildren[1];
+}
+
+int FrameWnd::onGetFocus() {
+ postDeferredCallback(DC_FWFOCUS, 0);
+ return 1;
+}
+
+int FrameWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ switch (p1) {
+ case DC_FWFOCUS:
+ if (rwchildren[0]) rwchildren[0]->setFocus();
+ break;
+ default:
+ return FRAMEWND_PARENT::onDeferredCallback(p1, p2);
+ }
+ return 1;
+}
+
+
+void FrameWnd::setSnap(int snap)
+{
+ if (snap>0)
+ SNAP=snap;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/framewnd.h b/Src/Wasabi/api/wnd/wndclass/framewnd.h
new file mode 100644
index 00000000..506426e6
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/framewnd.h
@@ -0,0 +1,124 @@
+//NONPORTABLE
+#ifndef _FRAMEWND_H
+#define _FRAMEWND_H
+
+#include <bfc/common.h>
+#include <api/wnd/wndclass/labelwnd.h>
+#include <tataki/bitmap/autobitmap.h>
+
+#define MAXCHILD 2 // this had better never not be 2
+
+typedef enum {
+ DIVIDER_HORIZONTAL, DIVIDER_VERTICAL, DIVIDER_UNDEFINED = -1
+} FrameWndDividerType;
+enum { SDP_FROMLEFT, SDP_FROMRIGHT };
+#define SDP_FROMTOP SDP_FROMLEFT
+#define SDP_FROMBOTTOM SDP_FROMRIGHT
+
+typedef enum {
+ FRAMEWND_SQUISH,
+ FRAMEWND_COVER
+} FrameWndSlideMode;
+
+#define SIZERWIDTH 8
+
+// this window holds other basewnd derived classes
+#define FRAMEWND_PARENT LabelWnd
+class FrameWnd : public FRAMEWND_PARENT {
+public:
+ FrameWnd();
+ virtual ~FrameWnd();
+
+ virtual int onInit();
+
+ virtual int getCursorType(int x, int y);
+
+ virtual int onPaint(Canvas *canvas);
+ virtual int onResize();
+
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onMouseMove(int x, int y); // only called when mouse captured
+ virtual int onLeftButtonUp(int x, int y);
+
+ virtual int childNotify(ifc_window *which, int msg, intptr_t param1, intptr_t param2);
+
+// virtual int forceFocus();
+
+ // unique to this class
+ int setChildren(BaseWnd *child1, BaseWnd *child2=NULL);
+ int setChildrenRootWnd(ifc_window *child1, ifc_window *child2=NULL);
+ ifc_window *enumChild(int which);
+ // horizontal or vertical?
+ void setDividerType(FrameWndDividerType type);
+ FrameWndDividerType getDividerType();
+ // where is the divider?
+ int setDividerPos(int from, int pos);
+ // this version doesn't check the cfg file for last position
+ int setDividerPosNoCfg(int from, int pos);
+ void getDividerPos(int *from, int *pos);
+
+ int setResizeable(int is);
+ void setMinWidth(int min);
+ void setMaxWidth(int max);
+ void setSnap(int snap);
+
+ virtual int onGetFocus();
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ // cover or squish
+ void setSlideMode(FrameWndSlideMode mode);
+ FrameWndSlideMode getSlideMode();
+
+ virtual void onResizeChildren(RECT leftr, RECT rightr);
+
+ // drag and drops are forwarded into windowshaded windows
+ virtual int dragEnter(ifc_window *sourceWnd);
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual int dragLeave(ifc_window *sourceWnd);
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
+
+protected:
+ int convertPropToPix(int prop);
+ int ConvertPixToProp();
+
+ void windowshade(int which, int shaded);
+ ifc_window *getWindowShadedChild();
+
+ void Set_v_bitmap(const wchar_t *new_v_bitmap);
+ void Set_v_grabber(const wchar_t *new_v_grabber);
+
+private:
+ int _setChildren(ifc_window *child1, ifc_window *child2, BaseWnd *child1b, BaseWnd *child2b);
+ int nchild;
+ BaseWnd *children[MAXCHILD];
+ ifc_window *rwchildren[MAXCHILD];
+ int hidey[MAXCHILD];
+ int windowshaded[MAXCHILD];
+
+ FrameWndDividerType vert;
+
+ int resizeable;
+ FrameWndSlideMode slidemode;
+
+ int divideside;
+ int pullbarpos; // 0..65536
+ int prevpullbarpos;
+ int minwidth, maxwidth;
+ int maxpixels;
+ boolean noMaxRestriction;
+ int minpixels;
+ int snapoffsetx, snapoffsety;
+ int SNAP;
+ RECT sizerRect;
+
+ AutoSkinBitmap h_bitmap, v_bitmap, h_grabber, v_grabber, ws_bitmap;
+ int resizing;
+};
+
+#define PULLBAR_FULL 65536L
+#define PULLBAR_HALF (PULLBAR_FULL/2)
+#define PULLBAR_QUARTER (PULLBAR_FULL/4)
+#define PULLBAR_THREEQUARTER (PULLBAR_FULL-PULLBAR_QUARTER)
+#define PULLBAR_EIGHTH (PULLBAR_FULL/8)
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/gradientwnd.cpp b/Src/Wasabi/api/wnd/wndclass/gradientwnd.cpp
new file mode 100644
index 00000000..f34b31f9
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/gradientwnd.cpp
@@ -0,0 +1,82 @@
+#include <precomp.h>
+
+#include "gradientwnd.h"
+
+
+// NOTE
+// works now ;)
+
+GradientWnd::GradientWnd()
+: bitmap(4,4, getOsWindowHandle())
+{
+ cache_w = cache_h = 4;
+ last_w = last_h = -1;
+ recreate = 1;
+ setReverseColors(TRUE);
+}
+
+GradientWnd::~GradientWnd()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
+}
+
+int GradientWnd::onInit ()
+{
+ int r = GRADIENTWND_PARENT::onInit();
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
+ return r;
+}
+
+int GradientWnd::onPaint(Canvas *canvas)
+{
+ ASSERT(canvas != NULL);
+ RECT cr = clientRect();
+
+ int w = cr.right - cr.left, h = cr.bottom - cr.top;
+ if (w && h)
+ {
+ if (w != last_w || h != last_h)
+ {
+ recreate=1;
+ }
+ if (w > cache_w || h > cache_h)
+ {
+ cache_w = max(w, cache_w);
+ cache_h = max(h, cache_h);
+ // round up to nearest 4
+ cache_w = (cache_w+3) & ~3;
+ cache_h = (cache_h+3) & ~3;
+
+ bitmap.DestructiveResize(cache_w,cache_h,32);
+ recreate = 1;
+ }
+
+ if (recreate)
+ {
+ ARGB32 *bits = static_cast<ARGB32*>(bitmap.getBits());
+ renderGradient(bits, w, h, /*pitch=*/cache_w);
+ last_w = w;
+ last_h = h;
+ recreate=0;
+ }
+ RECT src = {0,0,w,h};
+ bitmap./*getSkinBitmap()->*/blitToRect(canvas, &src, &cr, getPaintingAlpha());
+ //bitmap./*getSkinBitmap()->*/blitAlpha(canvas, cr.left, cr.top, getPaintingAlpha());
+ }
+ return 1;
+}
+
+void GradientWnd::onParamChange()
+{
+ invalidate();
+ recreate = 1;
+}
+
+int GradientWnd::skincb_onColorThemeChanged(const wchar_t *newcolortheme)
+{
+ // TODO: This will refresh after ca 1 sec - we need an instand redraw
+ invalidate();
+ recreate = 1;
+ return 0;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/gradientwnd.h b/Src/Wasabi/api/wnd/wndclass/gradientwnd.h
new file mode 100644
index 00000000..c7c02695
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/gradientwnd.h
@@ -0,0 +1,31 @@
+#ifndef _GRADIENTWND_H
+#define _GRADIENTWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/draw/gradient.h>
+#include <tataki/canvas/bltcanvas.h>
+
+#define GRADIENTWND_PARENT GuiObjectWnd
+class GradientWnd : public GRADIENTWND_PARENT, public Gradient, public SkinCallbackI {
+public:
+ GradientWnd();
+ virtual ~GradientWnd();
+
+ virtual int onPaint(Canvas *canvas);
+
+protected:
+ virtual void onParamChange();
+
+private:
+ int recreate;
+
+ int last_w, last_h;
+ int cache_w, cache_h;
+ BltCanvas bitmap;
+
+protected:
+ int onInit();
+ int skincb_onColorThemeChanged(const wchar_t *newcolortheme);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/guiobjwnd.cpp b/Src/Wasabi/api/wnd/wndclass/guiobjwnd.cpp
new file mode 100644
index 00000000..fcb70d0c
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/guiobjwnd.cpp
@@ -0,0 +1,476 @@
+#include <precomp.h>
+#include <api/script/api_maki.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptobj.h>
+#include <api/script/scriptguid.h>
+#include <api/service/svcs/svc_droptarget.h>
+#include <api/wnd/notifmsg.h>
+#include <api/script/objects/rootobject.h>
+#include <api/locales/xlatstr.h>
+
+XMLParamPair GuiObjectWnd::params[] =
+ {
+ {GUIOBJECT_ACTIVEALPHA, L"ACTIVEALPHA"},
+ {GUIOBJECT_ALPHA, L"ALPHA"},
+ {GUIOBJECT_SETANCHOR, L"ANCHOR"},
+#ifdef USEAPPBAR
+ {GUIOBJECT_APPBAR, L"APPBAR"},
+#endif
+ {GUIOBJECT_CFGATTR, L"CFGATTRIB"},
+ {GUIOBJECT_SETCURSOR, L"CURSOR"},
+ {GUIOBJECT_DROPTARGET, L"DROPTARGET"},
+ {GUIOBJECT_ENABLED, L"ENABLED"},
+ {GUIOBJECT_FITTOPARENT, L"FITPARENT"},
+ {GUIOBJECT_FOCUSONCLICK, L"FOCUSONCLICK"},
+ {GUIOBJECT_GHOST, L"GHOST"},
+ {GUIOBJECT_H, L"H"},
+ {GUIOBJECT_ID, L"ID"},
+ {GUIOBJECT_INACTIVEALPHA, L"INACTIVEALPHA"},
+ {GUIOBJECT_MOVE, L"MOVE"},
+ {GUIOBJECT_SETNOCONTEXTMENU, L"NOCONTEXTMENU"},
+ {GUIOBJECT_SETNODBLCLICK, L"NODBLCLICK"},
+ {GUIOBJECT_SETNOLEFTCLICK, L"NOLEFTCLICK"},
+ {GUIOBJECT_SETNOMOUSEMOVE, L"NOMOUSEMOVE"},
+ {GUIOBJECT_SETNORIGHTCLICK, L"NORIGHTCLICK"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY0"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY1"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY2"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY3"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY4"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY5"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY6"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY7"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY8"},
+ {GUIOBJECT_NOTIFY, L"NOTIFY9"},
+ {GUIOBJECT_RECTRGN, L"RECTRGN"},
+ {GUIOBJECT_SYSREGION, L"REGIONOP"},
+ {GUIOBJECT_RELATH, L"RELATH"},
+ {GUIOBJECT_RELATW, L"RELATW"},
+ {GUIOBJECT_RELATX, L"RELATX"},
+ {GUIOBJECT_RELATY, L"RELATY"},
+ {GUIOBJECT_RENDERBASETEXTURE, L"RENDERBASETEXTURE"},
+ {GUIOBJECT_SYSMETRICSX, L"SYSMETRICSX"},
+ {GUIOBJECT_SYSMETRICSY, L"SYSMETRICSY"},
+ {GUIOBJECT_SYSMETRICSW, L"SYSMETRICSW"},
+ {GUIOBJECT_SYSMETRICSH, L"SYSMETRICSH"},
+ {GUIOBJECT_SYSREGION, L"SYSREGION"},
+ {GUIOBJECT_TABORDER, L"TABORDER"},
+ {GUIOBJECT_TOOLTIP, L"TOOLTIP"},
+ {GUIOBJECT_TRANSLATE, L"TRANSLATE"},
+ {GUIOBJECT_USERDATA, L"USERDATA"},
+ {GUIOBJECT_VISIBLE, L"VISIBLE"},
+ {GUIOBJECT_W, L"W"},
+ {GUIOBJECT_WANTFOCUS, L"WANTFOCUS"},
+ {GUIOBJECT_X, L"X"},
+ {GUIOBJECT_SETX1, L"X1"},
+ {GUIOBJECT_SETX2, L"X2"},
+ {GUIOBJECT_Y, L"Y"},
+ {GUIOBJECT_SETY1, L"Y1"},
+ {GUIOBJECT_SETY2, L"Y2"},
+ };
+
+GuiObjectWnd::GuiObjectWnd()
+{
+ my_gui_object = static_cast<GuiObject *>(WASABI_API_MAKI->maki_encapsulate(guiObjectGuid, getScriptObject()));
+ getScriptObject()->vcpu_setInterface(xmlObjectGuid, static_cast<XmlObject *>(this));
+ getScriptObject()->vcpu_setInterface(guiObjectWndGuid, static_cast<GuiObjectWnd *>(this));
+#ifdef USEAPPBAR
+ getScriptObject()->vcpu_setInterface(appBarGuid, static_cast<AppBar*>(this));
+#endif
+ my_gui_object->guiobject_setRootWnd(this);
+ getScriptObject()->vcpu_setClassName(L"GuiObject");
+ getScriptObject()->vcpu_setController(WASABI_API_MAKI->maki_getController(guiObjectGuid));
+ cfg_reentry = 0;
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+}
+
+void GuiObjectWnd::CreateXMLParameters(int master_handle)
+{
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+GuiObjectWnd::~GuiObjectWnd()
+{
+ WASABI_API_MAKI->maki_deencapsulate(guiObjectGuid, my_gui_object);
+ my_gui_object = NULL;
+}
+
+const wchar_t *GuiObjectWnd::getTip()
+{
+ switch(wantTranslation())
+ {
+ case 1:
+ return _(tip);
+ case 2:
+return __(tip);
+ default:
+ return tip;
+ }
+}
+
+int GuiObjectWnd::onRightButtonDown(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onRightButtonDown(x, y);
+ my_gui_object->guiobject_onRightButtonDown(x, y);
+ return 1;
+}
+
+int GuiObjectWnd::onRightButtonUp(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onRightButtonUp(x, y);
+ my_gui_object->guiobject_onRightButtonUp(x, y);
+ return 1;
+}
+
+int GuiObjectWnd::onLeftButtonDown(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onLeftButtonDown(x, y);
+ my_gui_object->guiobject_onLeftButtonDown(x, y);
+ return 1;
+}
+
+int GuiObjectWnd::onLeftButtonUp(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onLeftButtonUp(x, y);
+ my_gui_object->guiobject_onLeftButtonUp(x, y);
+ return 1;
+}
+
+int GuiObjectWnd::onMouseMove(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onMouseMove(x, y);
+ my_gui_object->guiobject_onMouseMove(x, y);
+ return 1;
+}
+
+int GuiObjectWnd::wantTranslation()
+{
+ if (!my_gui_object) return 1;
+ return my_gui_object->guiobject_wantTranslation();
+}
+
+int GuiObjectWnd::onLeftButtonDblClk(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onLeftButtonDblClk(x, y);
+ my_gui_object->guiobject_onLeftButtonDblClk(x, y);
+ return 1;
+}
+
+int GuiObjectWnd::onRightButtonDblClk(int x, int y)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onRightButtonDblClk(x, y);
+ my_gui_object->guiobject_onRightButtonDblClk(x, y);
+ return 1;
+}
+
+// Martin> For the next two functions, we need to ensure that we don't kill volume change if nothing is done
+int GuiObjectWnd::onMouseWheelDown (int click, int line)
+{
+ if (!my_gui_object) return 1;
+ int ret = GUIOBJECTWND_PARENT::onMouseWheelDown(click, line);
+ if (!ret) ret = my_gui_object->guiobject_onMouseWheelDown(click, line);
+ return ret;
+}
+
+int GuiObjectWnd::onMouseWheelUp (int click, int line)
+{
+ if (!my_gui_object) return 1;
+ int ret = GUIOBJECTWND_PARENT::onMouseWheelUp(click, line);
+ if (!ret) ret = my_gui_object->guiobject_onMouseWheelUp(click, line);
+ return ret;
+}
+
+int GuiObjectWnd::onResize()
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onResize();
+ if (!isInited()) return 1;
+ ifc_window *w = my_gui_object->guiobject_getRootWnd();
+ RECT r;
+ w->getClientRect(&r);
+ my_gui_object->guiobject_onResize(r.left, r.top, r.right - r.left, r.bottom - r.top);
+ return 1;
+}
+
+void GuiObjectWnd::onEnterArea()
+{
+ if (!my_gui_object) return ;
+ GUIOBJECTWND_PARENT::onEnterArea();
+ my_gui_object->guiobject_onEnterArea();
+}
+
+void GuiObjectWnd::onLeaveArea()
+{
+ if (!my_gui_object) return ;
+ GUIOBJECTWND_PARENT::onLeaveArea();
+ my_gui_object->guiobject_onLeaveArea();
+}
+
+void GuiObjectWnd::onSetVisible(int show)
+{
+ if (!my_gui_object)
+ return ;
+
+ GUIOBJECTWND_PARENT::onSetVisible(show);
+ my_gui_object->guiobject_onSetVisible(show);
+}
+
+int GuiObjectWnd::onEnable(int en)
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onEnable(en);
+ my_gui_object->guiobject_onEnable(en);
+ return 1;
+}
+
+GuiObject *GuiObjectWnd::getGuiObject()
+{
+ return my_gui_object;
+}
+
+RootObject *GuiObjectWnd::getRootObject()
+{
+ return my_gui_object->guiobject_getRootObject();
+}
+
+int GuiObjectWnd::dragDrop(ifc_window *sourceWnd, int x, int y)
+{
+ int r = DropTargetEnum::throwDrop(my_gui_object->guiobject_getDropTarget(), sourceWnd, x, y);
+ if (r == 0)
+ {
+ ifc_window *p = getParent();
+ if (p != NULL)
+ {
+ DragInterface *d = p->getDragInterface();
+ if (d != NULL)
+ return d->dragDrop(sourceWnd, x, y);
+ }
+ }
+ return r;
+}
+
+int GuiObjectWnd::dragEnter(ifc_window *sourceWnd)
+{
+ my_gui_object->guiobject_dragEnter(sourceWnd);
+ return 1;
+}
+
+int GuiObjectWnd::dragOver(int x, int y, ifc_window *sourceWnd)
+{
+ my_gui_object->guiobject_dragOver(x, y, sourceWnd);
+ return 1;
+}
+
+int GuiObjectWnd::dragLeave(ifc_window *sourceWnd)
+{
+ my_gui_object->guiobject_dragLeave(sourceWnd);
+ return 1;
+}
+
+int GuiObjectWnd::onActivate()
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onActivate();
+ invalidate();
+ return 1;
+}
+
+int GuiObjectWnd::onDeactivate()
+{
+ if (!my_gui_object) return 1;
+ GUIOBJECTWND_PARENT::onDeactivate();
+ invalidate();
+ return 1;
+}
+
+void GuiObjectWnd::onCancelCapture()
+{
+ if (!my_gui_object) return ;
+ GUIOBJECTWND_PARENT::onCancelCapture();
+ my_gui_object->guiobject_onCancelCapture();
+}
+
+int GuiObjectWnd::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *value)
+{
+ if (_xuihandle == xuihandle)
+ {
+ switch (attrid)
+ {
+ case GUIOBJECT_FOCUSONCLICK:
+ setFocusOnClick(WTOI(value));
+ break;
+ default:
+ getGuiObject()->guiobject_setXmlParamById(attrid, value);
+ break;
+ }
+ }
+ return 0;
+}
+
+int GuiObjectWnd::onUnknownXmlParam(const wchar_t *param, const wchar_t *value)
+{
+ return onUnknownXuiParam(param, value);
+}
+
+int GuiObjectWnd::setXmlParamById(int xmlhandle, int attrid, const wchar_t *name, const wchar_t *value)
+{
+ return setXuiParam(xmlhandle, attrid, name, value);
+}
+
+void *GuiObjectWnd::getInterface(GUID interface_guid)
+{
+ void *r = GUIOBJECTWND_PARENT::getInterface(interface_guid);
+ if (r) return r;
+ return getRootObject()->rootobject_getScriptObject()->vcpu_getInterface(interface_guid);
+}
+
+int GuiObjectWnd::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (!_wcsicmp(action, L"reload_config") && isInited())
+ {
+ if (cfg_reentry) return 1;
+ cfg_reentry = 1;
+ int r = onReloadConfig();
+ cfg_reentry = 0;
+ return r;
+ }
+#endif
+ int rt = GUIOBJECTWND_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ getGuiObject()->guiobject_onAction(action, param, x, y, p1, p2, data, datalen, source);
+ return rt;
+}
+
+void GuiObjectWnd::setContent(const wchar_t *groupid_orguid, int autoresizefromcontent)
+{
+#ifdef WASABI_COMPILE_SKIN
+
+ // abstract_setAllowDeferredContent(0);
+ abstract_setContent(groupid_orguid, autoresizefromcontent);
+#endif
+}
+
+void GuiObjectWnd::setContentBySkinItem(SkinItem *item, int autoresizefromcontent)
+{
+ // abstract_setAllowDeferredContent(0);
+#ifdef WASABI_COMPILE_SKIN
+ abstract_setContentBySkinItem(item, autoresizefromcontent);
+#endif
+}
+
+void GuiObjectWnd::abstract_onNewContent()
+{
+
+#ifdef WASABI_COMPILE_SKIN
+ GUIOBJECTWND_PARENT::abstract_onNewContent();
+#endif
+ onNewContent();
+#ifdef WASABI_COMPILE_CONFIG
+ if (getGuiObject()->guiobject_hasCfgAttrib())
+ onReloadConfig();
+#endif
+}
+
+GuiObject *GuiObjectWnd::findObject(const wchar_t *object_id)
+{
+ return getGuiObject()->guiobject_findObject(object_id);
+}
+
+#ifdef WASABI_COMPILE_SCRIPT
+ScriptObject *GuiObjectWnd::findScriptObject(const wchar_t *object_id)
+{
+ GuiObject *fo = getGuiObject()->guiobject_findObject(object_id);
+ if (fo != NULL) return fo->guiobject_getScriptObject();
+ return NULL;
+}
+#endif
+const wchar_t *GuiObjectWnd::getId()
+{
+ if (my_gui_object)
+ return my_gui_object->guiobject_getId();
+ return GUIOBJECTWND_PARENT::getId();
+}
+
+int GuiObjectWnd::onPostOnInit()
+{
+ int r = GUIOBJECTWND_PARENT::onPostOnInit();
+#ifdef WASABI_COMPILE_CONFIG
+ if (getGuiObject()->guiobject_hasCfgAttrib())
+ onReloadConfig();
+#endif
+ return r;
+}
+
+int GuiObjectWnd::onInit()
+{
+ int r = GUIOBJECTWND_PARENT::onInit();
+ getGuiObject()->guiobject_onInit();
+ return r;
+}
+
+int GuiObjectWnd::onChar(unsigned int c)
+{
+ if (!my_gui_object) return 1;
+ int r = GUIOBJECTWND_PARENT::onChar(c);
+ getGuiObject()->guiobject_onChar(c);
+ return r;
+}
+
+int GuiObjectWnd::onKeyDown(int vkcode)
+{
+ if (!my_gui_object) return 1;
+ int r = GUIOBJECTWND_PARENT::onKeyDown(vkcode);
+ getGuiObject()->guiobject_onKeyDown(vkcode);
+ return r;
+}
+
+int GuiObjectWnd::onKeyUp(int vkcode)
+{
+ if (!my_gui_object) return 1;
+ int r = GUIOBJECTWND_PARENT::onKeyUp(vkcode);
+ getGuiObject()->guiobject_onKeyUp(vkcode);
+ return r;
+}
+
+int GuiObjectWnd::onGetFocus()
+{
+ if (!my_gui_object) return 1;
+ int r = GUIOBJECTWND_PARENT::onGetFocus();
+ getGuiObject()->guiobject_onGetFocus();
+ return r;
+}
+
+int GuiObjectWnd::onKillFocus()
+{
+ if (!my_gui_object) return 1;
+ int r = GUIOBJECTWND_PARENT::onKillFocus();
+ getGuiObject()->guiobject_onKillFocus();
+ return r;
+}
+
+int GuiObjectWnd::onAcceleratorEvent(const wchar_t *name)
+{
+ int r = GUIOBJECTWND_PARENT::onAcceleratorEvent(name);
+ getGuiObject()->guiobject_onAccelerator(name);
+ return r;
+}
+
+int GuiObjectWnd::wantFocus()
+{
+ if (GUIOBJECTWND_PARENT::wantFocus()) return 1;
+ if (my_gui_object)
+ return my_gui_object->guiobject_wantFocus();
+ return 0;
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/guiobjwnd.h b/Src/Wasabi/api/wnd/wndclass/guiobjwnd.h
new file mode 100644
index 00000000..f172c92f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/guiobjwnd.h
@@ -0,0 +1,237 @@
+#ifndef __GUIOBJWND_H
+#define __GUIOBJWND_H
+
+#if defined(WIN32) || defined(WIN64)
+#define USEAPPBAR
+#endif
+
+#ifdef USEAPPBAR
+#include <api/wnd/wndclass/appbarwnd.h>
+#define GUIOBJECTWND_PARENT AppBarWnd
+#else
+#include <api/wnd/wndclass/clickwnd.h>
+#define GUIOBJECTWND_PARENT ClickWnd
+#endif
+
+#include <api/script/scriptobj.h>
+#include <api/script/objects/guiobject.h>
+#include <api/script/objects/rootobj.h>
+#include <api/skin/xmlobject.h>
+#include <api/service/svcs/svc_xuiobject.h>
+
+// {E5760861-5489-4ffc-BE02-061D9DA6CD1B}
+const GUID guiObjectWndGuid =
+ { 0xe5760861, 0x5489, 0x4ffc, { 0xbe, 0x2, 0x6, 0x1d, 0x9d, 0xa6, 0xcd, 0x1b } };
+
+#define XUI_ATTRIBUTE_IMPLIED XML_ATTRIBUTE_IMPLIED
+#define XUI_ATTRIBUTE_REQUIRED XML_ATTRIBUTE_REQUIRED
+
+class GuiObjectWnd : public GUIOBJECTWND_PARENT, public RootObjectInstance, public XmlObjectI
+{
+public:
+ GuiObjectWnd();
+ virtual ~GuiObjectWnd();
+
+#ifdef WASABI_COMPILE_CONFIG
+ virtual int onReloadConfig() { return 1; }
+#endif
+
+ // XmlObject
+
+ virtual int setXmlParamById(int xmlhandle, int attrid, const wchar_t *name, const wchar_t *value);
+ virtual int onUnknownXmlParam(const wchar_t *param, const wchar_t *value);
+ virtual int newXuiHandle() { return newXmlHandle(); }
+
+ // ClickWnd
+
+ virtual int onRightButtonDown(int x, int y);
+ virtual int onRightButtonUp(int x, int y);
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onMouseMove(int x, int y);
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int onRightButtonDblClk(int x, int y);
+ virtual int onMouseWheelUp(int click, int lines);
+ virtual int onMouseWheelDown(int click, int lines);
+ virtual int onResize();
+ virtual int onActivate();
+ virtual int onDeactivate();
+ virtual void onEnterArea();
+ virtual void onLeaveArea();
+ virtual void onSetVisible(int show);
+ virtual int onEnable(int en);
+ virtual void onCancelCapture();
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
+ virtual int acceptExternalDrops() { return 1; }
+ virtual int dragEnter(ifc_window *sourceWnd);
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual int dragLeave(ifc_window *sourceWnd);
+ virtual void *getInterface(GUID g);
+ virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+ virtual const wchar_t *getId();
+ virtual int onAcceleratorEvent(const wchar_t *name);
+
+ virtual void setContent(const wchar_t *groupid_orguid, int autoresizefromcontent = 0);
+ virtual void setContentBySkinItem(SkinItem *item, int autoresizefromcontent = 0);
+ virtual void onNewContent() {}
+
+ // AbstractWndHolder
+ virtual void abstract_onNewContent();
+
+
+ virtual int onUnknownXuiParam(const wchar_t *param, const wchar_t *value) { return 0; }
+
+ virtual GuiObject *findObject(const wchar_t *object_id);
+#ifdef WASABI_COMPILE_SCRIPT
+ virtual ScriptObject *findScriptObject(const wchar_t *object_id);
+#endif
+#ifdef WASABI_COMPILE_SKIN
+ virtual GuiObject *getContent() { return abstract_getContent(); }
+ virtual ScriptObject *getContentScriptObject() { return abstract_getContentScriptObject(); }
+ virtual ifc_window *getContentRootWnd() { return abstract_getContentRootWnd(); }
+#endif
+
+ // BaseWnd
+
+ virtual int onInit();
+ virtual int onPostOnInit();
+ virtual int onChar(unsigned int c);
+ virtual int onKeyDown(int vkcode);
+ virtual int onKeyUp(int vkcode);
+
+ virtual int onGetFocus();
+ virtual int onKillFocus();
+ virtual int wantFocus();
+
+ const wchar_t *getTip();
+ // GuiObjectWnd
+ int wantTranslation();
+ GuiObject *getGuiObject();
+ RootObject *getRootObject();
+ int cfg_reentry;
+
+ // XuiObject
+ virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *value);
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+private:
+ GuiObject *my_gui_object;
+ int xuihandle;
+ static XMLParamPair params[];
+
+
+public:
+
+ enum {
+ GUIOBJECT_ID = 0,
+ GUIOBJECT_ALPHA,
+ GUIOBJECT_ACTIVEALPHA,
+ GUIOBJECT_INACTIVEALPHA,
+ GUIOBJECT_SYSREGION,
+ GUIOBJECT_RECTRGN,
+ GUIOBJECT_TOOLTIP,
+ GUIOBJECT_SYSMETRICSX,
+ GUIOBJECT_SYSMETRICSY,
+ GUIOBJECT_SYSMETRICSW,
+ GUIOBJECT_SYSMETRICSH,
+ GUIOBJECT_MOVE,
+ GUIOBJECT_RENDERBASETEXTURE,
+ GUIOBJECT_CFGATTR,
+ GUIOBJECT_X,
+ GUIOBJECT_Y,
+ GUIOBJECT_W,
+ GUIOBJECT_H,
+ GUIOBJECT_VISIBLE,
+ GUIOBJECT_ENABLED,
+ GUIOBJECT_RELATX,
+ GUIOBJECT_RELATY,
+ GUIOBJECT_RELATW,
+ GUIOBJECT_RELATH,
+ GUIOBJECT_DROPTARGET,
+ GUIOBJECT_GHOST,
+ GUIOBJECT_NOTIFY,
+ GUIOBJECT_FOCUSONCLICK,
+ GUIOBJECT_TABORDER,
+ GUIOBJECT_WANTFOCUS,
+ GUIOBJECT_SETNODBLCLICK,
+ GUIOBJECT_SETNOLEFTCLICK,
+ GUIOBJECT_SETNORIGHTCLICK,
+ GUIOBJECT_SETNOMOUSEMOVE,
+ GUIOBJECT_SETNOCONTEXTMENU,
+ GUIOBJECT_SETX1,
+ GUIOBJECT_SETY1,
+ GUIOBJECT_SETX2,
+ GUIOBJECT_SETY2,
+ GUIOBJECT_SETANCHOR,
+ GUIOBJECT_SETCURSOR,
+ GUIOBJECT_FITTOPARENT,
+ GUIOBJECT_USERDATA,
+#ifdef USEAPPBAR
+ GUIOBJECT_APPBAR,
+#endif
+ GUIOBJECT_TRANSLATE,
+ GUIOBJECT_NUMPARAMS
+ };
+
+
+};
+
+template <class T, const wchar_t XMLTAG[], char SVCNAME[]>
+class XuiObjectSvc : public svc_xuiObjectI
+{
+public:
+ static const wchar_t *xuisvc_getXmlTag() { return XMLTAG; }
+
+ int testTag(const wchar_t *xmltag)
+ {
+ if (!WCSICMP(xmltag, XMLTAG)) return 1;
+ return 0;
+ }
+ GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params = NULL)
+ {
+ if (testTag(xmltag))
+ {
+ T * obj = new T;
+ ASSERT(obj != NULL);
+ return obj->getGuiObject();
+ }
+ return NULL;
+ }
+ void destroy(GuiObject *g)
+ {
+ T *obj = static_cast<T *>(g->guiobject_getRootWnd());
+ delete obj;
+ }
+ static const char *getServiceName() { return SVCNAME; }
+};
+
+template <class T>
+class XuiObjectSvc2 : public svc_xuiObjectI
+{
+public:
+ static const wchar_t *xuisvc_getXmlTag() { return T::xuiobject_getXmlTag(); }
+ int testTag(const wchar_t *xmltag)
+ {
+ if (!WCSICMP(xmltag, T::xuiobject_getXmlTag())) return 1;
+ return 0;
+ }
+ GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params = NULL)
+ {
+ if (testTag(xmltag))
+ {
+ T * obj = new T;
+ ASSERT(obj != NULL);
+ return obj->getGuiObject();
+ }
+ return NULL;
+ }
+ void destroy(GuiObject *g)
+ {
+ T *obj = static_cast<T *>(g->guiobject_getRootWnd());
+ delete obj;
+ }
+ static const char *getServiceName() { return T::xuiobject_getServiceName(); }
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/itemlistwnd.cpp b/Src/Wasabi/api/wnd/wndclass/itemlistwnd.cpp
new file mode 100644
index 00000000..1ff97732
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/itemlistwnd.cpp
@@ -0,0 +1,286 @@
+#include "precomp.h"
+
+#include "itemlistwnd.h"
+#include "../../common/metatags.h"
+
+#include "../../studio/api.h"
+
+#include "../skinclr.h"
+#include "../../common/filename.h"
+
+#include "../../common/dragitemi.h"
+#include "../../common/contextmenu.h"
+
+#define NIFTY_OUTLINE
+
+static SkinColor current("wasabi.itemlist.outline.current");
+static SkinColor selborder("wasabi.itemlist.selborder");
+static SkinColor focus("wasabi.itemlist.outline.focus");
+
+ItemListColumn_MetaTag::ItemListColumn_MetaTag(const char *newtag, int centered, const char *label)
+ : ItemListColumn() {
+ if (label == NULL) label = newtag;
+ setLabel(label);
+ tag = newtag;
+ center = centered;
+ datatype = api->metadb_getMetaDataType(tag);
+}
+
+ItemListColumn_Callback::ItemListColumn_Callback(ItemListWnd *_parent, LPARAM _lparam, const char *name)
+: ItemListColumn(name)
+{
+ parent = _parent;
+ lparam = _lparam;
+}
+
+void ItemListColumn_Callback::render(int pos, const char *playstring, Canvas &c, RECT &r) {
+ parent->userRender(pos, playstring, c, r, lparam);
+}
+
+void ItemListColumn_Callback::columnToText(int pos, const char *playstring, char *str, int maxlen) {
+ parent->userColumnToText(pos, playstring, lparam, str, maxlen);
+}
+
+void ItemListColumn_MetaTag::render(int pos, const char *playstring, Canvas &canvas, RECT &r) {
+ char buf[4096]="";
+ if (api->metadb_getMetaData(playstring, tag, buf, 4096) <= 1) return;
+ api->metadb_renderData(&canvas, r, buf, datatype, center);
+}
+
+void ItemListColumn_MetaTag::columnToText(int pos, const char *playstring, char *str, int maxlen) {
+ api->metadb_getMetaData(playstring, tag, str, maxlen);
+}
+
+const char *ItemListColumn_MetaTag::getTag() {
+ return tag;
+}
+
+void ItemListColumn_Numbered::render(int pos, const char *playstring, Canvas &c, RECT &r) {
+ StringPrintf buf("%d.", pos+1);
+ c.textOutEllipsed(r.left, r.top, r.right - r.left, r.bottom-r.top, buf);
+}
+
+void ItemListColumn_Numbered::columnToText(int pos, const char *playstring, char *str, int maxlen) {
+ StringPrintf buf("%d", pos+1);
+ STRNCPY(str, buf, maxlen);
+}
+
+ItemListWnd::ItemListWnd() {
+ keep = NULL;
+ item_invalidate_border++;
+}
+
+ItemListWnd::~ItemListWnd() {
+ api->syscb_deregisterCallback(static_cast<MetaCallbackI *>(this));
+}
+
+int ItemListWnd::onInit() {
+
+ ITEMLISTWND_PARENT::onInit();
+
+ api->syscb_registerCallback(static_cast<MetaCallbackI *>(this));
+
+ return 1;
+}
+
+int ItemListWnd::insertColumn(ItemListColumn *column, int width, int pos) {
+ column->setWidth(width);
+ return ITEMLISTWND_PARENT::insertColumn(column, pos);
+}
+
+int ItemListWnd::onBeginDrag(int iItem) {
+
+ if (!wantAutoDrag()) return ITEMLISTWND_PARENT::onBeginDrag(iItem);
+
+ // add all the entries
+ int n, i, c = 0;
+ n = getNumItems();
+ if (n == 0) return 0; // empty list
+
+ ASSERT(keep == NULL);
+ keep = new PtrList<FilenameNC>();
+
+ // count up the items
+ for (i = 0; i < n; i++) {
+ if (getItemSelected(i)) { // expose all the pointers we can
+ LPARAM lparam = getItemData(i);
+ if (!addMoreDragTypes(i)) {
+ FilenameNC *fn = keep->addItem(new FilenameNC(convertlParam(lparam)));
+ addDragItem(DD_FILENAME, static_cast<Filename*>(fn));
+ }
+ c++;
+ }
+ }
+
+ if (keep->getNumItems() == 0 || c <= 0) {
+ delete keep; keep = NULL;
+ return 0;
+ }
+
+ handleDrag();
+
+ return 1;
+}
+
+int ItemListWnd::dragComplete(int success) {
+ ASSERT(keep != NULL);
+
+ keep->deleteAll();
+ delete keep; keep = NULL;
+
+ return 1;
+}
+
+int ItemListWnd::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) {
+ const char *playstring = convertlParam(lParam);
+ if (playstring == NULL) return 0;
+ COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam);
+ COLORREF fgcolor = getTextColor(lParam);
+ int iscur = getSelected(lParam);
+
+ RECT box;
+ canvas->getClipBox(&box);
+
+ if (!getBgBitmap()) {
+ RECT r2 = *r;
+ r2.left = box.left;
+ RegionI *reg = new RegionI(&r2);
+ canvas->selectClipRgn(reg);
+ delete reg;
+ canvas->fillRect(r, getBgColor());
+ }
+
+ canvas->setTextColor(fgcolor);
+
+// ASSERT(cols.getNumItems() == getNumColumns());
+
+ if (isselected) {
+ RECT mr = *r;
+ canvas->fillRect(&mr, bgcolor);
+/*au gratin potatoes/broccoli
+chicken^2
+salad, croutons, cheese, ranch
+fries */
+#ifdef NIFTY_OUTLINE
+ int prevsel = getItemSelected(pos-1);
+ int nextsel = getItemSelected(pos+1);
+ mr.bottom--;
+ canvas->pushPen(selborder);
+ canvas->lineDraw(mr.left, mr.top, mr.left, mr.bottom);
+ canvas->lineDraw(mr.right-1, mr.top, mr.right-1, mr.bottom);
+ if (!prevsel) canvas->lineDraw(mr.left, mr.top, mr.right, mr.top);
+ if (!nextsel) canvas->lineDraw(mr.left, mr.bottom, mr.right, mr.bottom);
+ canvas->popPen();
+#endif
+ }
+
+ if (isfocused || iscur) {
+ int pentype = isfocused ? FALSE : TRUE;
+ int boxcolor = iscur ? current : focus;
+ canvas->drawRect(r, pentype, boxcolor);
+ }
+
+ canvas->pushTextSize(getFontSize());
+
+ int x = 1+r->left;
+ for (int i = 0; i < getNumColumns(); i++) {
+ ItemListColumn *col = (ItemListColumn *)enumListColumn(i);
+ RECT ir;
+ ir.left = x;
+ ir.right = x + getColumnWidth(i);
+ ir.top = r->top;
+ ir.bottom = r->bottom;
+ if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) {
+ col->render(pos, playstring, *canvas, ir);
+ }
+ x = ir.right;
+ }
+ canvas->popTextSize();
+ return 1;
+}
+
+void ItemListWnd::convertlParamColumn(int col, int pos, LPARAM param, char *str, int maxlen) {
+ ASSERT(str != NULL);
+ ItemListColumn *cl = (ItemListColumn *)enumListColumn(col);
+ const char *playstring = convertlParam(param);
+ cl->columnToText(pos, playstring, str, maxlen);
+}
+
+
+int ItemListWnd::onContextMenu(int x, int y) {
+ PtrList<FilenameNC> filenames;
+ DragItemI *dragitem = NULL;
+
+ if ((dragitem = itemlistwnd_getDragItem(x, y)) == NULL) {
+ DragItemT<Filename> *di = new DragItemT<Filename>;
+ int n = getNumItems();
+ for (int i = 0; i < n; i++) {
+ if (getItemSelected(i)) {
+ LPARAM lparam = getItemData(i);
+ const char *playstring = convertlParam(lparam);
+ di->addDatum(filenames.addItem(new FilenameNC(playstring)));
+ }
+ }
+ dragitem = di;
+ }
+
+ ContextMenu cm(this, filenames.getNumItems() ? dragitem : NULL, false);
+
+ PtrList<DragItemI> drags;
+ for (int i = 0; ; i++) {
+ DragItemI *aitem = itemlistwnd_getSecondDragItem(i);
+ if (aitem == NULL) break;
+ drags.addItem(aitem);
+ if (cm.getNumCommands()) cm.addSeparator();
+ cm.addDragItem(aitem);
+ }
+ itemlistwnd_addCustomContextMenuCommands(&cm);
+ int r = cm.popAtMouse();
+ if (r < -10) itemlistwnd_contextMenuResult(r);
+ drags.deleteAll();
+
+ filenames.deleteAll();
+
+ delete dragitem;
+
+ return 1;
+}
+
+#if 0
+int ItemListWnd::onRightClick(int itemnum, int _x, int _y) {
+ // figure out which column they clicked on
+ int x, l = 0, r = 0;
+ for (int i = 0; i < cols.getNumItems(); i++) {
+ l = r;
+ r += getColumnWidth(i);
+ if (_x >= l && y <= r) break;
+ }
+ if (i >= cols.getNumItems()) return 0;
+ PlayItem *item = convertlParam(itemnum);
+ if (!allowEdition(item, cols[i]->getTag())) return 0;
+
+ return 0;
+}
+#endif
+
+void ItemListWnd::metacb_onItemChange(const char *playstring, const char *tag) {
+ int n = getNumItems();
+ for (int i = 0; i < n; i++) {
+ const char *ps = convertlParam(getItemData(i));
+ if (ps != NULL && STREQL(ps, playstring)) {
+ onItemChange(i, ps);
+ invalidateItem(i);
+ }
+ }
+}
+
+void ItemListWnd::metacb_onItemDel(const char *playstring) {
+ int n = getNumItems();
+ for (int i = 0; i < n; i++) {
+ const char *ps = convertlParam(getItemData(i));
+ if (ps != NULL && STREQL(ps, playstring)) {
+ onItemDel(i, ps);
+ invalidateItem(i);
+ }
+ }
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/itemlistwnd.h b/Src/Wasabi/api/wnd/wndclass/itemlistwnd.h
new file mode 100644
index 00000000..b2245d9c
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/itemlistwnd.h
@@ -0,0 +1,426 @@
+//PORTABLE
+#ifndef _ITEMLIST_H
+#define _ITEMLIST_H
+
+#include "listwnd.h"
+#include "../canvas.h"
+#include "../named.h"
+#include "../ptrlist.h"
+#include "../string.h"
+#include "../../studio/metacb.h"
+
+class FilenameNC;
+class DragItemI;
+class ContextMenu;
+
+// this class just handles rendering the various properties of playitems
+// in a listwnd... the rest is up to you, just override the convert fn
+
+// abstract base class to render something in a column for a playstring
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class NOVTABLE ItemListColumn : public ListColumn {
+protected:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ItemListColumn(const wchar_t *name=NULL) : ListColumn(name) {}
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~ItemListColumn() {}
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r)=0;
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+
+ virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen)=0;
+};
+
+#define ITEMLISTWND_PARENT ListWnd
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ItemListWnd : public ListWnd, private MetaCallbackI {
+friend class ItemListColumn_Callback;
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ItemListWnd();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~ItemListWnd();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int insertColumn(ItemListColumn *column, int width, int pos=-1);
+
+protected:
+ // override and return 0 to suppress auto-dragging from window
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int wantAutoDrag() { return 1; }
+ // handles auto-adding all selected rows and calls addDragTypes
+ // so you can add more via addDragItem()
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onBeginDrag(int);
+ // if you return 0, the Filename version will be auto-added, otherwise not
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int addMoreDragTypes(int pos) { return 0; }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int dragComplete(int success);
+
+ // tell ListWnd we do our own drawing
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused);
+
+ // ItemListColumn_Callback calls this to do its rendering, lParam is what you
+ // gave it to pass back to you
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void userRender(int pos, const wchar_t *playstring, Canvas &c, RECT &r, LPARAM lParam) {}
+
+ // ItemListColumn_Callback calls this to get the column text, lParam is what you
+ // gave it to pass back to you
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void userColumnToText(int pos, const wchar_t *playstring, LPARAM lParam, wchar_t *str, int maxlen) {}
+
+ // override this to turn the ownerdraw into a playstring
+ virtual const wchar_t *convertlParam(LPARAM lParam)=0;
+ virtual void convertlParamColumn(int col, int pos, LPARAM lParam, wchar_t *str, int maxlen);
+
+ // override this and return 1 if you want a "current" box around item
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int getSelected(LPARAM lParam) { return 0; }
+
+// virtual int onRightClick(int itemnum, int x, int y);
+ // automatically generated context menu (uses Filename)
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onContextMenu(int x, int y);
+
+ // return optional DragItemI for context menu (will be deleted for you)
+ virtual DragItemI *itemlistwnd_getDragItem(int x, int y) { return NULL; }
+ virtual DragItemI *itemlistwnd_getSecondDragItem(int n) { return NULL; }
+ virtual void itemlistwnd_addCustomContextMenuCommands(ContextMenu *cm) { }
+ virtual void itemlistwnd_contextMenuResult(int res) { }
+
+ // return TRUE if it's ok to edit in place
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int allowEdition(const wchar_t *playstring, wchar_t *field) { return 0; }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void resort() {
+ //TODO> implement me!
+ }
+
+protected:
+ // implement this if you want to know when an item's metadata changed
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onItemChange(int pos, const wchar_t *playstring) { }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onItemDel(int pos, const wchar_t *playstring) { }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void metacb_onItemChange(const wchar_t *playstring, const wchar_t *tag);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void metacb_onItemDel(const wchar_t *);
+
+private:
+ PtrList<FilenameNC> *keep;
+};
+
+// column class to ask ItemListWnd to do the rendering
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ItemListColumn_Callback : public ItemListColumn {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ItemListColumn_Callback(ItemListWnd *_parent, LPARAM _lparam, const wchar_t *name=NULL);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r);
+ virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen);
+
+private:
+ ItemListWnd *parent;
+ LPARAM lparam;
+};
+
+// column class to render a metatag
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ItemListColumn_MetaTag : public ItemListColumn {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ItemListColumn_MetaTag(const wchar_t *tag, int center=0, const wchar_t *label=NULL);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~ItemListColumn_MetaTag() {}
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r);
+ virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen);
+
+ const wchar_t *getTag();
+
+private:
+ StringW tag;
+ int center;
+ int datatype;
+};
+
+// this just renders the position of the item, starting from 1
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+ */
+class ItemListColumn_Numbered : public ItemListColumn {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ItemListColumn_Numbered(int _offset=0) : offset(_offset) {}
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r);
+ virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen);
+
+private:
+ int offset;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/labelwnd.cpp b/Src/Wasabi/api/wnd/wndclass/labelwnd.cpp
new file mode 100644
index 00000000..d9aedd0f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/labelwnd.cpp
@@ -0,0 +1,203 @@
+#include <precomp.h>
+
+#include "labelwnd.h"
+
+#include <api/locales/xlatstr.h>
+#include <api/wnd/paintsets.h>
+
+#include <tataki/canvas/bltcanvas.h>
+#include <tataki/color/skinclr.h>
+#include <api/wnd/notifmsg.h>
+#include <tataki/region/region.h>
+#include <api/wnd/PaintCanvas.h>
+
+static SkinColor labelfg(L"wasabi.labelwnd.foreground");
+static SkinColor labelbg(L"wasabi.labelwnd.background", L"Text backgrounds");
+
+#define DEF_LABEL_HEIGHT 0
+#define DEF_LABEL_FONTSIZE 16
+
+LabelWnd::LabelWnd() {
+ show_label = FALSE;
+ labelsize = DEF_LABEL_FONTSIZE;
+ labelHeight = 0;
+ margin=0;
+ setVirtual(0);
+}
+
+void LabelWnd::getClientRect(RECT *r) {
+ LABELWND_PARENT::getClientRect(r);
+ r->top += getLabelHeight();
+}
+
+int LabelWnd::onResize() {
+ LABELWND_PARENT::onResize();
+ invalidateLabel();
+/* if (getLabelHeight() <= 0) return 0;
+ RECT r,ir;
+ LABELWND_PARENT::getClientRect(&r);
+ LABELWND_PARENT::getNonClientRect(&ir);
+ ir.bottom = ir.top + getLabelHeight()+margin;
+ invalidateRect(&ir);*/
+ return 1;
+}
+
+int LabelWnd::onPaint(Canvas *canvas) {
+ if (getLabelHeight() <= 0) return LABELWND_PARENT::onPaint(canvas);
+
+ PaintBltCanvas paintcanvas;
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaintNC(this)) return 0;
+ canvas = &paintcanvas;
+ }
+
+ RECT r;
+ LabelWnd::getNonClientRect(&r);
+
+ if (canvas->isFixedCoords()) { // handle possible double buffer
+ // convert to canvas coords
+ r.right -= r.left; r.left = 0;
+ r.bottom -= r.top; r.top = 0;
+ }
+
+ r.bottom = r.top + getLabelHeight();
+
+ if (margin) {
+ r.left+=margin;
+ r.right-=margin;
+ r.bottom+=margin*2;
+ }
+
+ LABELWND_PARENT::onPaint(canvas);
+ int got_focus = gotFocus() || forceFocus();
+
+ if (wantRenderBaseTexture()) {
+ WASABI_API_WND->skin_renderBaseTexture(getBaseTextureWindow(), canvas, r, this);
+ }
+
+#ifdef WASABI_COMPILE_PAINTSETS
+ WASABI_API_WND->paintset_render(Paintset::LABEL, canvas, &r, got_focus ? 255 : 64);
+#endif
+ Wasabi::FontInfo fontInfo;
+ fontInfo.opaque=false;
+ fontInfo.pointSize = getLabelHeight()-1;
+ const wchar_t *name = getName();
+ if (name == NULL || *name == '\0')
+ name = L"Label";
+#define LEFTMARGIN 3
+ fontInfo.color = labelbg;
+ const wchar_t *xname = name;
+
+ switch(wantTranslation())
+ {
+ case 1:
+ xname = _(name);
+ break;
+ case 2:
+ xname = __(name);
+ break;
+ }
+
+ canvas->textOut(r.left+LEFTMARGIN+1, r.top+1, xname, &fontInfo);
+ fontInfo.color = labelfg;
+ canvas->textOut(r.left+LEFTMARGIN, r.top, xname, &fontInfo);
+
+ return 1;
+}
+
+void LabelWnd::onSetName() {
+ LABELWND_PARENT::onSetName();
+ // make sure label gets repainted
+ if (isInited()) {
+ RECT r;
+ LabelWnd::getNonClientRect(&r);
+ r.bottom = r.top + getLabelHeight();
+ invalidateRect(&r);
+ }
+}
+
+//CUTint LabelWnd::childNotify(api_window *child, int msg, intptr_t param1, intptr_t param2) {
+//CUT switch (msg) {
+//CUT case CHILD_WINDOWSHADE_CAPABLE: return show_label;
+//CUT case CHILD_WINDOWSHADE_ENABLE: return TRUE;
+//CUT }
+//CUT return LABELWND_PARENT::childNotify(child, msg, param1, param2);
+//CUT}
+
+int LabelWnd::showLabel(int show) {
+ show_label = show;
+ setFontSize(-1);
+ if (isPostOnInit()) {
+ onResize();
+ }
+ return 1;
+}
+
+int LabelWnd::getLabelHeight() {
+ return show_label ? labelHeight : 0;
+}
+
+void LabelWnd::setMargin(int newmargin) {
+ margin = newmargin;
+ RECT r;
+ getNonClientRect(&r);
+ r.bottom = getLabelHeight()+margin;
+ invalidateRect(&r);
+}
+
+int LabelWnd::onGetFocus() {
+ LABELWND_PARENT::onGetFocus();
+ invalidateLabel();
+ return 1;
+}
+
+int LabelWnd::onKillFocus() {
+ LABELWND_PARENT::onKillFocus();
+ invalidateLabel();
+ return 1;
+}
+
+void LabelWnd::invalidateLabel() {
+ if (labelHeight <= 0) return;
+ RECT ncr;
+ RECT cr;
+// RECT lr;
+ LabelWnd::getNonClientRect(&ncr);
+ LabelWnd::getClientRect(&cr);
+ RegionI nonClientRgn(&ncr);
+ RegionI clientRgn(&cr);
+ nonClientRgn.subtractRgn(&clientRgn);
+ invalidateRgn(&nonClientRgn);
+// SubtractRect(&lr, &ncr, &cr); // PORT ME
+// invalidateRect(&lr);
+}
+
+int LabelWnd::wantFocus() {
+ return (labelHeight > 0);
+}
+
+void LabelWnd::reloadResources()
+{
+ LABELWND_PARENT::reloadResources();
+ if (isPostOnInit())
+ onResize();
+ invalidateLabel();
+}
+
+int LabelWnd::setFontSize(int size)
+{
+ LABELWND_PARENT::setFontSize(size);
+ TextInfoCanvas blt(this);
+ Wasabi::FontInfo fontInfo;
+#ifndef WASABINOMAINAPI
+ fontInfo.pointSize = labelsize+api->metrics_getDelta();
+#else
+ fontInfo.pointSize = labelsize;
+ //MULTIAPI-FIXME: not handling delta
+#endif
+ labelHeight = blt.getTextHeight(&fontInfo) + 1;
+ invalidate();
+ if (isPostOnInit()) onResize();
+ return 1;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/labelwnd.h b/Src/Wasabi/api/wnd/wndclass/labelwnd.h
new file mode 100644
index 00000000..f6425514
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/labelwnd.h
@@ -0,0 +1,46 @@
+#ifndef _LABELWND_H
+#define _LABELWND_H
+
+#include <bfc/common.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define LABELWND_PARENT GuiObjectWnd
+class LabelWnd : public LABELWND_PARENT {
+protected:
+ LabelWnd();
+public:
+
+ virtual void getClientRect(RECT *);
+ virtual int onResize();
+ virtual int onPaint(Canvas *canvas);
+ virtual int onGetFocus();
+ virtual int onKillFocus();
+ virtual void invalidateLabel();
+ virtual int wantFocus();
+ virtual int wantRenderBaseTexture() { return 1; }
+
+ // override & return 1 to force painting label with focus all the time
+ virtual int forceFocus() { return 0; }
+
+ virtual void onSetName();
+ virtual void setMargin(int newmargin);
+
+ virtual int setFontSize(int size);
+
+//CUT virtual int childNotify(api_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+
+ int showLabel(int show);
+ int getLabelHeight();
+
+ void reloadResources();
+
+private:
+ int show_label, labelsize;
+ int labelHeight;
+ int margin;
+};
+
+// use this if you want a generic labelwnd (but try not to)
+class LabelWndI : public LabelWnd { };
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/listwnd.cpp b/Src/Wasabi/api/wnd/wndclass/listwnd.cpp
new file mode 100644
index 00000000..5da770be
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/listwnd.cpp
@@ -0,0 +1,2151 @@
+#pragma warning(disable:4355)
+
+#include <precomp.h>
+
+#include "listwnd.h"
+
+#include <bfc/wasabi_std.h>
+#include <api/wnd/usermsg.h>
+#include <bfc/ptrlist.h>
+#include <tataki/color/skinclr.h>
+#include <api/wnd/notifmsg.h>
+
+#include <bfc/assert.h>
+
+#include <api/locales/xlatstr.h>
+#include <api/wnd/accessible.h>
+#include <bfc/string/StringW.h>
+#include <new>
+#define DEF_TEXT_SIZE 14 // Default text size
+
+#define ITEMLIST_INC 4092
+#define LISTWND_DRAG_TIMERID 0x8972
+#define LISTWND_DRAG_MARGIN 12
+#define LISTWND_DRAG_TIMERDELAY 100
+#define DRAGSKIP_START 5
+
+#define X_SHIFT 2
+#define Y_SHIFT 2
+#define DRAG_THRESHOLD 4
+#define COLUMNS_DEFAULT_HEIGHT 12
+#define COLUMNS_DEFAULT_WIDTH 96
+#define COLUMNS_MARGIN 2
+#define COLUMNS_RESIZE_THRESHOLD 4
+#define COLUMNS_MIN_WIDTH 1
+#define COLSEPHEIGHT 1
+
+static SkinColor textColor(L"studio.list.text");// todo: have own color in skin.cpp
+static SkinColor bgcolor(L"studio.list.background");// todo: have own color in skin.cpp
+static SkinColor color_item_selected_fg(L"studio.list.item.selected.fg"); // RGB(0, 0, 128)
+static SkinColor color_item_selected(L"studio.list.item.selected"); // RGB(0, 0, 128)
+static SkinColor color_item_focused(L"studio.list.item.focused");// RGB(0, 128, 128)
+static SkinColor color_item_focusrect(L"studio.list.item.focused");// RGB(0, 128, 128)
+static SkinColor color_headers(L"studio.list.column.background");//RGB(0, 152, 208)
+static SkinColor columnTextColor(L"studio.list.column.text");
+static SkinColor columnSepColor(L"studio.list.column.separator");
+
+typedef struct
+{
+ wchar_t *label;
+ int column;
+} listSubitemStruct;
+
+class listItem
+{
+friend ListWnd;
+public:
+ ListWnd *getList() const { return listwnd; }
+protected:
+ listItem()
+ {
+ data = 0;
+ subitems = NULL;
+ listwnd = NULL;
+ }
+ ~listItem()
+ {
+ if (subitems != NULL)
+ {
+ for (int i=0;i<subitems->getNumItems();i++)
+ {
+ listSubitemStruct *subitem = subitems->enumItem(i);
+ if (subitem->label)
+ FREE(subitem->label);
+ }
+ subitems->freeAll();
+ delete subitems;
+ }
+ }
+ void setList(ListWnd *newlist) { listwnd=newlist; }
+
+ StringW label;
+ LPARAM data;
+ PtrList<listSubitemStruct> *subitems;
+ ListWnd *listwnd;
+ AutoSkinBitmap icon;
+};
+
+class CompareListItem {
+public:
+ static int compareItem(listItem *p1, listItem *p2);
+};
+
+int CompareListItem::compareItem(listItem *p1, listItem *p2) {
+ return p1->getList()->sortCompareItem(p1, p2);
+}
+
+
+XMLParamPair ListWnd::params[] = {
+ {LIST_ANTIALIAS, L"ANTIALIAS"},
+ {LIST_BACKGROUND, L"BACKGROUND"},
+ {LIST_TILE, L"TILE"},
+ {LIST_NOCOLHEADER, L"NOCOLHEADER"},
+};
+
+ListWnd::ListWnd()
+: selItemList(this)
+{
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ if (WASABI_API_SKIN->skin_getVersion() >= 1) {
+ textColor.setElementName(L"wasabi.list.text");
+ textColor.setColorGroup(L"");
+ bgcolor.setElementName(L"wasabi.list.background");
+ bgcolor.setColorGroup(L"");
+ color_item_selected_fg.setElementName(L"wasabi.list.text.selected");
+ color_item_selected_fg.setColorGroup(L"");
+ color_item_selected.setElementName(L"wasabi.list.text.selected.background");
+ color_item_selected.setColorGroup(L"");
+ color_headers.setElementName(L"wasabi.list.column.background");
+ color_headers.setColorGroup(L"");
+ columnTextColor.setElementName(L"wasabi.list.column.text");
+ columnTextColor.setColorGroup(L"");
+ columnSepColor.setElementName(L"wasabi.list.column.frame.bottom");
+ columnSepColor.setColorGroup(L"");
+ color_item_focused.setColorGroup(L"");
+ color_item_focusrect.setColorGroup(L"");
+ }
+ selectonupdown = 1;
+ setAutoSort(FALSE);
+ setOwnerDraw(FALSE);
+ setSortDirection(0);
+ setSortColumn(0);
+ lastcolsort=-1;
+ dragtimeron = 0;
+ dragskip = DRAGSKIP_START;
+ dragskipcount = 0;
+ item_invalidate_border = 0;
+
+ metrics_ok = FALSE;
+ setFontSize(DEF_TEXT_SIZE);
+ redraw = TRUE;
+ columnsHeight = COLUMNS_DEFAULT_HEIGHT;
+ lastItemFocused = NULL;
+ lastItemFocusedPos = -1;
+ lastAddedItem = NULL;
+ selectionStart = -1;
+ colresize = -1;
+ resizing_col = FALSE;
+ processbup = FALSE;
+ bdown = FALSE;
+ nodrag = FALSE;
+ showColumnsHeaders = TRUE;
+ rectselecting=0;
+ preventMultipleSelection = 0;
+//CUT autoresizecol0 = 0;
+ wantautodeselect = 1;
+ registerAcceleratorSection(L"listwnd");
+ hoverselect = 0;
+ firstItemVisible = -1;
+ lastItemVisible = -1;
+ showicons = 0;
+ iconWidth = -1; // If it's still negative use itemHeight instead -- better user getIconWidth()
+ iconHeight = -1;
+ antialias=1;
+ hasUserBg = false;
+}
+
+void ListWnd::CreateXMLParameters(int master_handle)
+{
+ //LISTWND_PARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+ListWnd::~ListWnd() {
+ deleteAllItems();
+ columnsList.deleteAll();
+ nodrag=FALSE;
+}
+
+int ListWnd::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value)
+{
+ if (_xuihandle != xuihandle)
+ return ScrlBkgWnd::setXuiParam(_xuihandle, xmlattributeid, xmlattributename, value);
+
+ switch (xmlattributeid)
+ {
+ case LIST_ANTIALIAS:
+ antialias = WTOI(value);
+ break;
+ case LIST_BACKGROUND:
+ {
+ SkinBitmap __bmp(value);
+ if (!__bmp.isInvalid())
+ {
+ this->setBgBitmap(value);
+ hasUserBg = true;
+ }
+ else
+ {
+ this->setBgBitmap(L"wasabi.list.background");
+ hasUserBg = false;
+ }
+ }
+ this->invalidate();
+ break;
+ case LIST_TILE:
+ this->wantTileBg = WTOI(value)?1:0;
+ this->invalidate();
+ break;
+ case LIST_NOCOLHEADER:
+ setShowColumnsHeaders(!WTOI(value));
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int ListWnd::onInit() {
+
+ LISTWND_PARENT::onInit();
+
+ if (!hasUserBg) setBgBitmap(L"wasabi.list.background");
+ setLineHeight(getItemHeight());
+
+ return 1;
+}
+
+int ListWnd::onPostOnInit() {
+ LISTWND_PARENT::onPostOnInit();
+ recalcHeaders();
+ return 1;
+}
+
+int ListWnd::onPaint(Canvas *canvas)
+{
+
+ PaintCanvas paintcanvas;
+ PaintBltCanvas paintbcanvas;
+
+ if (canvas == NULL) {
+ if (needDoubleBuffer()) {
+ if (!paintbcanvas.beginPaintNC(this)) return 0;
+ canvas = &paintbcanvas;
+ } else {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ }
+
+ LISTWND_PARENT::onPaint(canvas);
+
+ RegionI clip;
+ canvas->getClipRgn(&clip);
+ api_region *orig;
+ orig = clip.clone();
+
+ drawColumnHeaders(canvas);
+
+ if (getColumnsHeight() > 0) {
+ RECT cr;
+ getClientRect(&cr);
+ cr.bottom = cr.top;
+ cr.top -= getColumnsHeight();
+ clip.subtractRect(&cr);
+ canvas->selectClipRgn(&clip);
+ }
+
+ firstItemVisible = -1;
+ lastItemVisible = -1;
+
+ //drawSubItems(canvas, x, &y, items, r.top, r.bottom, 0);
+ drawItems(canvas);
+
+ canvas->selectClipRgn(orig); // reset cliping region;
+
+ clip.disposeClone(orig);
+
+ return 1;
+}
+
+int ListWnd::onResize() {
+ LISTWND_PARENT::onResize();
+ recalcHeaders();
+ return 1;
+}
+
+int ListWnd::getNumItems(void) {
+ return itemList.getNumItems();
+}
+
+void ListWnd::drawItems(Canvas *canvas) {
+
+ RECT r, c;
+ getClientRect(&r);
+
+ RegionI clip;
+ if (!canvas->getClipRgn(&clip))
+ {
+ clip.setRect(&r);
+ }
+
+ if (GetClipBox(canvas->getHDC(), &c) == NULLREGION) {
+ getClientRect(&c);
+ }
+
+// DebugString("%d %d %d %d\n", c.left, c.top, c.right, c.bottom);
+
+// float f,l;
+ calcBounds();
+
+ //int first, last;
+
+/* RECT s=c;
+
+ s.bottom = min(s.bottom, r.bottom);
+ s.top = max(s.top, getLabelHeight()+(showColumnsHeaders ? getColumnsHeight() : 0));
+
+ f = ((float)(s.top - getLabelHeight() - (showColumnsHeaders ? getColumnsHeight() : 0) - getYShift() + getScrollY())) / (float)itemHeight;
+ l = ((float)(s.bottom - getLabelHeight() - (showColumnsHeaders ? getColumnsHeight() : 0) - getYShift() + getScrollY())) / (float)itemHeight;
+ first = (int)f;
+ first = max(0,first);
+ last = (int)l;
+ if ((float)((int)l) != l) {
+ last++;
+ }*/
+
+ int g=0;
+
+ for (int i=firstItemVisible;i<=lastItemVisible && i<itemList.getNumItems();i++) {
+ RECT ir={0,0,0,0};
+ getItemRect(i, &ir);
+ int a=ir.right;
+ ir.right = r.right;
+ if (!clip.doesIntersectRect(&ir))
+ continue;
+ ir.right=a;
+ g++;
+
+ LPARAM itemdata = getItemData(i);
+ int itemselected = getItemSelected(i);
+ int itemfocused = getItemFocused(i);
+
+ onPreItemDraw(canvas, i, &ir, itemdata, itemselected, itemfocused);
+
+ int sel = getItemSelected(i);
+ canvas->pushPen(PS_SOLID, 1, getColumnSepColor());
+
+ if (!ownerDraw(canvas, i, &ir, itemdata, itemselected, itemfocused))
+ {
+ Wasabi::FontInfo fontInfo;
+ fontInfo.antialias = getTextAntialias(itemdata);
+ fontInfo.bold = getTextBold(itemdata);
+ fontInfo.italic = !!getTextItalic(itemdata);
+ fontInfo.opaque = false;
+ fontInfo.color = sel ? getSelFgColor(itemdata) : getTextColor(itemdata);
+ fontInfo.pointSize = getFontSize();
+ int x = -getScrollX();
+ if (sel)
+ canvas->fillRect(&ir, getSelBgColor(itemdata));
+ if (getItemFocused(i))
+ canvas->fillRect(&ir, getFocusColor(itemdata));
+ if (needFocusRect(itemdata))
+ canvas->drawRect(&ir, 1, getFocusRectColor(itemdata));
+ if (showicons)
+ {
+ SkinBitmap *icon = getItemIcon(i);
+ if (icon)
+ {
+ RECT dst={x+X_SHIFT+r.left+1, ir.top+1, x+X_SHIFT+r.left+getIconWidth()+1, ir.top+getIconHeight()+1};
+ icon->stretchToRect(canvas, &dst);
+ }
+ x += getIconWidth()+1;
+ }
+ int xsep = wantColSepOnItems()?COLSEPHEIGHT:0;
+ for (int j=0;j<columnsList.getNumItems();j++) {
+ ListColumn *col = columnsList[j];
+ RECT cr=ir;
+ cr.left = x+X_SHIFT+r.left;
+ cr.right = cr.left + col->getWidth()-X_SHIFT*2+xsep;
+ if (j > 0 && wantColSepOnItems()) {
+ canvas->moveTo(x, ir.top);
+ canvas->lineTo(x, ir.top+getItemHeight());
+ }
+ switch (col->getAlignment()) {
+ case COL_LEFTALIGN:
+ canvas->textOutEllipsed(cr.left+2, cr.top, cr.right-cr.left-4, cr.bottom-cr.top, getSubitemText(i, j), &fontInfo);
+ break;
+ case COL_CENTERALIGN: {
+ RECT _cr = {cr.left+2, cr.top, cr.right-4, cr.bottom};
+ canvas->textOutCentered(&_cr, getSubitemText(i, j), &fontInfo);
+ break;
+ }
+ case COL_RIGHTALIGN: {
+ const wchar_t *txt = getSubitemText(i, j);
+ int __x = cr.left;
+ int __y = cr.top;
+ int fw = canvas->getTextWidth(txt, &fontInfo);
+ int aw = cr.right-cr.left-4;
+ __x -= fw-aw;
+ canvas->textOut(__x, __y, txt, &fontInfo);
+ break;
+ }
+ }
+ x += col->getWidth()+xsep;
+ }
+ if (wantColSepOnItems()) {
+ canvas->moveTo(x, ir.top);
+ canvas->lineTo(x, ir.top+getItemHeight());
+ }
+ }
+
+ canvas->popPen();
+ onPostItemDraw(canvas, i, &ir, itemdata, itemselected, itemfocused);
+ }
+/*
+ OutputDebugString("%d items draw\n", g);
+*/
+}
+
+int ListWnd::wantColSepOnItems() {
+ return 0;
+}
+
+int ListWnd::getXShift() {
+ if (wantColSepOnItems()) return X_SHIFT; else return 0;
+}
+
+int ListWnd::getFirstItemSelected() {
+ return getNextItemSelected(-1);
+}
+
+int ListWnd::getNextItemSelected(int lastpos) {
+ if (lastpos < -1) lastpos = -1;
+ for (int i=lastpos+1;i<itemList.getNumItems();i++)
+ if (getItemSelected(i))
+ return i;
+ return -1;
+}
+
+void ListWnd::calcBounds() {
+ lastComplete = TRUE;
+ firstComplete = TRUE;
+ float f,l;
+ RECT r;
+ getClientRect(&r);
+
+ f = ((float)(getScrollY()-Y_SHIFT) / getItemHeight());
+ l = ((float)(getScrollY()-Y_SHIFT+(r.bottom-r.top)) / getItemHeight()) - 1.0f;
+
+ firstItemVisible = (int)f;
+ lastItemVisible = (int)l;
+
+ if ((float)((int)l) != l) {
+ lastItemVisible++;
+ lastComplete = FALSE;
+ }
+ if ((float)((int)f) != f && f >= 0) {
+ firstComplete = FALSE;
+ }
+}
+
+// Draws tiled background
+void ListWnd::drawBackground(Canvas *canvas)
+{
+ LISTWND_PARENT::drawBackground(canvas);
+ drawColumnHeaders(canvas);
+}
+
+void ListWnd::drawColumnHeaders(Canvas *c)
+{
+ if (columnsList.getNumItems() == 0 || !showColumnsHeaders) return;
+
+ RECT r;
+ getClientRect(&r);
+ r.top -= getColumnsHeight();
+ r.bottom = r.top + getColumnsHeight();
+ if (renderRatioActive())
+ r.left -= (int)((double)getScrollX()*getRenderRatio());
+ else
+ r.left-=getScrollX();
+
+ c->fillRect(&r, color_headers);
+ int x = r.left + X_SHIFT/*+ 1*/;
+
+ if (showicons)
+ x += getIconWidth()+1 + 2;
+
+ Wasabi::FontInfo fontInfo;
+ fontInfo.color = columnTextColor;
+ fontInfo.opaque = false;
+ fontInfo.pointSize = getColumnsHeight();
+ c->pushPen(PS_SOLID, 1, getColumnSepColor());
+
+ for (int i=0;i<columnsList.getNumItems();i++)
+ {
+ ListColumn *col = columnsList[i];
+ int width = col->getWidth();
+ if (i > 0) {
+ c->moveTo(x, r.top);
+ c->lineTo(x, r.top+getColumnsHeight());
+ }
+ RECT ch;
+ ch.left = x+COLUMNS_MARGIN-((i==0)?X_SHIFT:0);
+ ch.top = r.top;
+ ch.right = ch.left + col->getWidth()-1-COLUMNS_MARGIN*2+((i==0)?X_SHIFT:0);
+ ch.bottom = ch.top + getColumnsHeight()-1;
+ col->customDrawHeader(c, &ch, &fontInfo);
+ x+=width/*+1*/;
+ }
+ c->moveTo(x, r.top);
+ c->lineTo(x, r.top+getColumnsHeight());
+ c->popPen();
+
+}
+
+ARGB32 ListWnd::getColumnSepColor() {
+ return columnSepColor;
+}
+
+int ListWnd::getHeaderHeight() {
+ return (showColumnsHeaders && columnsList.getNumItems() > 0) ? getColumnsHeight() : 0;
+}
+
+// Returns the current tree width in pixels
+int ListWnd::getContentsWidth() {
+ return getColumnsWidth()+X_SHIFT;
+}
+
+// Returns the current tree height in pixels
+int ListWnd::getContentsHeight() {
+ return itemList.getNumItems()*(getItemHeight()+(wantColSepOnItems()?COLSEPHEIGHT:0))+Y_SHIFT*2;
+}
+
+void ListWnd::setAutoSort(bool dosort) {
+ autosort = dosort;
+ itemList.setAutoSort(dosort);
+}
+
+void ListWnd::setOwnerDraw(bool doownerdraw) {
+ ownerdraw = doownerdraw;
+}
+
+int ListWnd::setFontSize(int size)
+{
+ LISTWND_PARENT::setFontSize(size);
+ if (size >= 0) textsize = size;
+ TextInfoCanvas c(this);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = getFontSize();
+ setItemHeight(c.getTextHeight(&fontInfo)+2, false);
+ redraw = TRUE;
+ metrics_ok = FALSE;
+ invalidate();
+ return 1;
+}
+
+int ListWnd::getFontSize() {
+#ifndef WASABINOMAINAPI
+ return textsize+api->metrics_getDelta();
+#else
+ //MULTIAPI-FIXME: not handling delta
+ return textsize;
+#endif
+}
+
+void ListWnd::onSetVisible(int show) {
+ LISTWND_PARENT::onSetVisible(show);
+ if (show) invalidate();
+}
+
+int ListWnd::fullyVisible(int pos) {
+ return (((lastComplete && pos <= lastItemVisible) || (!lastComplete && pos < lastItemVisible)) && ((firstComplete && pos >= firstItemVisible) || (!firstComplete && pos > firstItemVisible)));
+}
+
+void ListWnd::ensureItemVisible(int pos) {
+ if (pos >= itemList.getNumItems()) pos = itemList.getNumItems()-1;
+ if (pos < 0) pos = 0;
+ if (fullyVisible(pos)) return;
+
+ RECT c;
+ int y=pos*getItemHeight();
+ getClientRect(&c);
+ int showing_height = c.bottom - c.top;
+
+ if (getScrollY() < y) // scrolling up
+ y = (y - showing_height) + getItemHeight()*3;
+ else
+ y -= getItemHeight()*2;
+
+ if (y < 0) y = 0;
+ else if (y + showing_height > getContentsHeight()) {
+ // just show bottom pane
+ y = getContentsHeight()-showing_height;
+ }
+ scrollToY(y);
+}
+
+void ListWnd::scrollToItem(int pos) {
+ if (!isInited()) return;
+ scrollToY(Y_SHIFT+pos*(getItemHeight()+(wantColSepOnItems()?COLSEPHEIGHT:0)));
+}
+
+int ListWnd::getNumColumns() {
+ return columnsList.getNumItems();
+}
+
+ListColumn *ListWnd::getColumn(int n) {
+ return columnsList.enumItem(n);
+}
+
+int ListWnd::getColumnWidth(int c) {
+ ListColumn *col = columnsList[c];
+ ASSERT(col != NULL);
+ return col->getWidth();
+}
+
+int ListWnd::selectAll(int cb) {
+
+ int i;
+
+ if (preventMultipleSelection) return 1;
+
+ for (i=0;i<itemList.getNumItems();i++) {
+ selItemList.setSelected(i, TRUE, cb);
+ }
+
+ if (cb)
+ notifySelChanged();
+ return 1;
+}
+
+int ListWnd::deselectAll(int cb) {
+
+ int lif = getItemFocused();
+ if (lif != -1)
+ invalidateItem(lif);
+ lastItemFocused = NULL;
+
+ for (int i = 0; i < itemList.getNumItems(); i++) {
+ selItemList.setSelected(i, FALSE, cb);
+ }
+
+ if (cb)
+ notifySelChanged();
+ return 1;
+}
+
+void ListWnd::notifySelChanged(int item, int sel) {
+ if (!getRedraw()) return;
+ if (item == -1)
+ notifyParent(ChildNotify::LISTWND_SELCHANGED);
+ else
+ notifyParent(ChildNotify::LISTWND_ITEMSELCHANGED, item, sel);
+}
+
+int ListWnd::invertSelection(int cb) {
+ if (preventMultipleSelection) return 1;
+ for (int i = 0; i < itemList.getNumItems(); i++) {
+ toggleSelection(i, FALSE, cb);
+ }
+ return 1;
+}
+
+int ListWnd::invalidateItem(int pos) {
+ RECT r;
+ if (!isInited()) return 0;
+ int rv = getItemRect(pos, &r);
+ r.top -= item_invalidate_border;
+ r.bottom += item_invalidate_border;
+ if (rv)
+ invalidateRect(&r);
+ return rv;
+}
+
+int ListWnd::onLeftButtonDblClk(int x, int y) {
+ // check for column dblclick
+ int colhit;
+ if ((colhit = hitTestColumns(Wasabi::Std::makePoint(x, y))) >= 0) {
+ return onColumnDblClick(colhit, x, y);
+ }
+
+ if (itemList.getNumItems() == 0) return 0;
+ POINT p={x,y};
+ int i = hitTest(p);
+ if (i > -1) {
+ notifyParent(ChildNotify::LISTWND_DBLCLK, i, 0);
+ onDoubleClick(i);
+ return 1;
+ }
+ return 0;
+}
+
+int ListWnd::onRightButtonDown(int x, int y) {
+ nodrag=TRUE;
+ return 1;
+}
+
+int ListWnd::onRightButtonUp(int x, int y) {
+ nodrag=FALSE;
+ int i = hitTest(x,y);
+ if (i >= 0) { // did hit something
+ setItemFocused(i); // it always gets the focus
+ if (!getItemSelected(i)) { // reselect the item out of the cur selection
+ ListWnd::onLeftButtonDown(x,y); // don't call inherited!
+ ListWnd::onLeftButtonUp(x,y); // don't call inherited!
+ }
+ onRightClick(i);
+ } else {
+ if (wantAutoDeselect())
+ deselectAll();
+ }
+ onContextMenu(x,y);
+
+ return 1;
+}
+
+int ListWnd::onRightClick(int itemnum) {
+ return 0;
+}
+
+
+int ListWnd::onLeftButtonDown(int x, int y) {
+ if (colresize != -1) {
+ resizing_col = TRUE;
+ drawXorLine(colresizept.x);
+ }
+
+ processbup = FALSE;
+ bdown = TRUE;
+ bdownx = x;
+ bdowny = y;
+
+ if (!resizing_col) {
+
+ POINT p={x,y};
+ int i = hitTest(p);
+ if (i >= 0) {
+ if (Std::keyDown(VK_SHIFT)) {
+ if (getItemSelected(i))
+ processbup=TRUE;
+ else
+ setSelectionEnd(i);
+ } else
+ if (Std::keyDown(VK_CONTROL)) {
+ if (getItemSelected(i))
+ processbup=TRUE;
+ else
+ toggleSelection(i);
+ } else {
+ if (getItemSelected(i))
+ processbup = TRUE;
+ else
+ setSelectionStart(i);
+ }
+ } else {
+ if (wantAutoDeselect())
+ deselectAll();
+ /*rectselecting=1;
+ selectStart.x = x;
+ selectStart.y = y;
+ selectLast.x = x;
+ selectLast.y = y;
+ drawRect(selectStart.x, selectStart.y, x, y);
+ beginCapture();*/
+ }
+ }
+
+ return 1;
+}
+
+int ListWnd::onLeftButtonUp(int x, int y) {
+
+ bdown = FALSE;
+
+ if (resizing_col) {
+ resizing_col = FALSE;
+ drawXorLine(colresizept.x);
+ calcNewColWidth(colresize, colresizept.x);
+ recalcHeaders();
+ return 1;
+ }
+
+ // check for column label click
+ int colhit;
+ if ((colhit = hitTestColumnsLabel(Wasabi::Std::makePoint(x, y))) >= 0) {
+ ListColumn *lc = getColumn(colhit);
+ int ret = lc->onHeaderClick();
+ if (!ret) ret = onColumnLabelClick(colhit, x, y);
+ return ret;
+ }
+
+ POINT p={x,y};
+ int i = hitTest(p);
+
+ if (rectselecting || (processbup && !resizing_col) || hoverselect) {
+ if (i >= 0) {
+ if (Std::keyDown(VK_SHIFT)) {
+ if (getItemSelected(i))
+ setSelectionStart(i);
+ else
+ setSelectionEnd(i);
+ } else {
+ if (Std::keyDown(VK_CONTROL) || !wantAutoDeselect()) {
+ toggleSelection(i);
+ selectionStart = i;
+ } else {
+ setSelectionStart(i);
+ }
+ }
+ } else {
+/* if (rectselecting) {
+ drawRect(selectStart.x, selectStart.y, selectLast.x, selectLast.y);
+ endCapture();
+ rectselecting=0;
+ selectRect(selectStart.x, selectStart.y, x, y);
+ } else*/
+ if (wantAutoDeselect())
+ deselectAll();
+ }
+ }
+
+ if (i >= 0) {
+ int cn = hitTestColumnClient(x);
+ int r = 0;
+ if (cn >= 0) {
+ ListColumn *lc = getColumn(cn);
+ ASSERT(lc != NULL);
+ r = lc->onColumnLeftClick(i);
+ }
+ if (!r)
+ {
+ // Add 1px clickable border to our icon
+ if (x < getIconWidth()+2) r = onIconLeftClick(i,x,y-(i*getItemHeight()) - getHeaderHeight());
+ if (!r) onLeftClick(i);
+ }
+ }
+
+ return 1;
+}
+
+int ListWnd::onMouseMove(int x, int y) {
+ LISTWND_PARENT::onMouseMove(x,y);
+
+ if (!bdown && (Std::keyDown(MK_RBUTTON) || Std::keyDown(MK_RBUTTON))) {
+ bdown = TRUE;
+ processbup = TRUE;
+ _enterCapture();
+ }
+
+ if (!rectselecting && bdown && !resizing_col && !nodrag && (ABS(x-bdownx) >= 4 || ABS(y-bdowny) >= 4)) {
+ processbup = FALSE;
+ bdown = FALSE;
+ int i = hitTest(x, y);
+ if (i != -1) {
+ onBeginDrag(i);
+ return 1;
+ }
+ }
+
+/* if (rectselecting) {
+ drawRect(selectStart.x, selectStart.y, selectLast.x, selectLast.y);
+ selectLast.x = x;
+ selectLast.y = y;
+ drawRect(selectStart.x, selectStart.y, selectLast.x, selectLast.y);
+ return 1;
+ }*/
+
+ POINT p={x,y};
+ if (wantResizeCols()) {
+ if (!resizing_col) {
+ int c = hitTestColumns(p, &colresizeo);
+ if (c != -1) {
+ if (colresize != c) {
+ SetCursor(LoadCursor(NULL, IDC_SIZEWE)); // NONPORTABLE
+ if (!getCapture())
+ beginCapture();
+ colresize = c;
+ colresizept = p;
+ }
+ } else {
+ if (colresize != -1) {
+ SetCursor(LoadCursor(NULL, IDC_ARROW)); // NONPORTABLE
+ endCapture();
+ colresize = -1;
+ }
+ }
+ } else {
+ if (p.x + getScrollX() < colresizeo + COLUMNS_MIN_WIDTH) {
+ p.x = colresizeo + COLUMNS_MIN_WIDTH - getScrollX();
+ }
+ drawXorLine(colresizept.x);
+ colresizept = p;
+ drawXorLine(colresizept.x);
+ }
+ }
+
+ if (hoverselect) {
+ int i = hitTest(x, y);
+ if (i >= 0 && !getItemSelected(i)) {
+ deselectAll(0);
+ setSelected(i, 1, 0);
+ wchar_t t[256]=L"";
+ getItemLabel(i, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+ }
+ return 1;
+}
+
+// NONPORTABLE / Todo: implement necessary stuff in canvas
+void ListWnd::drawXorLine(int x) {
+ HDC dc = GetDC(gethWnd());
+ HBRUSH brush = CreateSolidBrush(0xFFFFFF);
+ HPEN pen = CreatePen(PS_SOLID,0,0xFFFFFF);
+ HBRUSH oldB = (HBRUSH)SelectObject(dc, brush);
+ HPEN oldP = (HPEN)SelectObject(dc, pen);
+ int mix = SetROP2(dc,R2_XORPEN);
+
+ RECT r;
+ getClientRect(&r);
+ r.top -= getColumnsHeight();
+ r.bottom = r.top + getColumnsHeight();
+
+ if (renderRatioActive()) {
+ multRatio(&x);
+ multRatio(&r);
+ }
+
+ MoveToEx(dc, x, r.top, NULL);
+ LineTo(dc, x, r.bottom);
+
+ SelectObject(dc, oldB);
+ SelectObject(dc, oldP);
+ SetROP2(dc, mix);
+ DeleteObject(pen);
+ DeleteObject(brush);
+ ReleaseDC(gethWnd(), dc);
+}
+
+void ListWnd::calcNewColWidth(int c, int px) {
+ RECT r;
+ getClientRect(&r);
+ r.top -= getColumnsHeight();
+ r.bottom = r.top + getColumnsHeight();
+ px += getScrollX();
+ int x = r.left+X_SHIFT;
+ for (int i=0;i<columnsList.getNumItems();i++) {
+ ListColumn *col = columnsList[i];
+ if (col->getIndex() == c) {
+ int w = px - x;
+ col->setWidth(w);
+ setSlidersPosition();
+ return;
+ }
+ x += col->getWidth();
+ }
+ return;
+}
+
+int ListWnd::hitTestColumns(POINT p, int *origin) {
+ RECT r;
+ if (!showColumnsHeaders) return -1;
+ int best=-1, besto = 0, bestd=9999;
+ getClientRect(&r);
+ r.top -= getColumnsHeight();
+ r.bottom = r.top + getColumnsHeight();
+ p.x += getScrollX();
+ if (p.y > r.top && p.y < r.top + getColumnsHeight()) {
+ int x = r.left+X_SHIFT;
+ for (int i=0;i<columnsList.getNumItems();i++) {
+ ListColumn *col = columnsList[i];
+ x += col->getWidth();
+ if (p.x > x-COLUMNS_RESIZE_THRESHOLD && p.x < x+COLUMNS_RESIZE_THRESHOLD) {
+ int d = ABS(p.x-x);
+ if (d < bestd) {
+ bestd = d;
+ besto = x - col->getWidth();
+ best = col->getIndex();
+ }
+ }
+ }
+ }
+
+ if (best != -1)
+ if (origin != NULL) *origin = besto;
+ return best;
+}
+
+int ListWnd::hitTestColumnClient(int x) {
+ RECT cr = clientRect();
+ int x1 = cr.left+X_SHIFT;
+ foreach(columnsList)
+ int x2 = x1 + columnsList.getfor()->getWidth();
+ if (x >= x1 && x <= x2) return foreach_index;
+ x1 = x2;
+ endfor
+ return -1;
+}
+
+void ListWnd::invalidateColumns() {
+ RECT r;
+ getClientRect(&r);
+ r.top -= getColumnsHeight();
+ r.bottom = r.top + getColumnsHeight();
+ invalidateRect(&r);
+}
+
+int ListWnd::hitTestColumnsLabel(POINT p) {
+ RECT r;
+ if (!showColumnsHeaders) return -1;
+ getClientRect(&r);
+ r.top -= getColumnsHeight();
+ r.bottom = r.top + getColumnsHeight();
+ p.x += getScrollX();
+ if (p.y > r.top && p.y < r.top + getColumnsHeight()) {
+ int x = X_SHIFT;
+ for (int i=0;i<columnsList.getNumItems();i++) {
+ ListColumn *col = columnsList[i];
+ if (p.x >= x && p.x <= x+col->getWidth())
+ return i;
+ x += col->getWidth();
+ }
+ }
+ return -1;
+}
+
+void ListWnd::setSelectionStart(int pos, int wantcb) {
+ if (wantAutoDeselect())
+ deselectAll(wantcb);
+ if (!selItemList.isSelected(pos)) {
+ selItemList.setSelected(pos, TRUE, wantcb);
+ lastItemFocused = itemList[pos];
+ lastItemFocusedPos = pos;
+ invalidateItem(pos);
+ repaint();
+ }
+
+ selectionStart = pos;
+ notifySelChanged();
+}
+
+void ListWnd::setSelectionEnd(int pos) {
+
+ if (itemList.getNumItems() == 0) return;
+ if (selectionStart == -1) selectionStart = 0;
+
+ if (wantAutoDeselect())
+ deselectAll();
+
+ int inc = (selectionStart > pos) ? -1 : 1;
+ int i = selectionStart;
+
+ while (1) {
+ if (!selItemList.isSelected(i)) {
+ selItemList.setSelected(i, TRUE);
+ lastItemFocused = itemList[i];
+ lastItemFocusedPos = i;
+ invalidateItem(i);
+ }
+ if (i == pos) break;
+ i += inc;
+ }
+ notifySelChanged();
+}
+
+void ListWnd::setSelected(int pos, int selected, int cb) {
+ selItemList.setSelected(pos, selected, cb);
+}
+
+void ListWnd::toggleSelection(int pos, int setfocus, int cb) {
+ if (!selItemList.isSelected(pos)) {
+ selItemList.setSelected(pos, TRUE, cb);
+ if (setfocus) {
+ if (selItemList.getNumSelected() > 1) {
+ for (int i=0;i<itemList.getNumItems();i++)
+ if (selItemList.isSelected(i))
+ invalidateItem(i);
+ }
+ lastItemFocused = itemList[pos];
+ lastItemFocusedPos = pos;
+ }
+ } else {
+ selItemList.setSelected(pos, FALSE, cb);
+ if (setfocus) {
+ lastItemFocused = NULL;
+ lastItemFocusedPos = -1;
+ }
+ }
+
+ invalidateItem(pos);
+ if (cb)
+ notifySelChanged();
+}
+
+int ListWnd::onBeginDrag(int iItem) {
+ // nothing by default
+ lastItemFocused = NULL;
+ lastItemFocusedPos = -1;
+ invalidateItem(iItem);
+ return 0;
+}
+
+int ListWnd::dragOver(int x, int y, ifc_window *sourceWnd) {
+ int rt = LISTWND_PARENT::dragOver(x, y, sourceWnd);
+ if (dragtimeron) return rt;
+
+ POINT pos={x,y};
+ screenToClient(&pos);
+
+ int item = hitTest(pos);
+ if (item == LW_HT_BELOW || item == LW_HT_ABOVE) {
+ dragtimeron = 1;
+ dragskip = DRAGSKIP_START;
+ dragskipcount = DRAGSKIP_START-1; // start right away
+ setTimer(LISTWND_DRAG_TIMERID, LISTWND_DRAG_TIMERDELAY);
+ }
+ return rt;
+}
+
+void ListWnd::onDragTimer() {
+ POINT pos;
+ Wasabi::Std::getMousePos(&pos);
+ screenToClient(&pos);
+ int item = hitTest(pos);
+ if (item == LW_HT_BELOW || item == LW_HT_ABOVE) {
+ dragskipcount++;
+ if (dragskipcount >= dragskip) {
+ switch (item) {
+ case LW_HT_BELOW:
+ scrollDown();
+ break;
+ case LW_HT_ABOVE:
+ scrollUp();
+ break;
+ }
+ dragskipcount = 0;
+ if (dragskip > 0) dragskip--;
+ }
+ } else {
+ killTimer(LISTWND_DRAG_TIMERID);
+ dragtimeron = 0;
+ }
+}
+
+void ListWnd::timerCallback(int id) {
+ switch (id) {
+ case LISTWND_DRAG_TIMERID:
+ onDragTimer();
+ return;
+ }
+ LISTWND_PARENT::timerCallback(id);
+}
+
+void ListWnd::onSelectAll() {
+}
+
+void ListWnd::onDelete() {
+ // do nothing by default
+}
+
+void ListWnd::onDoubleClick(int itemnum) {
+ // do nothing by default
+}
+
+void ListWnd::onLeftClick(int itemnum) {
+ // do nothing by default
+}
+
+int ListWnd::onIconLeftClick (int itemnum, int x, int y)
+{
+ return 0;
+}
+
+void ListWnd::onSecondLeftClick(int itemnum) {
+ // do nothing by default
+}
+
+int ListWnd::scrollAbsolute(int x) {
+ scrollToX(x);
+ return getScrollX();
+}
+
+int ListWnd::scrollRelative(int x) {
+ scrollToX(getScrollX() + x);
+ return getScrollX();
+}
+
+int ListWnd::getItemFocused() {
+ if (lastItemFocused == NULL) return -1;
+ if (itemList[lastItemFocusedPos] == lastItemFocused)
+ return lastItemFocusedPos;
+ else {
+ lastItemFocusedPos = itemList.searchItem(lastItemFocused);
+ return lastItemFocusedPos;
+ }
+}
+
+void ListWnd::setItemFocused(int pos, int ensure_visible) {
+ invalidateItem(lastItemFocusedPos);
+ lastItemFocused = itemList[pos];
+ lastItemFocusedPos = -1;
+ if (lastItemFocused != NULL) lastItemFocusedPos = pos;
+ invalidateItem(lastItemFocusedPos);
+ if (ensure_visible) ensureItemVisible(pos);
+}
+
+int ListWnd::getItemRect(int pos, RECT *r) {
+ MEMSET(r, 0, sizeof(RECT));
+ if (pos < 0 || pos >= itemList.getNumItems()) return 0;
+ RECT cr={0,0,0,0};
+ getClientRect(&cr);
+ r->left = -getScrollX() + X_SHIFT + cr.left;
+ r->right = cr.left + getColumnsWidth();
+ if (showicons) r->right += getItemHeight();
+ r->top = -getScrollY() + pos * (getItemHeight() + (wantColSepOnItems() ? COLSEPHEIGHT : 0)) + Y_SHIFT + cr.top;
+ r->bottom = r->top + getItemHeight();
+
+ // clip!
+ if (r->top > cr.bottom || r->bottom < cr.top) return 0;
+
+ return 1;
+}
+
+int ListWnd::locateData(LPARAM data) { // linear search
+ for (int i=0;i<itemList.getNumItems();i++) {
+ if (itemList[i]->data == data)
+ return i;
+ }
+ return -1;
+}
+
+int ListWnd::getItemFocused(int pos) {
+ if (pos >= itemList.getNumItems()) return 0;
+ return getItemFocused() == pos;
+}
+
+int ListWnd::getItemSelected(int pos) {
+ listItem *item = itemList[pos];
+ return (item && selItemList.isSelected(pos));
+}
+
+int ListWnd::hitTest(POINT pos, int drag) {
+ RECT r;
+ getClientRect(&r);
+ if (pos.y < r.top) return LW_HT_ABOVE;
+ if (getScrollY() > 0 && drag && pos.y < r.top + LISTWND_DRAG_MARGIN) return LW_HT_ABOVE;
+ if (pos.y > r.bottom) return LW_HT_BELOW;
+ if (getContentsHeight() > (getScrollY() + r.bottom-r.top) && drag && pos.y > r.bottom - LISTWND_DRAG_MARGIN) return LW_HT_BELOW;
+
+ if (pos.x > r.left + getColumnsWidth() - getScrollX()) return LW_HT_DONTKNOW;
+ if (pos.x < r.left + getScrollX()) return LW_HT_DONTKNOW;
+
+ int i = (pos.y - r.top + getScrollY() - Y_SHIFT) / (getItemHeight() + (wantColSepOnItems() ? COLSEPHEIGHT : 0));
+ if (i >= itemList.getNumItems()) return LW_HT_DONTKNOW;
+ return i;
+}
+
+int ListWnd::hitTest(int x, int y, int drag) {
+ POINT pt={x, y};
+ return hitTest(pt, drag);
+}
+
+void ListWnd::selectRect(int x1, int y1, int x2, int y2) {
+
+}
+
+void ListWnd::drawRect(int x1, int y1, int x2, int y2) {
+ HDC dc = GetDC(gethWnd());
+ RECT r={x1,y1,x2,y2};
+ DrawFocusRect(dc, &r);
+ ReleaseDC(gethWnd(), dc);
+}
+
+LPARAM ListWnd::getItemData(int pos) {
+ if (pos >= itemList.getNumItems()) return 0;
+ listItem *item = itemList[pos];
+ if (item) return item->data;
+ return NULL;
+}
+
+int ListWnd::getItemLabel(int pos, int subpos, wchar_t *txt, int textmax)
+{
+ const wchar_t *t = getSubitemText(pos, subpos);
+ if (t)
+ {
+ WCSCPYN(txt, t, textmax);
+ return 1;
+ }
+ return 0;
+}
+
+void ListWnd::setItemLabel(int pos, const wchar_t *text)
+{
+ if (pos >= itemList.getNumItems()) return;
+ listItem *item = itemList[pos];
+ if (!item) return;
+ item->label = text;
+ invalidateItem(pos);
+}
+
+void ListWnd::resort() {
+ itemList.sort(TRUE);
+ invalidate();
+}
+
+int ListWnd::getSortDirection() {
+ return sortdir;
+}
+
+int ListWnd::getSortColumn() {
+ return sortcol;
+}
+
+void ListWnd::setSortDirection(int dir) {
+ sortdir=dir;
+}
+
+void ListWnd::setSortColumn(int col) {
+ sortcol=col;
+}
+
+int ListWnd::sortCompareItem(listItem *p1, listItem *p2)
+{
+ const wchar_t *l1=p1->label;
+ const wchar_t *l2=p2->label;
+
+ int i;
+
+ if(sortcol!=0)
+ {
+ if (p1->subitems != NULL)
+ {
+ for (i=0;i<p1->subitems->getNumItems();i++)
+ {
+ listSubitemStruct *subitem = p1->subitems->enumItem(i);
+ if (subitem->column == sortcol)
+ {
+ l1=subitem->label;
+ break;
+ }
+ }
+ } else {
+ l1 = L"";
+ }
+ if (p2->subitems != NULL) {
+ for (i=0;i<p2->subitems->getNumItems();i++) {
+ listSubitemStruct *subitem = p2->subitems->enumItem(i);
+ if (subitem->column == sortcol) {
+ l2=subitem->label;
+ break;
+ }
+ }
+ } else {
+ l2 = L"";
+ }
+ }
+
+ if(!columnsList.enumItem(sortcol)->getNumeric()) {
+ if(!sortdir) return(WCSICMP(l1, l2));
+ else return(WCSICMP(l2, l1));
+ } else {
+ int a=WTOI(l1),b=WTOI(l2);
+ if(!sortdir) return a-b;
+ else return b-a;
+ }
+}
+
+
+int ListWnd::findItemByParam(LPARAM param) {
+ for (int i=0;i<itemList.getNumItems();i++) {
+ if (itemList[i]->data == param)
+ return i;
+ }
+ return -1;
+}
+
+void ListWnd::setItemParam(int pos, LPARAM param) {
+ if (pos >= itemList.getNumItems()) return;
+ itemList[pos]->data = param;
+ invalidateItem(pos);
+}
+
+int ListWnd::deleteByPos(int pos) {
+ listItem *item = itemList[pos];
+ if (item == NULL) return 0;
+
+// selItemList.setSelected(pos, FALSE); // If you do not delete the item from the selItemList, you corrupt it for all item positions downstream of this one.
+ selItemList.deleteByPos(pos);
+
+ itemList.removeByPos(pos);
+
+ onItemDelete(item->data);
+
+ deleteListItem(item); item=NULL;
+
+ if (redraw) {
+ invalidate();
+ setSlidersPosition();
+ }
+ return 1;
+}
+
+void ListWnd::deleteAllItems() {
+ bool sav = getRedraw();
+ deselectAll();
+ setRedraw(FALSE);
+ selItemList.deselectAll(); //force desel so as to avoid the MEMCPY
+ while (itemList.getNumItems()) {
+ deleteByPos(0);
+ }
+ setRedraw(sav);
+// setSlidersPosition();
+}
+
+void ListWnd::setSubItem(int pos, int subpos, const wchar_t *txt)
+{
+ if (pos >= itemList.getNumItems()) return;
+ listItem *item = itemList[pos];
+ if (!item) return;
+ if (!item->subitems)
+ item->subitems = new PtrList<listSubitemStruct>;
+ for (int i=0;i<item->subitems->getNumItems();i++) {
+ listSubitemStruct *subitem = item->subitems->enumItem(i);
+ if (subitem->column == subpos) {
+ if (subitem->label) {
+ FREE(subitem->label);
+ subitem->label = NULL;
+ }
+ if (txt)
+ subitem->label = WCSDUP(txt);
+ invalidateItem(pos);
+ return;
+ }
+ }
+ listSubitemStruct *subitem = (listSubitemStruct *) MALLOC(sizeof(listSubitemStruct));
+ item->subitems->addItem(subitem);
+ subitem->label = WCSDUP(txt);
+ subitem->column = subpos;
+ invalidateItem(pos);
+}
+
+SkinBitmap *ListWnd::getItemIcon(int pos)
+{
+ if (pos >= itemList.getNumItems()) return NULL;
+ listItem *item = itemList[pos];
+ return item->icon;
+}
+
+void ListWnd::setItemIcon(int pos, const wchar_t *bitmapid) {
+ if (pos >= itemList.getNumItems()) return;
+ listItem *item = itemList[pos];
+ item->icon = bitmapid;
+ invalidateItem(pos);
+}
+
+const wchar_t *ListWnd::getSubitemText(int pos, int subpos) {
+ if (pos >= itemList.getNumItems()) return NULL;
+ listItem *item = itemList[pos];
+ if (!item) return NULL;
+ if (subpos == 0) {
+ return item->label;
+ }
+ if (!item->subitems) return NULL;
+ for (int i=0;i<item->subitems->getNumItems();i++) {
+ listSubitemStruct *subitem = item->subitems->enumItem(i);
+ if (subitem->column == subpos) {
+ return subitem->label;
+ }
+ }
+ return NULL;
+}
+
+listItem *ListWnd::createListItem() {
+ listItem *item = listItem_freelist.getRecord();
+ new(item) listItem();
+ item->setList(this);
+ return item;
+}
+
+void ListWnd::deleteListItem(listItem *item) {
+ if (item == NULL) return;
+ item->~listItem();
+ listItem_freelist.freeRecord(item);
+}
+
+ListColumn *ListWnd::enumListColumn(int pos) {
+ return columnsList[pos];
+}
+
+int ListWnd::getColumnPosByName(const wchar_t *name)
+{
+ for (int i = 0; i < columnsList.getNumItems(); i++)
+ {
+ const wchar_t *name2 = columnsList[i]->getName();
+ if (name2 == NULL) continue;
+ if (!wcscmp(name, name2)) return i;
+ }
+ return -1;
+}
+
+int ListWnd::delColumnByPos(int pos) {
+ if (pos < 0 || pos >= columnsList.getNumItems()) return 0;
+ delete columnsList[pos];
+ columnsList.removeByPos(pos);
+ recalcHeaders();
+ return 1;
+}
+
+void ListWnd::recalcHeaders() {
+ if (getNumColumns() <= 0) return;
+
+ int wid = 0, ndynamic = 0;
+ for (int i = 0; i < getNumColumns(); i++) {
+ ListColumn *col = enumListColumn(i);
+ if (!col->isDynamic()) wid += col->getWidth()+COLUMNS_MARGIN-1;
+ else ndynamic++;
+ }
+ if (ndynamic == 0) return;
+
+ RECT r = clientRect();
+ int wwidth = (r.right - r.left) - 2;
+
+ int leftover = wwidth - wid;
+ if (leftover <= 1) return;
+
+ leftover--;
+ leftover /= ndynamic;
+
+ for (int i = 0; i < getNumColumns(); i++) {
+ ListColumn *col = enumListColumn(i);
+ if (col->isDynamic()) col->setWidth(leftover);
+ }
+
+ //BU note: we could probably find a way to not invalidate everything
+ invalidate();
+}
+
+void ListWnd::itemSelection(int itemnum, int selected) {
+ notifySelChanged(itemnum, selected);
+ onItemSelection(itemnum, selected);
+}
+
+void ListWnd::onItemSelection(int itemnum, int selected) {
+ if (selected) {
+ Accessible *a = getAccessibleObject();
+ if (a != NULL)
+ a->onGetFocus(itemnum);
+ }
+}
+
+int ListWnd::doAddItem(const wchar_t *label, LPARAM lParam, int pos)
+{
+ listItem *item = createListItem();
+ item->label = label;
+ item->data = lParam;
+
+ itemList.addItem(item, pos, ITEMLIST_INC);
+ lastAddedItem = item;
+
+ if (redraw)
+ {
+ invalidate(); // todo: optimize to invalidate only if necessary
+ setSlidersPosition();
+ }
+
+ if (isInited()) calcBounds();
+ int p = (pos == POS_LAST) ? itemList.getNumItems()-1 : pos;
+ if (p <= selectionStart) selectionStart++;
+ if (autosort) {
+ itemList.sort();
+ p = itemList.searchItem(item);
+ }
+ return p;
+}
+
+void ListWnd::setMinimumSize(int size) {
+ if (size > 0) itemList.setMinimumSize(size);
+}
+
+int ListWnd::addItem(const wchar_t *label, LPARAM lParam)
+{
+ return doAddItem(label, lParam, POS_LAST);
+}
+
+int ListWnd::insertItem(int pos, const wchar_t *label, LPARAM lParam)
+{
+ return doAddItem(label, lParam, pos);
+}
+
+int ListWnd::getLastAddedItemPos() {
+ if (lastAddedItem == NULL) return -1;
+ return itemList.searchItem(lastAddedItem);
+}
+
+int ListWnd::getColumnsHeight() {
+ return columnsHeight;
+}
+
+int ListWnd::getColumnsWidth() {
+ int i, x=0;
+ for (i=0;i<columnsList.getNumItems();i++) x+= columnsList[i]->getWidth();
+ return x+1;
+}
+
+int ListWnd::insertColumn(ListColumn *col, int pos, int alignment)
+{
+ ASSERT(col != NULL);
+ ASSERT(pos >= -1);
+ if (pos < 0) col->setIndex(columnsList.getNumItems());
+ else col->setIndex(pos);
+ col->setList(this);
+ col->setAlignment(alignment);
+ columnsList.addItem(col);
+ if (pos >= 0) {
+ columnsList.moveItem(columnsList.getNumItems()-1, pos);
+ }
+ if (redraw && isInited()) {
+ invalidate();
+ setSlidersPosition();
+ }
+ recalcHeaders();
+ return columnsList.getNumItems();
+}
+
+void ListWnd::deleteAllColumns() {
+ columnsList.deleteAll();
+ if (redraw && isInited()) {
+ invalidate();
+ setSlidersPosition();
+ }
+ recalcHeaders();
+}
+
+int ListWnd::addColumn(const wchar_t *name, int width, int numeric, int align)
+{
+ ListColumn *col = new ListColumn();
+ col->setWidth(width);
+ col->setLabel(name);
+ col->setNumeric(numeric);
+ col->setAlignment(align);
+ return insertColumn(col, -1, align);
+}
+
+bool ListWnd::setRedraw(bool _redraw) {
+ bool prev = redraw;
+ if (!redraw && _redraw) {
+ invalidate();
+ setSlidersPosition();
+ notifySelChanged();
+ }
+ redraw = _redraw;
+ return prev;
+}
+
+bool ListWnd::getRedraw() {
+ return redraw;
+}
+
+int ListWnd::onChar(unsigned int c) {
+ //CT> Commented this out so shortcuts work in playlist editor
+ /*char b = TOUPPER(c);
+ if (b >= 'A' && b <= 'Z') {
+ jumpToNext(b);
+ return 1;
+ }*/
+
+ return LISTWND_PARENT::onChar(c);
+}
+
+int ListWnd::onKeyDown(int keyCode) {
+ switch (keyCode) {
+ case VK_DOWN:
+ next(selectonupdown);
+ return 1;
+ case VK_UP:
+ previous(selectonupdown);
+ return 1;
+ case VK_PRIOR:
+ pageup(selectonupdown);
+ return 1;
+ case VK_NEXT:
+ pagedown(selectonupdown);
+ return 1;
+ case VK_HOME:
+ home(selectonupdown);
+ return 1;
+ case VK_END:
+ end(selectonupdown);
+ return 1;
+ case VK_DELETE:
+ onDelete();
+ return 1;
+ case VK_RETURN: {
+ int i=getItemFocused();
+ //setSelected(i, 0, 0);
+ //setSelected(i, 1, 1);
+ if(i!=-1)
+ onDoubleClick(i);
+ return 1;
+ }
+ }
+ return LISTWND_PARENT::onKeyDown(keyCode);
+}
+
+void ListWnd::next(int wantcb) {
+ int from=getItemFocused();
+/* if (selItemList.getNumItems() > 0)
+ for (int i=0;i<itemList.getNumItems();i++)
+ if (getItemSelected(i)) {
+ from = i;
+ break;
+ }*/
+ int to = from + 1;
+ if (to < itemList.getNumItems() && to >= 0) {
+ setSelectionStart(to, wantcb);
+ if (!fullyVisible(to)) {
+ RECT c;
+ getClientRect(&c);
+ scrollToY((Y_SHIFT*2+(to+1)*(getItemHeight()+(wantColSepOnItems()?COLSEPHEIGHT:0)))-(c.bottom-c.top));
+ }
+ if (!wantcb)
+ {
+ wchar_t t[256]=L"";
+ getItemLabel(to, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+ }
+}
+
+void ListWnd::selectCurrent() {
+ int from=getItemFocused();
+ int to = from;
+ if (to < itemList.getNumItems() && to >= 0) {
+ setSelectionStart(to);
+ if (!fullyVisible(to)) {
+ RECT c;
+ getClientRect(&c);
+ scrollToY((Y_SHIFT*2+(to+1)*(getItemHeight()+(wantColSepOnItems()?COLSEPHEIGHT:0)))-(c.bottom-c.top));
+ }
+ }
+}
+
+void ListWnd::selectFirstEntry(int wantcb) {
+ setSelectionStart(0, wantcb);
+ ensureItemVisible(0);
+}
+
+void ListWnd::previous(int wantcb) {
+ int from=0;
+/* if (selItemList.getNumItems() > 0)
+ for (int i=0;i<itemList.getNumItems();i++)
+ if (getItemSelected(i)) {
+ from = i;
+ break;
+ }*/
+ from = getItemFocused();
+ int to = from - 1;
+ if (to < itemList.getNumItems() && to >= 0) {
+ setSelectionStart(to, wantcb);
+ ensureItemVisible(to);
+ if (!wantcb) {
+ wchar_t t[256]=L"";
+ getItemLabel(to, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+ }
+}
+
+void ListWnd::pagedown(int wantcb) {
+ int from=-1,to;
+ if (selItemList.getNumSelected())
+ for (int i=0;i<itemList.getNumItems();i++)
+ if (getItemSelected(i)) {
+ from = i;
+ break;
+ }
+ if(from==-1) to = 0;
+ else to = from + getLinesPerPage();
+ to=MIN(to,itemList.getNumItems()-1);
+ if(to>=0) {
+ setSelectionStart(to, wantcb);
+ if (!fullyVisible(to)) {
+ RECT c;
+ getClientRect(&c);
+ scrollToY((Y_SHIFT*2+(to+1)*(getItemHeight()+(wantColSepOnItems()?COLSEPHEIGHT:0)))-(c.bottom-c.top));
+ }
+ if (!wantcb) {
+ wchar_t t[256]=L"";
+ getItemLabel(to, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+ }
+}
+
+void ListWnd::pageup(int wantcb) {
+ int from=-1,to;
+ if (selItemList.getNumSelected())
+ for (int i=0;i<itemList.getNumItems();i++)
+ if (getItemSelected(i)) {
+ from = i;
+ break;
+ }
+ if(from==-1) to = 0;
+ else to = from - getLinesPerPage();
+ to=MAX(to,0);
+ to=MIN(to,itemList.getNumItems()-1);
+ if(to>=0) {
+ setSelectionStart(to, wantcb);
+ ensureItemVisible(to);
+ if (!wantcb) {
+ wchar_t t[256]=L"";
+ getItemLabel(to, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+ }
+}
+
+void ListWnd::home(int wantcb) {
+ if(!itemList.getNumItems()) return;
+ setSelectionStart(0, wantcb);
+ ensureItemVisible(0);
+ if (!wantcb) {
+ wchar_t t[256]=L"";
+ getItemLabel(0, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+}
+
+void ListWnd::end(int wantcb) {
+ if(!itemList.getNumItems()) return;
+ int i=itemList.getNumItems()-1;
+ setSelectionStart(i, wantcb);
+ if (!fullyVisible(i)) {
+ RECT c;
+ getClientRect(&c);
+ scrollToY((Y_SHIFT*2+(i+1)*(getItemHeight()+(wantColSepOnItems()?COLSEPHEIGHT:0)))-(c.bottom-c.top));
+ }
+ if (!wantcb) {
+ wchar_t t[256]=L"";
+ getItemLabel(i, 0, t, 255);
+ foreach(tempselectnotifies)
+ sendAction(tempselectnotifies.getfor(), L"tempselectnotify", t);
+ endfor;
+ }
+}
+
+void ListWnd::jumpToNext(wchar_t c)
+{
+ if (doJumpToNext(c, FALSE)) return;
+ doJumpToNext(c, TRUE);
+}
+
+int ListWnd::doJumpToNext(wchar_t c, bool fromtop)
+{
+ int from = 0;
+ if (!fromtop && selItemList.getNumSelected())
+ {
+ for (int i=0;i<itemList.getNumItems();i++)
+ if (getItemSelected(i))
+ {
+ from = i+1;
+ break;
+ }
+ }
+ for (int j=from;j<itemList.getNumItems();j++)
+ {
+ listItem *item = itemList[j];
+ if (item->label != NULL) {
+ wchar_t z = TOUPPERW(*(item->label));
+ if (z == c)
+ {
+ setSelectionStart(j);
+ ensureItemVisible(j);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+void ListWnd::reset() {
+ columnsList.deleteAll();
+ deleteAllItems();
+}
+
+void ListWnd::setShowColumnsHeaders(int show) {
+ int prev = showColumnsHeaders;
+ showColumnsHeaders = !!show;
+ if (prev != show) {
+ invalidate();
+ }
+}
+
+int ListWnd::onContextMenu (int x, int y) {
+ return notifyParent(ChildNotify::LISTWND_POPUPMENU, x, y);
+}
+
+void ListWnd::scrollUp(int lines) {
+ scrollToY(MAX(0, getScrollY()-getItemHeight()*lines));
+}
+
+void ListWnd::scrollLeft(int lines) {
+ scrollToX(MAX(0, getScrollX()-getItemHeight()*lines));
+}
+
+void ListWnd::scrollDown(int lines) {
+ scrollToY(MIN(getMaxScrollY(), getScrollY()+getItemHeight()*lines));
+}
+
+void ListWnd::scrollRight(int lines) {
+ scrollToX(MIN(getMaxScrollX(), getScrollX()+getItemHeight()*lines));
+}
+
+int ListWnd::onMouseWheelUp(int clicked, int lines) {
+ lines *= Wasabi::Std::osparam_getScrollLines();
+ if (!clicked)
+ scrollUp(lines);
+ else
+ scrollLeft(lines);
+ return 1;
+}
+
+int ListWnd::onMouseWheelDown(int clicked, int lines) {
+ lines *= Wasabi::Std::osparam_getScrollLines();
+ if (!clicked)
+ scrollDown(lines);
+ else
+ scrollRight(lines);
+ return 1;
+}
+
+int ListWnd::onColumnLabelClick(int col, int x, int y)
+{
+ if(lastcolsort==col) {
+ setSortDirection(1);
+ lastcolsort=-1;
+ } else {
+ setSortDirection(0);
+ lastcolsort=col;
+ }
+ setSortColumn(col);
+ resort();
+ return 1;
+}
+
+ARGB32 ListWnd::getTextColor(LPARAM lParam) {
+ return textColor;
+}
+
+ARGB32 ListWnd::getSelBgColor(LPARAM LParam) {
+ return color_item_selected;
+}
+
+ARGB32 ListWnd::getSelFgColor(LPARAM LParam) {
+ ARGB32 r = color_item_selected_fg;
+ if (r == 0xFFFFFFFF)
+ return color_item_selected_fg;
+ return r;
+}
+
+ARGB32 ListWnd::getBgColor() {
+ return bgcolor;
+}
+
+ARGB32 ListWnd::getFocusColor(LPARAM LParam) {
+ return color_item_focused;
+}
+
+ARGB32 ListWnd::getFocusRectColor(LPARAM lParam) {
+ return color_item_focusrect;
+}
+
+
+void ListWnd::moveItem(int from, int to) {
+ itemList.moveItem(from,to);
+ invalidate();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ListColumn
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ListColumn::ListColumn(const wchar_t *name, int isdynamic)
+: NamedW(name), dynamic(isdynamic)
+{
+ align=COL_LEFTALIGN;
+ index = -1;
+ width = COLUMNS_DEFAULT_WIDTH;
+ list = NULL;
+ numeric = 0;
+}
+
+void ListColumn::setLabel(const wchar_t *newlabel) {
+ setName(newlabel);
+}
+
+const wchar_t *ListColumn::getLabel() {
+ return getName();
+}
+
+void ListColumn::setIndex(int newindex) {
+ index = newindex;
+}
+
+int ListColumn::getIndex() {
+ return index;
+}
+
+void ListColumn::setWidth(int _width) {
+ width = _width;
+ if (list && list->getRedraw()) {
+ list->invalidate();
+ }
+}
+
+int ListColumn::getWidth() {
+ return width;
+}
+
+int ListColumn::customDrawHeader(Canvas *c, RECT *r, const Wasabi::FontInfo *fontInfo)
+{
+ int y = (r->bottom-r->top-c->getTextHeight(fontInfo)) / 2;
+ c->textOutEllipsed(r->left, y, r->right-r->left, c->getTextHeight(fontInfo), _(getName()), fontInfo);
+ return 1;
+}
+
+void ListColumn::setDynamic(int isdynamic)
+{
+ int prev = dynamic;
+ dynamic = !!isdynamic;
+ if (prev != dynamic && dynamic && list != NULL)
+ list->recalcHeaders();
+}
+
+void ListColumn::setList(ListWnd *_list) {
+ list = _list;
+}
+
+ListWnd *ListColumn::getList() {
+ return list;
+}
+
+int ListWnd::wantAutoContextMenu() {
+ return 0;
+}
+
+int ListWnd::onAcceleratorEvent(const wchar_t *name) {
+ if(!_wcsicmp(name, L"selectall")) {
+ selectAll();
+ return 1;
+ }
+ return 0;
+}
+
+int ListWnd::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ int r = LISTWND_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+ if (WCSCASEEQLSAFE(action, L"register_tempselectnotify")) {
+ tempselectnotifies.addItem(source);
+ }
+ else if (WCSCASEEQLSAFE(action, L"up")) {
+ previous((int)p1);
+ }
+ else if (WCSCASEEQLSAFE(action, L"down")) {
+ next((int)p1);
+ }
+ else if (WCSCASEEQLSAFE(action, L"home")) {
+ home((int)p1);
+ }
+ else if (WCSCASEEQLSAFE(action, L"end")) {
+ end((int)p1);
+ }
+ else if (WCSCASEEQLSAFE(action, L"pageup")) {
+ pageup((int)p1);
+ }
+ else if (WCSCASEEQLSAFE(action, L"pagedown")) {
+ pagedown((int)p1);
+ }
+ else if (WCSCASEEQLSAFE(action, L"select_current")) {
+ selectCurrent();
+ }
+ else if (WCSCASEEQLSAFE(action, L"doubleclick")) {
+ int pos = getItemFocused();
+ if (pos >= 0) onDoubleClick(pos);
+ return 1;
+ }
+ return r;
+}
+
+void ListWnd::setShowIcons(int icons)
+{
+ showicons = icons;
+ invalidate();
+}
+
+int ListWnd::getShowIcons ()
+{
+ return showicons;
+}
+
+int ListWnd::getIconWidth ()
+{
+ // The old behaviour used the itemheight as value, so we return this for backwards compatibility if iconWidth is negative
+ return (iconWidth < 0 ? itemHeight-2 : iconWidth);
+}
+
+void ListWnd::setIconWidth (int width)
+{
+ iconWidth = width;
+ invalidate();
+}
+
+int ListWnd::getIconHeight ()
+{
+ // The old behaviour used the itemheight as value, so we return this for backwards compatibility if iconWidth is negative
+ return (iconHeight < 0 ? itemHeight-2 : iconHeight);
+}
+
+void ListWnd::setIconHeight (int height)
+{
+ iconHeight = height;
+ invalidate();
+}
+
+int ListWnd::getItemHeight ()
+{
+ return (itemHeight < getIconHeight()+2) ? getIconHeight()+2 : itemHeight;
+}
+
+void ListWnd::setItemHeight (int height, bool forceInvalidate /*true*/)
+{
+ itemHeight = height;
+ if (forceInvalidate) invalidate();
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/listwnd.h b/Src/Wasabi/api/wnd/wndclass/listwnd.h
new file mode 100644
index 00000000..018986ca
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/listwnd.h
@@ -0,0 +1,459 @@
+#ifndef _LISTWND_H
+#define _LISTWND_H
+
+#include <api/wnd/wndclass/scbkgwnd.h>
+#include <bfc/common.h>
+
+#include <bfc/freelist.h>
+#include "SelItemList.h"
+#define POS_LAST -1
+
+#define LISTWND_PARENT ScrlBkgWnd
+
+#define LW_HT_DONTKNOW (-1)
+#define LW_HT_ABOVE (-10)
+#define LW_HT_BELOW (-20)
+
+#define COL_LEFTALIGN 0
+#define COL_CENTERALIGN 1
+#define COL_RIGHTALIGN 2
+
+class listItem;
+class ListWnd;
+class CompareListItem;
+
+class ListColumn : public NamedW
+{
+friend class ListWnd;
+public:
+ ListColumn(const wchar_t *name=NULL, int isdynamic=FALSE);
+ virtual ~ListColumn() { }
+
+ int getWidth();
+ void setWidth(int newwidth);
+ const wchar_t *getLabel();
+ void setLabel(const wchar_t *newlabel);
+ virtual int customDrawHeader(Canvas *c, RECT *cr, const Wasabi::FontInfo *fontInfo);
+ virtual int onHeaderClick() { return 0; }//return 1 if you override
+ virtual int onColumnLeftClick(int pos) { return 0; }//return 1 if you override
+ int getNumeric() { return numeric; }
+ void setDynamic(int isdynamic);
+ int isDynamic() { return dynamic; }
+ void setAlignment(int _align) { align = _align; }
+ int getAlignment() { return align; }
+
+protected:
+ void setIndex(int i);
+ int getIndex();
+ void setList(ListWnd *list);
+ ListWnd *getList();
+
+ void setNumeric(int n) { numeric=n; }
+
+private:
+ int width;
+ int index;
+ int numeric;
+ int dynamic;
+ ListWnd *list;
+ int align;
+};
+
+//class SelItemList;
+
+
+
+class ListWnd : public ScrlBkgWnd
+{
+friend class ListColumn;
+friend class SelItemList;
+public:
+ ListWnd();
+
+ virtual ~ListWnd();
+ virtual int onInit();
+ virtual int onPostOnInit();
+ virtual int onPaint(Canvas *canvas);
+ virtual int onResize();
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onRightButtonDown(int x, int y);
+ virtual int onRightButtonUp(int x, int y);
+ virtual int onMouseMove(int x, int y);
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int onChar(unsigned int c);
+ virtual int onKeyDown(int keyCode);
+ virtual int onContextMenu (int x, int y);
+ virtual int wantAutoContextMenu();
+ virtual int onMouseWheelUp(int click, int lines);
+ virtual int onMouseWheelDown(int click, int lines);
+ virtual int wantAutoDeselect() { return wantautodeselect; }
+ virtual void setWantAutoDeselect(int want) { wantautodeselect = want; }
+
+ void onSetVisible(int show);
+
+ void setAutoSort(bool dosort);
+ void setOwnerDraw(bool doownerdraw);
+
+ virtual void timerCallback(int id);
+
+ void next(int wantcb=1);
+ void selectCurrent();
+ void selectFirstEntry(int wantcb=1);
+ void previous(int wantcb=1);
+ void pagedown(int wantcb=1);
+ void pageup(int wantcb=1);
+ void home(int wantcb=1);
+ void end(int wantcb=1);
+ void setItemCount(int c);
+ void reset();
+ void setShowColumnsHeaders(int show);
+ int addColumn(const wchar_t *name, int width, int numeric=0, int align=COL_LEFTALIGN); // adds to end
+ ListColumn *getColumn(int n);
+ int getNumColumns();
+ int getColumnWidth(int col);
+ bool setRedraw(bool redraw); // returns prev state
+ bool getRedraw();
+ void setMinimumSize(int size);
+ virtual int addItem(const wchar_t *label, LPARAM lParam);
+ virtual int insertItem(int pos, const wchar_t *label, LPARAM lParam);
+ virtual int getLastAddedItemPos();
+ virtual void setSubItem(int pos, int subpos, const wchar_t *txt);
+ virtual void deleteAllItems();
+ virtual int deleteByPos(int pos);
+ int getNumItems(void);
+
+ virtual int getItemLabel(int pos, int subpos, wchar_t *text, int textmax);
+ virtual void setItemLabel(int pos, const wchar_t *text);
+ virtual LPARAM getItemData(int pos);
+ virtual int getItemRect(int pos, RECT *r);
+ virtual int getItemSelected(int pos); // returns 1 if selected
+ virtual int getItemFocused(int pos); // returns 1 if focused
+ virtual int getItemFocused(); // returns focused item
+ void setItemFocused(int pos, int ensure_visible=TRUE);
+ void ensureItemVisible(int pos);
+ void invalidateColumns();
+ virtual int scrollAbsolute(int x);
+ virtual int scrollRelative(int x);
+ virtual void scrollLeft(int lines=1);
+ virtual void scrollRight(int lines=1);
+ virtual void scrollUp(int lines=1);
+ virtual void scrollDown(int lines=1);
+ virtual const wchar_t *getSubitemText(int pos, int subpos);
+
+
+ int getFirstItemSelected();
+
+
+ int getNextItemSelected(int lastpos); // next item AFTER given pos
+
+
+ virtual int selectAll(int cb=1); // force all items selected
+
+ virtual int deselectAll(int cb=1); // force all items to be deselected
+
+ virtual int invertSelection(int cb=1); // invert all selections
+
+ virtual int hitTest(POINT pos, int drag=0);
+
+ /**
+ Method
+
+ @see
+ @ret
+ */
+ virtual int hitTest(int x, int y, int drag=0);
+
+ /**
+ Method
+
+ @see
+ @ret
+ */
+ virtual int invalidateItem(int pos);
+ virtual int locateData(LPARAM data);
+
+ // -1 if we've never been drawn yet
+
+ /**
+ Method
+
+ @see
+ @ret
+ */
+ int getFirstItemVisible() const { return firstItemVisible; }
+
+ /**
+ Method
+
+ @see
+ @ret
+ */
+ int getLastItemVisible() const { return lastItemVisible; }
+
+ virtual int setFontSize(int size);
+
+ virtual int getFontSize();
+ virtual void jumpToNext(wchar_t c);
+ int wantFocus() { return 1; }
+ void scrollToItem(int pos);
+ virtual void resort();
+ int getSortDirection();
+
+ /**
+ Method
+
+ @see
+ @ret
+ */
+ int getSortColumn();
+
+ void setSortColumn(int col);
+
+ void setSortDirection(int dir);
+
+ int findItemByParam(LPARAM param);
+
+ void setItemParam(int pos, LPARAM param);
+
+ int getItemCount() { return getNumItems(); }
+
+ void setSelectionStart(int pos, int wantcb=1);
+
+ /**
+ Method
+
+ @see
+ @ret
+ */
+ virtual void setSelectionEnd(int pos);
+
+ void setSelected(int pos, int selected, int cb=1);
+ void toggleSelection(int pos, int setfocus=TRUE, int cb=1);
+ virtual int getHeaderHeight();
+
+ // this sort function just provides string/numeric comparison
+ // if you need more types, just override and provide your own
+
+ virtual int sortCompareItem(listItem *p1, listItem *p2);
+
+ int getPreventMultipleSelection() { return preventMultipleSelection; }
+ int setPreventMultipleSelection(int val) { return preventMultipleSelection = val; }
+ void moveItem(int from, int to);
+ virtual int onAcceleratorEvent(const wchar_t *name);
+
+ // override this to turn the LPARAM into a text
+ virtual const wchar_t *convertlParam(LPARAM lParam) { return NULL; }
+ virtual void convertlParamColumn(int col, int pos, LPARAM param, wchar_t *str, int maxlen) { };
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+
+ // return 1 if you override this
+
+ virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int selected, int focused) { return 0; };
+ virtual void onPreItemDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int selected, int focused) { }
+ virtual void onPostItemDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int selected, int focused) { };
+ virtual ARGB32 getTextColor(LPARAM lParam);
+ int getTextAntialias(LPARAM lParam) { return antialias; }
+ virtual int getTextBold(LPARAM lParam) { return 0; }
+ virtual int getTextItalic(LPARAM lParam) { return 0; }
+ virtual ARGB32 getSelBgColor(LPARAM lParam);
+ virtual ARGB32 getSelFgColor(LPARAM lParam);
+ virtual ARGB32 getBgColor();
+ virtual ARGB32 getFocusColor(LPARAM lParam);
+ virtual ARGB32 getFocusRectColor(LPARAM lParam);
+ virtual int needFocusRect(LPARAM lParam) { return 0; }
+ virtual ARGB32 getColumnSepColor();
+ virtual int wantColSepOnItems();
+ virtual int getXShift();
+
+public:
+ int insertColumn(ListColumn *col, int pos=-1, int alignment=COL_LEFTALIGN);// -1 is add to end
+// void deleteColumn(int pos);
+ void deleteAllColumns();
+
+ void setHoverSelect(int a) { hoverselect = a; }
+ int getHoverSelect() { return hoverselect; }
+
+ void setSelectOnUpDown(int i) { selectonupdown = i; }
+ int getSelectOnUpDown() { return selectonupdown; }
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+
+ /**
+ Method
+ Will only work with simple text lists, be forwarned!!!
+
+ @see
+ @ret
+ */
+ int getItemHeight();
+ void setItemHeight(int height, bool forceInvalidate = true);
+
+ int getIconWidth();
+ void setIconWidth(int width);
+ int getIconHeight();
+ void setIconHeight(int height);
+
+protected:
+
+ virtual int getColumnsHeight();
+ virtual int getColumnsWidth();
+ virtual int getContentsWidth();
+ virtual int getContentsHeight();
+
+ virtual void drawBackground(Canvas *canvas);
+
+ void drawColumnHeaders(Canvas *c);
+
+ void drawItems(Canvas *canvas);
+
+ void updateScrollX();
+
+ void updateScrollY();
+ int doJumpToNext(wchar_t c, bool fromTop);
+ int fullyVisible(int pos);
+
+ virtual int onBeginDrag(int iItem);
+
+
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual void onSelectAll(); // hit Control-A
+
+ virtual void onDelete(); // hit 'delete'
+
+ virtual void onItemDelete(LPARAM lparam) {}
+
+ virtual void onDoubleClick(int itemnum); // double-click on an item
+ // this is called with the selected item#
+
+ virtual void onLeftClick(int itemnum); // left-click
+ // the second time you click on an already-focused item
+
+ virtual void onSecondLeftClick(int itemnum);
+ // this is called once for the item under cursor on click
+
+ virtual int onRightClick(int itemnum); // right-click on item
+
+ virtual int onIconLeftClick(int itemnum, int x, int y); // Returns 1 if we should not invoke onLeftClick()
+
+ // override this to be notified of item selections & deselections
+
+ virtual void onItemSelection(int itemnum, int selected);
+
+ virtual int onColumnDblClick(int col, int x, int y) { return 0; }
+
+ virtual int onColumnLabelClick(int col, int x, int y);
+
+ void selectRect(int x1, int y1, int x2, int y2);
+
+ void drawRect(int x1, int y1, int x2, int y2);
+
+ // interface to Freelist
+
+ listItem *createListItem();
+ void deleteListItem(listItem *item);
+ ListColumn *enumListColumn(int pos);
+
+ int getColumnPosByName(const wchar_t *name);
+
+ int delColumnByPos(int pos);
+public: // Martin> dunno why these were protected...
+ void setShowIcons(int icons);
+ int getShowIcons(); // Maybe useful or not
+ SkinBitmap *getItemIcon(int item);
+ void setItemIcon(int pos, const wchar_t *bitmapid);
+
+protected:
+ int item_invalidate_border;
+ bool showColumnsHeaders;
+ void recalcHeaders();
+ void itemSelection(int itemnum, int selected);
+
+private:
+ int doAddItem(const wchar_t *label, LPARAM lParam, int pos);
+
+
+ int hitTestColumns(POINT p, int *origin=NULL);
+ int hitTestColumnClient(int x);
+ int hitTestColumnsLabel(POINT p);
+ void drawXorLine(int x);
+ void calcNewColWidth(int col, int x);
+ void calcBounds();
+ void onDragTimer();
+ void notifySelChanged(int item=-1, int sel=-1);
+ virtual int wantResizeCols() { return 1; }
+
+ int autosort, ownerdraw;
+ int textsize;
+ int itemHeight;
+ int iconWidth; // If it's still negative use itemHeight instead -- better user getIconWidth()
+ int iconHeight;
+ bool metrics_ok;
+ bool redraw;
+ int columnsHeight;
+ int dragtimeron;
+
+ int antialias;
+
+ PtrList<ListColumn> columnsList;
+ PtrListQuickSorted<listItem,CompareListItem> itemList;
+
+ int firstItemVisible;
+ int lastItemVisible;
+
+ listItem *lastItemFocused;
+ int lastItemFocusedPos;
+
+ listItem *lastAddedItem;
+ SelItemList selItemList;
+
+ int dragskip;
+ int dragskipcount;
+ int selectionStart;
+ int colresize;
+ POINT colresizept;
+ bool resizing_col;
+ int colresizeo;
+
+ bool processbup;
+ bool bdown;
+ bool nodrag;
+ int bdownx, bdowny;
+ bool firstComplete, lastComplete;
+
+ int rectselecting;
+ POINT selectStart;
+ POINT selectLast;
+
+ int sortdir, sortcol, lastcolsort;
+
+ int preventMultipleSelection;
+
+ Freelist<listItem> listItem_freelist;
+ int wantautodeselect;
+
+ int hoverselect;
+ int selectonupdown;
+ PtrList<ifc_window> tempselectnotifies;
+ StringW accessibleItemName;
+ int showicons;
+
+private:
+ /* XML Parameters */
+ static XMLParamPair params[];
+ int xuihandle;
+ bool hasUserBg;
+
+ enum
+ {
+ LIST_ANTIALIAS = 0,
+ LIST_BACKGROUND,
+ LIST_TILE,
+ LIST_NOCOLHEADER,
+ };
+ protected:
+ int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/oswnd.cpp b/Src/Wasabi/api/wnd/wndclass/oswnd.cpp
new file mode 100644
index 00000000..021327ab
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/oswnd.cpp
@@ -0,0 +1,32 @@
+#include <precomp.h>
+#include "oswnd.h"
+
+int OSWnd::onInit()
+{
+ OSWND_PARENT::onInit();
+ onSetVisible(isVisible());
+ return 1;
+}
+
+void OSWnd::onSetVisible(int show)
+{
+#ifdef WIN32
+ ShowWindow(getOSHandle(), show ? SW_NORMAL : SW_HIDE);
+#endif
+}
+
+int OSWnd::onResize()
+{
+ OSWND_PARENT::onResize();
+#ifdef WIN32
+ if (getOSHandle())
+ {
+ RECT r;
+ getClientRect(&r);
+ SetWindowPos(getOSHandle(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+#endif
+ return 1;
+}
+
+
diff --git a/Src/Wasabi/api/wnd/wndclass/oswnd.h b/Src/Wasabi/api/wnd/wndclass/oswnd.h
new file mode 100644
index 00000000..7093dd6e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/oswnd.h
@@ -0,0 +1,19 @@
+#ifndef __OSWND_H
+#define __OSWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define OSWND_PARENT GuiObjectWnd
+
+class OSWnd : public OSWND_PARENT
+{
+public:
+ virtual int onInit();
+ virtual void onSetVisible(int show);
+ virtual int onResize();
+ virtual int handleRatio() { return 0; }
+
+ virtual HWND getOSHandle() = 0;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/oswndhost.cpp b/Src/Wasabi/api/wnd/wndclass/oswndhost.cpp
new file mode 100644
index 00000000..ab1a9680
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/oswndhost.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+#include "oswndhost.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS OSWndHostI
+START_DISPATCH;
+ VCB(OSWNDHOST_OSWNDHOST_HOST, oswndhost_host);
+ VCB(OSWNDHOST_OSWNDHOST_UNHOST, oswndhost_unhost);
+ VCB(OSWNDHOST_OSWNDHOST_SETREGIONOFFSETS, oswndhost_setRegionOffsets);
+END_DISPATCH;
+
+
diff --git a/Src/Wasabi/api/wnd/wndclass/oswndhost.h b/Src/Wasabi/api/wnd/wndclass/oswndhost.h
new file mode 100644
index 00000000..8e7503e5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/oswndhost.h
@@ -0,0 +1,53 @@
+#ifndef __OSWNDHOST_H
+#define __OSWNDHOST_H
+
+#include <bfc/dispatch.h>
+
+// {7050AACF-2731-4319-AF32-4ECE4CC8BDC4}
+static const GUID osWndHostGuid =
+ { 0x7050aacf, 0x2731, 0x4319, { 0xaf, 0x32, 0x4e, 0xce, 0x4c, 0xc8, 0xbd, 0xc4 } };
+
+
+class OSWndHost : public Dispatchable
+{
+public:
+ void oswndhost_host(HWND oswnd);
+ void oswndhost_unhost();
+ void oswndhost_setRegionOffsets(RECT *r);
+
+ DISPATCH_CODES
+ {
+ OSWNDHOST_OSWNDHOST_HOST = 0,
+ OSWNDHOST_OSWNDHOST_UNHOST = 5,
+ OSWNDHOST_OSWNDHOST_SETREGIONOFFSETS = 10,
+ };
+};
+
+inline void OSWndHost::oswndhost_host(HWND oswnd)
+{
+ _voidcall(OSWNDHOST_OSWNDHOST_HOST, oswnd);
+}
+
+inline void OSWndHost::oswndhost_unhost()
+{
+ _voidcall(OSWNDHOST_OSWNDHOST_UNHOST);
+}
+
+inline void OSWndHost::oswndhost_setRegionOffsets(RECT *r)
+{
+ _voidcall(OSWNDHOST_OSWNDHOST_SETREGIONOFFSETS, r);
+}
+
+class OSWndHostI : public OSWndHost
+{
+public:
+ virtual void oswndhost_host(HWND oswnd) = 0;
+ virtual void oswndhost_unhost() = 0;
+ virtual void oswndhost_setRegionOffsets(RECT *r) = 0;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/qpaintwnd.cpp b/Src/Wasabi/api/wnd/wndclass/qpaintwnd.cpp
new file mode 100644
index 00000000..dfdccc18
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/qpaintwnd.cpp
@@ -0,0 +1,357 @@
+#include <precomp.h>
+#include "qpaintwnd.h"
+#include <tataki/canvas/bltcanvas.h>
+#include "../nu/threadpool/TimerHandle.hpp"
+
+#define TIMER_QUICKPAINT 0x650
+
+// thread context, this is here so we can avoid the windows types in quickpaintwnd.h
+class QuickPaintContext
+{
+public:
+ QuickPaintContext(QuickPaintWnd *_wnd, int timeout)
+ {
+ killswitch = 0;
+ wnd = _wnd;
+ death = CreateEvent(NULL, FALSE, FALSE, NULL);
+ timer_ms = timeout;
+ WASABI_API_THREADPOOL->AddHandle(0, timer_handle, QPThreadPoolFunc, (void *)this, 0, 0/*api_threadpool::FLAG_LONG_EXECUTION*/);
+ timer_handle.Wait(timer_ms);
+ }
+
+ ~QuickPaintContext()
+ {
+ CloseHandle(death);
+ timer_handle.Close();
+ }
+
+ void Kill()
+ {
+ InterlockedExchangePointer((volatile PVOID*)&wnd, 0);
+ killswitch=1;
+ WaitForSingleObject(death, INFINITE);
+ }
+
+ QuickPaintWnd *wnd;
+ TimerHandle timer_handle;
+ HANDLE death;
+ volatile int killswitch;
+ int timer_ms;
+ static int QPThreadPoolFunc(HANDLE h, void *user_data, intptr_t t);
+};
+
+int QuickPaintContext::QPThreadPoolFunc(HANDLE h, void *user_data, intptr_t t)
+{
+ QuickPaintContext *context = (QuickPaintContext *)user_data;
+
+ if (context->killswitch)
+ {
+ WASABI_API_THREADPOOL->RemoveHandle(0, h);
+ SetEvent(context->death);
+ }
+ else
+ {
+ DWORD start = GetTickCount();
+ QuickPaintWnd *wnd = 0;
+ InterlockedExchangePointer((volatile PVOID*)&wnd, context->wnd);
+ if (wnd)
+ {
+ wnd->quickPaint();
+ TimerHandle timer_handle(h);
+ DWORD end = GetTickCount();
+ if (end-start > (DWORD)context->timer_ms)
+ timer_handle.Wait(1);
+ else
+ timer_handle.Wait(context->timer_ms - (end - start));
+ }
+ }
+
+ return 0;
+}
+
+
+// -----------------------------------------------------------------------
+QuickPaintWnd::QuickPaintWnd()
+{
+ invalidates_required = 0;
+ realtime = 1;
+ canvas_w = -1;
+ canvas_h = -1;
+ timerset = 0;
+ speed = 25;
+ enabled = 0;
+ render_canvas1 = NULL;
+ render_canvas2 = NULL;
+ paint_canvas = NULL;
+ thread_context = 0;
+
+ while (1)
+ {
+ svc_skinFilter *obj = sfe.getNext();
+ if (!obj) break;
+ filters.addItem(obj);
+ }
+ invalidated = 0;
+}
+
+// -----------------------------------------------------------------------
+QuickPaintWnd::~QuickPaintWnd()
+{
+ foreach(filters)
+ sfe.release(filters.getfor());
+ endfor;
+
+ KillThread();
+
+ delete render_canvas1;
+ delete render_canvas2;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::setRealtime(int rt)
+{
+ realtime = rt;
+}
+
+// -----------------------------------------------------------------------
+int QuickPaintWnd::getRealtime() const
+{
+ return realtime;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::setSpeed(int ms)
+{
+ speed = ms;
+ if (enabled && timerset)
+ {
+ if (thread_context)
+ thread_context->timer_ms = ms;
+ // let it change the timer value on the invalidate() timer
+ killTimer(TIMER_QUICKPAINT);
+ setTimer(TIMER_QUICKPAINT, getSpeed());
+ }
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::startQuickPaint()
+{
+ enabled = 1;
+ if (!isInited()) return;
+ CreateRenderThread();
+ timerset=1;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::stopQuickPaint()
+{
+ enabled = 0;
+ if (!isInited()) return;
+ KillThread();
+ timerset=0;
+}
+
+// -----------------------------------------------------------------------
+int QuickPaintWnd::isQuickPainting()
+{
+ return enabled;
+}
+
+// -----------------------------------------------------------------------
+int QuickPaintWnd::getSpeed()
+{
+ return speed;
+}
+
+// -----------------------------------------------------------------------
+int QuickPaintWnd::onInit()
+{
+ QUICKPAINTWND_PARENT::onInit();
+ if (enabled)
+ {
+ ASSERT(!thread_context);
+ CreateRenderThread();
+ timerset = 1;
+ }
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::timerCallback(int id)
+{
+ switch (id)
+ {
+ case TIMER_QUICKPAINT:
+ if (invalidates_required)
+ {
+ invalidated = 1;
+
+ if (getRealtime() && isVisible() && !isMinimized())
+ cascadeRepaint();
+ else
+ invalidate();
+
+ InterlockedExchange(&invalidates_required, 0);
+ }
+ //quickPaint();
+ break;
+ default:
+ QUICKPAINTWND_PARENT::timerCallback(id);
+ }
+}
+
+void QuickPaintWnd::SetPaintingCanvas(BltCanvas *c)
+{
+ InterlockedExchangePointer((volatile PVOID*)&paint_canvas, c);
+}
+
+BltCanvas *&QuickPaintWnd::GetDrawingConvas()
+{
+ if (paint_canvas == render_canvas2)
+ return render_canvas1;
+ else
+ return render_canvas2;
+}
+
+// -----------------------------------------------------------------------
+int QuickPaintWnd::quickPaint()
+{
+ int repaint=0;
+
+ int w, h;
+ getQuickPaintSize(&w, &h);
+
+ if (wantEvenAlignment())
+ {
+ if (w & 1) w++;
+ if (h & 1) h++;
+ }
+
+ if (w == 0 && h == 0) return 0;
+
+ BltCanvas *&render_canvas = GetDrawingConvas();
+ int newone = 0;
+
+ if (canvas_w != w || canvas_h != h)
+ {
+ delete render_canvas1; render_canvas1=0;
+ delete render_canvas2; render_canvas2=0;
+ }
+
+ if (!render_canvas)
+ {
+ render_canvas = new BltCanvas(w, wantNegativeHeight() ? -h : h, getOsWindowHandle());
+ canvas_w = w;
+ canvas_h = h;
+ newone = 1;
+ }
+
+ repaint = onQuickPaint(render_canvas, canvas_w, canvas_h, newone);
+
+ SetPaintingCanvas(render_canvas);
+ if (repaint)
+ InterlockedIncrement(&invalidates_required);
+
+ return repaint;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::getQuickPaintSize(int *w, int *h)
+{
+ RECT r;
+ getClientRect(&r);
+ if (w) *w = r.right - r.left;
+ if (h) *h = r.bottom - r.top;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::getQuickPaintSource(RECT *r)
+{
+ ASSERT(r != NULL);
+ r->left = 0;
+ r->right = canvas_w;
+ r->top = 0;
+ r->bottom = canvas_h;
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::getQuickPaintDest(RECT *r)
+{
+ ASSERT(r != NULL);
+ getClientRect(r);
+}
+
+// -----------------------------------------------------------------------
+void QuickPaintWnd::onSetVisible(int show)
+{
+ QUICKPAINTWND_PARENT::onSetVisible(show);
+ if (!show)
+ {
+ if (timerset)
+ {
+ KillThread();
+ timerset = 0;
+ }
+ }
+ else
+ {
+ if (enabled && !timerset)
+ {
+ CreateRenderThread();
+
+ timerset = 1;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+int QuickPaintWnd::onPaint(Canvas *canvas)
+{
+ QUICKPAINTWND_PARENT::onPaint(canvas);
+
+ if (!enabled) return 1;
+
+ BltCanvas *render_canvas;
+ InterlockedExchangePointer((volatile PVOID*)&render_canvas, paint_canvas);
+ if (!render_canvas) return 1;
+
+ RECT r;
+ getQuickPaintDest(&r);
+ RECT sr;
+ getQuickPaintSource(&sr);
+
+ if (invalidated && wantFilters())
+ {
+ foreach(filters)
+ filters.getfor()->filterBitmap((unsigned char *)render_canvas->getBits(), canvas_w, canvas_h, 32, NULL, getFiltersGroup());
+ endfor;
+ invalidated = 0;
+ }
+
+ render_canvas->/*getSkinBitmap()->*/stretchToRectAlpha(canvas, &sr, &r, getPaintingAlpha());
+ InterlockedExchange(&invalidates_required, 0);
+ return 1;
+}
+
+void QuickPaintWnd::KillThread()
+{
+ if (thread_context)
+ {
+ killTimer(TIMER_QUICKPAINT);
+ thread_context->Kill();
+ delete thread_context;
+ thread_context = 0;
+ }
+}
+
+void QuickPaintWnd::CreateRenderThread()
+{
+ int sp = getSpeed();
+ if (!thread_context)
+ {
+ thread_context = new QuickPaintContext(this, sp);
+ }
+ else
+ thread_context->timer_ms = sp;
+ setTimer(TIMER_QUICKPAINT, sp);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/qpaintwnd.h b/Src/Wasabi/api/wnd/wndclass/qpaintwnd.h
new file mode 100644
index 00000000..b758d440
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/qpaintwnd.h
@@ -0,0 +1,154 @@
+#ifndef __QPAINTWND_H
+#define __QPAINTWND_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/service/svcs/svc_skinfilter.h>
+
+#define QUICKPAINTWND_PARENT GuiObjectWnd
+
+/**
+ class QuickPaintWnd .
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+ @cat BFC
+*/
+class QuickPaintContext;
+class QuickPaintWnd : public QUICKPAINTWND_PARENT {
+
+ public:
+ /**
+ QuickPaintWnd constructor .
+
+ @see ~QuickPaintWnd()
+ */
+ QuickPaintWnd();
+
+ /**
+ Destructor for QuickPaintWnd .
+
+ @see QuickPaintWnd()
+ */
+ virtual ~QuickPaintWnd();
+
+ /**
+ QuickPaintWnd method onInit .
+
+ @ret 1
+ */
+ virtual int onInit();
+ virtual int onPaint(Canvas *c);
+
+ /**
+ QuickPaintWnd method timerCallback .
+
+ @param id Identifies requested action
+ */
+ virtual void timerCallback(int id);
+ virtual void onSetVisible(int show);
+
+ /**
+ QuickPaintWnd method setRealtime .
+
+ @see getRealtime()
+ @param rt
+ */
+ virtual void setRealtime(int rt);
+ int getRealtime() const;
+
+ /**
+ QuickPaintWnd method setSpeed sets the timer interval in milliseconds.
+
+ @see getSpeed()
+ @param ms The timer interval in milliseconds.
+ */
+ virtual void setSpeed(int ms);
+
+ /**
+ QuickPaintWnd method getSpeed gets the timer interval in milliseconds.
+
+ @see setSpeed()
+ @param ms The timer interval in milliseconds.
+ */
+ virtual int getSpeed();
+
+ /**
+ QuickPaintWnd method startQuickPaint .
+ */
+ virtual void startQuickPaint();
+
+ /**
+ QuickPaintWnd method stopQuickPaint .
+ */
+ virtual void stopQuickPaint();
+
+ /**
+ QuickPaintWnd method isQuickPainting .
+ */
+ virtual int isQuickPainting();
+
+ virtual int onQuickPaint(BltCanvas *c, int w, int h, int newone) { return 0; } // return 1 if your content has changed, or 0 to cancel update of your buffer to the window
+ virtual int wantEvenAlignment() { return 0; } // if you need even coordinates for your framebuffer, return 1 here
+
+ /**
+ QuickPaintWnd method getQuickPaintSize gets the client area width and
+ height.
+
+ @param w A pointer to the width to fill.
+ @param h A pointer to the height to fill.
+ */
+ virtual void getQuickPaintSize(int *w, int *h); // by default returns client width/height
+
+ /**
+ QuickPaintWnd method getQuickPaintSource .
+
+ @see getQuickPaintSize()
+ @assert r exists.
+ @ret None
+ @except
+ @param r
+ */
+ virtual void getQuickPaintSource(RECT *r); // by default returns the size of the quickpaint canvas
+
+ /**
+ QuickPaintWnd method getQuickPaintDest .
+
+ @see getQuickPaintSource()
+ @assert r exists.
+ @param r
+ */
+ virtual void getQuickPaintDest(RECT *r); // by default returns the size of client area
+ virtual int wantNegativeHeight() { return 0; }
+ virtual int wantFilters() { return 0; }
+ virtual const wchar_t *getFiltersGroup() { return L"Vis/Eq"; }
+
+ protected:
+int invalidated;
+ private:
+ /**
+ QuickPaintWnd method quickPaint .
+ */
+ friend class QuickPaintContext;
+ int quickPaint();
+ void KillThread();
+ void CreateRenderThread();
+ int realtime;
+ volatile LONG invalidates_required;
+ BltCanvas *render_canvas1, *render_canvas2, *paint_canvas;
+ void SetPaintingCanvas(BltCanvas *c);
+ BltCanvas *&GetDrawingConvas();
+ int canvas_w, canvas_h;
+ int speed;
+ int timerset;
+ int enabled;
+
+
+ PtrList<svc_skinFilter>filters;
+ SkinFilterEnum sfe;
+ QuickPaintContext *thread_context;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/rootwndholder.cpp b/Src/Wasabi/api/wnd/wndclass/rootwndholder.cpp
new file mode 100644
index 00000000..ad6000f3
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/rootwndholder.cpp
@@ -0,0 +1,113 @@
+#include "precomp.h"
+#include <api/wnd/api_wnd.h>
+
+#include "rootwndholder.h"
+#include <api/wnd/notifmsg.h>
+#include <tataki/canvas/canvas.h>
+
+
+RootWndHolder::RootWndHolder() {
+ privptr = NULL;
+}
+
+RootWndHolder::~RootWndHolder() {
+}
+
+void RootWndHolder::rootwndholder_getRect(RECT *r) {
+ if (isInited())
+ getClientRect(r);
+ else
+ MEMSET(r, 0, sizeof(RECT));
+}
+
+int RootWndHolder::onInit() {
+ ROOTWNDHOLDER_PARENT::onInit();
+ ifc_window *w = rootwndholder_getRootWnd();
+ if (w) {
+ checkInit(w);
+ setName(rootwndholder_getRootWnd()->getRootWndName());
+ }
+ return 1;
+}
+
+void RootWndHolder::checkInit(ifc_window *w) {
+ if (w && !w->isInited()) {
+ if (w->getParent() == NULL)
+ w->setParent(this);
+// w->setStartHidden(getStartHidden());
+ w->init(this);
+ }
+}
+
+int RootWndHolder::onResize() {
+ int rv = ROOTWNDHOLDER_PARENT::onResize();
+ if (!isInited()) return 1;
+ ifc_window *held = rootwndholder_getRootWnd();
+ if (!held) return rv;
+ RECT r;
+ rootwndholder_getRect(&r);
+ if (renderRatioActive() && !held->handleRatio())
+ multRatio(&r);
+ held->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ return rv;
+}
+
+/*void RootWndHolder::onSetVisible(int v) {
+ ROOTWNDHOLDER_PARENT::onSetVisible(v);
+ if (!rootwndholder_getRootWnd()) return;
+ rootwndholder_getRootWnd()->setVisible(v);
+}*/
+
+int RootWndHolder::onActivate() {
+ int r = ROOTWNDHOLDER_PARENT::onActivate();
+ if (rootwndholder_getRootWnd())
+ rootwndholder_getRootWnd()->onActivate();
+ return r;
+}
+
+int RootWndHolder::onDeactivate() {
+ int r = ROOTWNDHOLDER_PARENT::onDeactivate();
+ if (rootwndholder_getRootWnd())
+ rootwndholder_getRootWnd()->onDeactivate();
+ return r;
+}
+
+int RootWndHolder::getPreferences(int what) {
+ if (rootwndholder_getRootWnd())
+ return rootwndholder_getRootWnd()->getPreferences(what);
+ return ROOTWNDHOLDER_PARENT::getPreferences(what);
+}
+
+ifc_window *RootWndHolder::rootwndholder_getRootWnd() {
+ return privptr;
+}
+
+void RootWndHolder::rootwndholder_setRootWnd(ifc_window *w) {
+ if (privptr == w) return;
+ privptr = w;
+ checkInit(w);
+ if (isPostOnInit())
+ onResize();
+}
+
+int RootWndHolder::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (rootwndholder_getRootWnd())
+ return rootwndholder_getRootWnd()->onAction(action, param, x, y, p1, p2, data, datalen, source);
+ return ROOTWNDHOLDER_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
+int RootWndHolder::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+ if (msg == ChildNotify::NAMECHANGED && child == rootwndholder_getRootWnd())
+ setName(child->getRootWndName());
+ return passNotifyUp(child, msg, (int)param1, (int)param2);
+}
+
+int RootWndHolder::onPaint(Canvas *c) {
+ int rt = ROOTWNDHOLDER_PARENT::onPaint(c);
+ if (wantRenderBaseTexture()) {
+ RECT r;
+ rootwndholder_getRect(&r);
+ WASABI_API_WND->skin_renderBaseTexture(getBaseTextureWindow(), c, r, this);
+ }
+ return rt;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/rootwndholder.h b/Src/Wasabi/api/wnd/wndclass/rootwndholder.h
new file mode 100644
index 00000000..6c718ce5
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/rootwndholder.h
@@ -0,0 +1,41 @@
+#ifndef __ROOTWNDHOLD_H
+#define __ROOTWNDHOLD_H
+
+#include <api/wnd/virtualwnd.h>
+
+/**
+ A simple wnd that holds another window. Initializes it if needed, but DOES not delete it (and for a good reason, this is a ifc_window),
+ so your inheritor has to call whoever is needed to destroy the wnd
+*/
+
+#define ROOTWNDHOLDER_PARENT VirtualWnd
+
+class RootWndHolder : public ROOTWNDHOLDER_PARENT
+{
+ public:
+ RootWndHolder();
+ virtual ~RootWndHolder();
+
+ // override this
+ virtual ifc_window *rootwndholder_getRootWnd();
+ virtual void rootwndholder_getRect(RECT *r);
+ virtual void rootwndholder_setRootWnd(ifc_window *w);
+
+ // BaseWnd
+ virtual int onInit();
+ virtual int onResize();
+// virtual void onSetVisible(int v);
+ virtual int wantRenderBaseTexture() { return 0; }
+ virtual int onPaint(Canvas *c);
+ virtual int onActivate();
+ virtual int onDeactivate();
+ virtual int getPreferences(int what);
+ virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+
+ private:
+ void checkInit(ifc_window *w);
+ ifc_window *privptr;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/scbkgwnd.cpp b/Src/Wasabi/api/wnd/wndclass/scbkgwnd.cpp
new file mode 100644
index 00000000..758c7660
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/scbkgwnd.cpp
@@ -0,0 +1,869 @@
+#include <precomp.h>
+#include "scbkgwnd.h"
+#include <api/wnd/notifmsg.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define SCROLLBAR_SEP 4
+#define TIMER_SMOOTHSCROLLY 8873
+#define TIMER_SMOOTHSCROLLX 8874
+#define SMOOTH_STEPS 5
+#define DEFAULT_BGCOLOR RGB(0,0,0)
+
+ScrlBkgWnd::ScrlBkgWnd()
+{
+ inDestroy = FALSE;
+ bmp = NULL;
+ bgColor = DEFAULT_BGCOLOR;
+ scrollX = 0;
+ scrollY = 0;
+ dbbuffer = 1;
+ needSetSliders = FALSE;
+ lineHeight = 16;
+ wantsep = 0;
+ wantTileBg = true;
+ lastratio = 1.0;
+ MEMSET(&smsqr, 0, sizeof(RECT));
+ in_set_slider_position = 0;
+
+ smoothScrollYInc = smoothScrollXInc = 0;
+ smoothScrollYCur = smoothScrollXCur = 0;
+ smoothScrollYTimerCount = smoothScrollXTimerCount = 0;
+ smoothYTimer = smoothXTimer = 0;
+}
+
+ScrlBkgWnd::~ScrlBkgWnd()
+{
+ inDestroy = TRUE;
+}
+
+int ScrlBkgWnd::onInit()
+{
+
+ SCRLBKGWND_PARENT::onInit();
+
+ scrollY = 0;
+ scrollX = 0;
+
+ hSep.setOrientation(SEP_HORIZONTAL);
+
+ hScroll.setBitmaps(L"wasabi.scrollbar.horizontal.left",
+ L"wasabi.scrollbar.horizontal.left.pressed",
+ L"wasabi.scrollbar.horizontal.left.hover",
+ L"wasabi.scrollbar.horizontal.right",
+ L"wasabi.scrollbar.horizontal.right.pressed",
+ L"wasabi.scrollbar.horizontal.right.hover",
+ L"wasabi.scrollbar.horizontal.button",
+ L"wasabi.scrollbar.horizontal.button.pressed",
+ L"wasabi.scrollbar.horizontal.button.hover");
+
+ hScroll.setBackgroundBitmaps(L"wasabi.scrollbar.horizontal.background.left",
+ L"wasabi.scrollbar.horizontal.background.middle",
+ L"wasabi.scrollbar.horizontal.background.right");
+
+ vSep.setOrientation(SEP_VERTICAL);
+
+ vScroll.setBitmaps(L"wasabi.scrollbar.vertical.left",
+ L"wasabi.scrollbar.vertical.left.pressed",
+ L"wasabi.scrollbar.vertical.left.hover",
+ L"wasabi.scrollbar.vertical.right",
+ L"wasabi.scrollbar.vertical.right.pressed",
+ L"wasabi.scrollbar.vertical.right.hover",
+ L"wasabi.scrollbar.vertical.button",
+ L"wasabi.scrollbar.vertical.button.pressed",
+ L"wasabi.scrollbar.vertical.button.hover");
+
+ vScroll.setBackgroundBitmaps(L"wasabi.scrollbar.vertical.background.top",
+ L"wasabi.scrollbar.vertical.background.middle",
+ L"wasabi.scrollbar.vertical.background.bottom");
+
+ // hScroll->setVertical(FALSE);
+ vScroll.setVertical(TRUE);
+
+ hScroll.setStartHidden(TRUE); // prevent showing window at creation
+ vScroll.setStartHidden(TRUE);
+ hSep.setStartHidden(TRUE);
+ vSep.setStartHidden(TRUE);
+
+ hScroll.setParent(this);
+ vScroll.setParent(this);
+ hSep.setParent(this);
+ vSep.setParent(this);
+
+ hScroll.init(getOsModuleHandle(), getOsWindowHandle());
+ vScroll.init(getOsModuleHandle(), getOsWindowHandle());
+ hSep.init(getOsModuleHandle(), getOsWindowHandle());
+ vSep.init(getOsModuleHandle(), getOsWindowHandle());
+
+ hScroll.setPosition(0);
+ vScroll.setPosition(0);
+
+ setSlidersPosition(); // position sliders and show them if needed
+
+ return 1;
+}
+
+void ScrlBkgWnd::setBgBitmap(const wchar_t *b)
+{
+ bmp = b;
+ if (b) setBgColor(DEFAULT_BGCOLOR);
+}
+
+void ScrlBkgWnd::setBgColor(ARGB32 rgb)
+{
+ bgColor = rgb;
+}
+
+SkinBitmap *ScrlBkgWnd::getBgBitmap(void)
+{
+ return bmp;
+}
+
+ARGB32 ScrlBkgWnd::getBgColor(void)
+{
+ return bgColor;
+}
+
+// Scroll to a specified Y-pixels
+void ScrlBkgWnd::scrollToY(int y, int signal)
+{
+
+ WndCanvas *canvas = NULL;
+ RECT r;
+ int offset;
+ int dor2 = 0;
+ RECT r2 = {0, 0, 0, 0};
+ int focused = gotFocus();
+
+ if (isVirtual() || renderRatioActive())
+ {
+ scrollY = y;
+ invalidateRect(&clientRect());
+ onScrollY(y);
+ return ;
+ }
+
+ if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ; // no need to paint
+
+ if (y > scrollY)
+ { // tree scrolling up, scroller going down. invalidating from the bottom. bitblting from bottom to top
+ int lines = y - scrollY;
+ offset = -lines;
+ getClientRect(&r);
+ canvas = new WndCanvas();
+ canvas->attachToClient(this);
+
+ RegionI reg;
+ makeWindowOverlayMask(&reg);
+ RegionI clip(&r);
+ reg.offset(0, offset);
+ clip.subtractRegion(&reg);
+ canvas->selectClipRgn(&clip);
+
+ int b = hScroll.isVisible() ? hScroll.getHeight() : 0;
+ int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
+ int a = focused && (!b);
+ if (r.bottom-r.top-lines > 0)
+ canvas->blit(r.left, r.top+lines, canvas, r.left, r.top, r.right-r.left- c, r.bottom-r.top-lines-a - b);
+
+// int a = focused && (!hScroll->isVisible());
+ //if (r.bottom - r.top - lines > 0)
+// canvas->blit(r.left, r.top + lines, canvas, r.left, r.top, r.right - r.left, r.bottom - r.top - lines - a);
+
+ canvas->selectClipRgn(NULL);
+ if (!clip.isEmpty())
+ invalidateRgn(&clip);
+
+
+ getClientRect(&r2);
+ r2.bottom = r2.top + 1;
+ dor2 = 1;
+ r.top = r.bottom - lines - 1;
+ }
+ if (y < scrollY)
+ { // tree scrolling down, scroller going up. invalidating from the top. bitblting from top to bottom
+ int lines = scrollY - y;
+ offset = lines;
+ getClientRect(&r);
+ canvas = new WndCanvas();
+ canvas->attachToClient(this);
+
+ RegionI reg;
+ makeWindowOverlayMask(&reg);
+ RegionI clip(&r);
+ reg.offset(0, offset);
+ clip.subtractRegion(&reg);
+ canvas->selectClipRgn(&clip);
+
+ int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
+ canvas->blit(r.left, r.top+focused, canvas, r.left, r.top+lines+focused, r.right-r.left-c, r.bottom-r.top-lines-focused);
+ //canvas->blit(r.left, r.top + focused, canvas, r.left, r.top + lines + focused, r.right - r.left, r.bottom - r.top - lines - focused);
+
+ canvas->selectClipRgn(NULL);
+ if (!clip.isEmpty())
+ invalidateRgn(&clip);
+
+ getClientRect(&r2);
+ r2.top = r2.bottom - 1;
+ dor2 = 1;
+ r.bottom = r.top + lines + 1;
+ }
+ if (canvas)
+ {
+ delete canvas;
+ scrollY = y;
+
+ // in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
+ RECT cr;
+ getClientRect(&cr);
+ cr.top -= getHeaderHeight();
+ RECT screenblit;
+ SubtractRect(&screenblit, &cr, &r);
+
+ // invalidate what's needed
+ if (dor2 && focused)
+ cascadeRepaintRect(&r2, 0);
+ cascadeRepaintRect(&r);
+
+ deferedInvalidateRect(&screenblit);
+
+ //dbbuffer = 1;
+ //repaint();
+ }
+
+ if (signal)
+ updateVScroll(y);
+
+ onScrollY(y);
+}
+
+// Scroll to a specified X-pixel
+void ScrlBkgWnd::scrollToX(int x, int signal)
+{
+ WndCanvas *canvas = NULL;
+ RECT r;
+ int offset;
+ int dor2 = 0;
+ RECT r2 = {0, 0, 0, 0};
+ int focused = gotFocus();
+
+ if (isVirtual() || ABS(getRenderRatio() - 1.0) > 0.01)
+ {
+ scrollX = x;
+ getClientRect(&r);
+ invalidateRect(&r);
+ return ;
+ }
+
+ if (x > scrollX)
+ { // tree scrolling left, scroller going right. invalidating from the right. bitblting from right to left
+ int lines = x - scrollX;
+ offset = -lines;
+ getClientRect(&r);
+ r.top -= getHeaderHeight();
+ canvas = new WndCanvas();
+ canvas->attachToClient(this);
+
+ RegionI reg;
+ makeWindowOverlayMask(&reg);
+ RegionI clip(&r);
+ reg.offset(offset, 0);
+ clip.subtractRegion(&reg);
+ canvas->selectClipRgn(&clip);
+
+ int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
+ canvas->blit(r.left+lines, r.top, canvas, r.left, r.top, r.right-r.left-lines-focused-c, r.bottom-r.top);
+ //canvas->blit(r.left + lines, r.top, canvas, r.left, r.top, r.right - r.left - lines - focused, r.bottom - r.top);
+
+ canvas->selectClipRgn(NULL);
+ if (!reg.isEmpty())
+ invalidateRgn(&reg);
+
+ getClientRect(&r2);
+ r2.right = r2.left + 1;
+ dor2 = 1;
+ r.left = r.right - lines - 1;
+ }
+ if (x < scrollX)
+ { // tree scrolling right, scroller going left. invalidating from the left. bitblting from left to right
+ int lines = scrollX - x;
+ offset = lines;
+ getClientRect(&r);
+ r.top -= getHeaderHeight();
+ canvas = new WndCanvas();
+ canvas->attachToClient(this);
+
+ RegionI reg;
+ makeWindowOverlayMask(&reg);
+ RegionI clip(&r);
+ reg.offset(offset, 0);
+ clip.subtractRegion(&reg);
+ canvas->selectClipRgn(&clip);
+
+ int a = focused && (!vScroll.isVisible());
+ int c = hScroll.isVisible() ? hScroll.getHeight()-focused : 0;
+ canvas->blit(r.left+a, r.top, canvas, r.left+lines, r.top, r.right-r.left-lines-a, r.bottom-r.top-c);
+
+ //int a = focused && (!vScroll->isVisible());
+// canvas->blit(r.left + a, r.top, canvas, r.left + lines, r.top, r.right - r.left - lines - a, r.bottom - r.top);
+
+ canvas->selectClipRgn(NULL);
+ if (!reg.isEmpty())
+ invalidateRgn(&reg);
+
+ getClientRect(&r2);
+ r2.left = r2.right - 1;
+ dor2 = 1;
+ r.right = r.left + lines + 1;
+ }
+ if (canvas)
+ {
+ delete canvas;
+ scrollX = x;
+
+ // in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
+ RECT cr;
+ getClientRect(&cr);
+ cr.top -= getHeaderHeight();
+ RECT screenblit;
+ SubtractRect(&screenblit, &cr, &r);
+ deferedInvalidateRect(&screenblit);
+
+ if (dor2 && focused)
+ cascadeRepaintRect(&r2, 0);
+ // invalidate what's needed
+ cascadeRepaintRect(&r);
+
+ //dbbuffer = 1;
+ //repaint();
+ }
+
+ if (signal)
+ updateHScroll(x);
+}
+
+void ScrlBkgWnd::setSlidersPosition()
+{
+ if (in_set_slider_position) return ;
+ in_set_slider_position = 1;
+ _setSlidersPosition();
+ in_set_slider_position = 0;
+}
+
+void ScrlBkgWnd::_setSlidersPosition()
+{
+
+ if (!isInited()) return ;
+
+ RECT d;
+ getClientRect(&d);
+ if ((d.left >= d.right) || (d.top >= d.bottom))
+ return ;
+
+ RECT r;
+ if (inDestroy) return ;
+ if (!isVisible())
+ {
+ needSetSliders = TRUE;
+ return ;
+ }
+
+ needSetSliders = FALSE;
+
+ if (needHScroll())
+ {
+ SCRLBKGWND_PARENT::getClientRect(&r);
+ r.top = r.bottom - getScrollbarWidth();
+ if (needVScroll())
+ r.right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
+ RECT z; hScroll.getClientRect(&z);
+ if (!Wasabi::Std::rectEqual(r, z))
+ { // assumes ScrollBars are virtual
+ hScroll.resizeToRect(&r);
+ RECT s = r;
+ s.bottom = s.top;
+ s.top -= (wantsep ? SCROLLBAR_SEP : 0);
+ hSep.resizeToRect(&s);
+ }
+ if (!hScroll.isVisible())
+ {
+ hScroll.setVisible(TRUE);
+ if (wantsep) hSep.setVisible(TRUE);
+ onHScrollToggle(1);
+ }
+ hScroll.setNPages(((int)(getContentsWidth() / (r.right - r.left))) + 1);
+ hScroll.setUpDownValue((int)(((float)lineHeight / (getContentsWidth() - (r.right - r.left)))*SCROLLBAR_FULL));
+ hScroll.setPosition((int)((float)scrollX / getMaxScrollX() * SCROLLBAR_FULL));
+ }
+ else
+ {
+ if (hScroll.isVisible())
+ {
+ hScroll.setVisible(FALSE);
+ if (wantsep) hSep.setVisible(FALSE);
+ onHScrollToggle(0);
+ }
+ hScroll.setPosition(0);
+ scrollToX(0);
+ }
+
+ if (needVScroll())
+ {
+ SCRLBKGWND_PARENT::getClientRect(&r);
+ r.left = r.right - getScrollbarWidth();
+ if (needHScroll())
+ r.bottom -= getScrollbarWidth();
+ RECT z; vScroll.getNonClientRect(&z);
+ if (!Wasabi::Std::rectEqual(r, z))
+ {
+ vScroll.resizeToRect(&r);
+ RECT s = r;
+ s.right = s.left;
+ s.left -= (wantsep ? SCROLLBAR_SEP : 0);
+ vSep.resizeToRect(&s);
+ }
+ if (!vScroll.isVisible())
+ {
+ vScroll.setVisible(TRUE);
+ if (wantsep) vSep.setVisible(TRUE);
+ onVScrollToggle(1);
+ }
+ vScroll.setNPages(((int)(getContentsHeight() / (r.bottom - r.top))) + 1);
+ vScroll.setUpDownValue((int)(((float)lineHeight / (getContentsHeight() - (r.bottom - r.top)))*SCROLLBAR_FULL));
+ vScroll.setPosition((int)((float)scrollY / getMaxScrollY() * SCROLLBAR_FULL));
+ }
+ else
+ {
+ if (vScroll.isVisible())
+ {
+ vScroll.setVisible(FALSE);
+ if (wantsep) vSep.setVisible(FALSE);
+ onVScrollToggle(0);
+ }
+ vScroll.setPosition(0);
+ scrollToY(0);
+ }
+
+ hSep.invalidate();
+ vSep.invalidate();
+
+ if (needHScroll() && needVScroll())
+ {
+ getNonClientRect(&smsqr);
+ smsqr.left = smsqr.right - getScrollbarWidth();
+ smsqr.top = smsqr.bottom - getScrollbarWidth();
+ invalidateRect(&smsqr);
+ }
+ else
+ ZERO(smsqr);
+}
+
+void ScrlBkgWnd::onHScrollToggle(int set)
+{}
+
+void ScrlBkgWnd::onVScrollToggle(int set)
+{}
+
+int ScrlBkgWnd::onPaint(Canvas *canvas)
+{
+ RECT d;
+ getClientRect(&d);
+ if (d.right > d.left + 0xFFFF || d.bottom > d.top + 0xFFFF) return 1;
+ if ((d.left >= d.right) || (d.top >= d.bottom))
+ {
+ return SCRLBKGWND_PARENT::onPaint(canvas);
+ }
+
+ if (needSetSliders) setSlidersPosition();
+
+ // RECT z;
+ // GetUpdateRect(gethWnd(), &z, FALSE);
+
+ PaintCanvas paintcanvas;
+ PaintBltCanvas paintbcanvas;
+
+ if (canvas == NULL)
+ {
+ if (dbbuffer)
+ {
+ if (!paintbcanvas.beginPaintNC(this)) return 0;
+ canvas = &paintbcanvas;
+ }
+ else
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ }
+ //dbbuffer=1;
+ SCRLBKGWND_PARENT::onPaint(canvas);
+
+ RegionI *smsq = NULL;
+
+ if (needHScroll() && needVScroll())
+ {
+ renderBaseTexture(canvas, smsqr);
+ smsq = new RegionI(&smsqr);
+ }
+
+ RECT r;
+ LabelWnd::getNonClientRect(&r);
+ RECT c = {r.left, r.top, r.right, r.top + getLabelHeight()}; // create label rect
+
+
+ RegionI *clip = new RegionI();
+ if (canvas->getClipRgn(clip) == 0)
+ {
+ delete clip;
+ clip = new RegionI(&r);
+ if (smsq) clip->subtractRegion(smsq);
+ canvas->selectClipRgn(clip);
+ }
+ else
+ {
+ RegionI reg(&c);
+ clip->subtractRegion(&reg);
+ if (smsq) clip->subtractRegion(smsq);
+ canvas->selectClipRgn(clip);
+ }
+ delete smsq;
+
+ drawBackground(canvas);
+ delete clip;
+
+if (getRenderRatio() != lastratio) { invalidate(); lastratio = getRenderRatio(); } // todo: make that an event
+ return 1;
+}
+
+int ScrlBkgWnd::needDoubleBuffer()
+{
+ return dbbuffer;
+}
+
+int ScrlBkgWnd::onEraseBkgnd(HDC dc)
+{
+
+ /* DCCanvas canvas;
+ canvas.cloneDC(dc);
+
+ drawBackground(&canvas);*/
+
+ return 1;
+}
+
+// Draws tiled background
+void ScrlBkgWnd::drawBackground(Canvas *canvas)
+{
+ RECT r(clientRect());
+ RegionI reg(&r);
+ RegionI old;
+ canvas->getClipRgn(&old);
+ reg.andRegion(&old);
+ canvas->selectClipRgn(&reg);
+ if (bmp.getBitmap() && bgColor == DEFAULT_BGCOLOR)
+ {
+ r.top -= scrollY % bmp.getBitmap()->getHeight();
+ r.left -= scrollX % bmp.getBitmap()->getWidth();
+ if (wantTileBg)
+ bmp.getBitmap()->blitTile(canvas, &r);
+ else
+ bmp.getBitmap()->stretchToRect(canvas, &r);
+ }
+ else if (bgColor != DEFAULT_BGCOLOR)
+ {
+ canvas->fillRect(&r, bgColor);
+ }
+ canvas->selectClipRgn(&old);
+
+}
+
+bool ScrlBkgWnd::needHScroll()
+{
+ if (!wantHScroll()) return FALSE;
+ RECT r;
+ getNonClientRect(&r);
+ if (vScroll.isVisible())
+ r.right -= getScrollbarWidth();
+ return (getContentsWidth() > r.right - r.left);
+}
+
+bool ScrlBkgWnd::needVScroll()
+{
+ if (!wantVScroll()) return FALSE;
+ RECT r;
+ getNonClientRect(&r);
+ r.top += getHeaderHeight();
+ if (hScroll.isVisible())
+ r.bottom -= getScrollbarWidth();
+ return (getContentsHeight() > r.bottom - r.top);
+}
+
+// Returns the current tree width in pixels
+int ScrlBkgWnd::getContentsWidth()
+{
+ /*RECT r;
+ ScrlBkgWnd::getClientRect(&r);
+ return r.right-r.left;*/
+ return 10000;
+}
+
+// Returns the current tree height in pixels
+int ScrlBkgWnd::getContentsHeight()
+{
+ /*RECT r;
+ ScrlBkgWnd::getClientRect(&r);
+ return r.bottom-r.top;*/
+ return 10000;
+}
+
+int ScrlBkgWnd::getMaxScrollY()
+{
+ RECT r;
+ getClientRect(&r);
+ return MAX<int>(0, getContentsHeight() - (r.bottom - r.top));
+}
+
+int ScrlBkgWnd::getMaxScrollX()
+{
+ RECT r;
+ getClientRect(&r);
+ return MAX<int>(0, getContentsWidth() - (r.right - r.left));
+}
+
+void ScrlBkgWnd::updateVScroll(int y)
+{
+ if (getMaxScrollY() == 0) { vScroll.setPosition(0); return ; }
+ int z = (int)((float)y / getMaxScrollY() * SCROLLBAR_FULL);
+ vScroll.setPosition(z);
+}
+
+void ScrlBkgWnd::updateHScroll(int x)
+{
+ if (getMaxScrollX() == 0) { hScroll.setPosition(0); return ; }
+ int z = (int)((float)x / getMaxScrollX() * SCROLLBAR_FULL);
+ hScroll.setPosition(z);
+}
+
+void ScrlBkgWnd::updateScrollY(bool smooth)
+{
+ if (getMaxScrollY() == 0) { scrollToY(0); return ; }
+ int y = (int)((float)(vScroll.getPosition()) / SCROLLBAR_FULL * getMaxScrollY());
+ if (!smooth)
+ scrollToY(y /*& ~3*/);
+ else
+ smoothScrollToY(y);
+}
+
+void ScrlBkgWnd::updateScrollX(bool smooth)
+{
+ if (getMaxScrollX() == 0) { scrollToX(0); return ; }
+ int x = (int)((float)(hScroll.getPosition()) / SCROLLBAR_FULL * getMaxScrollX());
+ if (!smooth)
+ scrollToX(x /*& ~3*/);
+ else
+ smoothScrollToX(x);
+}
+
+void ScrlBkgWnd::smoothScrollToX(int x)
+{
+ killSmoothXTimer();
+ smoothScrollXInc = -(float)(scrollX - x) / SMOOTH_STEPS;
+ smoothScrollXCur = (float)scrollX;
+ smoothScrollXTimerCount = 0;
+ smoothXTimer = 1;
+ setTimer(TIMER_SMOOTHSCROLLX, 25);
+}
+
+void ScrlBkgWnd::killSmoothYTimer()
+{
+ if (smoothYTimer)
+ {
+ killTimer(TIMER_SMOOTHSCROLLY);
+ smoothScrollYCur += smoothScrollYInc * (SMOOTH_STEPS - smoothScrollYTimerCount);
+ scrollToY((int)smoothScrollYCur);
+ smoothYTimer = 0;
+ updateVScroll(scrollY);
+ }
+}
+
+void ScrlBkgWnd::killSmoothXTimer()
+{
+ if (smoothXTimer)
+ {
+ killTimer(TIMER_SMOOTHSCROLLX);
+ smoothScrollXCur += smoothScrollXInc * (SMOOTH_STEPS - smoothScrollXTimerCount);
+ scrollToX((int)smoothScrollXCur);
+ smoothXTimer = 0;
+ updateHScroll(scrollX);
+ }
+}
+
+void ScrlBkgWnd::smoothScrollToY(int y)
+{
+ killSmoothYTimer();
+ smoothScrollYInc = -(float)(scrollY - y) / SMOOTH_STEPS;
+ smoothScrollYCur = (float)scrollY;
+ smoothScrollYTimerCount = 0;
+ smoothYTimer = 1;
+ setTimer(TIMER_SMOOTHSCROLLY, 25);
+}
+
+void ScrlBkgWnd::timerCallback(int id)
+{
+ switch (id)
+ {
+ case TIMER_SMOOTHSCROLLY:
+ smoothScrollYCur += smoothScrollYInc;
+ scrollToY((int)smoothScrollYCur, FALSE);
+ if (++smoothScrollYTimerCount == SMOOTH_STEPS)
+ killSmoothYTimer();
+ return ;
+ case TIMER_SMOOTHSCROLLX:
+ smoothScrollXCur += smoothScrollXInc;
+ scrollToX((int)smoothScrollXCur, FALSE);
+ if (++smoothScrollXTimerCount == SMOOTH_STEPS)
+ killSmoothXTimer();
+ return ;
+ }
+ SCRLBKGWND_PARENT::timerCallback(id);
+}
+
+// Gets notification from sliders
+int ScrlBkgWnd::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2)
+{
+ switch (msg)
+ {
+ case ChildNotify::SCROLLBAR_SETPOSITION:
+ if (child == &vScroll)
+ {
+ updateScrollY(!!param1);
+ return 1;
+ }
+ if (child == &hScroll)
+ {
+ updateScrollX(!!param1);
+ return 1;
+ }
+ break;
+ }
+
+ return SCRLBKGWND_PARENT::childNotify(child, msg, param1, param2);
+}
+
+int ScrlBkgWnd::onResize()
+{
+ int rt = SCRLBKGWND_PARENT::onResize();
+ if (!isInited()) return rt;
+ invalidateRect(&smsqr);
+ setSlidersPosition();
+ return 1;
+}
+
+void ScrlBkgWnd::onSetVisible(int show)
+{
+ SCRLBKGWND_PARENT::onSetVisible(show);
+ if (show)
+ setSlidersPosition();
+}
+
+void ScrlBkgWnd::getClientRect(RECT *r)
+{
+ SCRLBKGWND_PARENT::getClientRect(r);
+ if (vScroll.isVisible(1))
+ r->right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
+ if (hScroll.isVisible(1))
+ r->bottom -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
+ r->top += getHeaderHeight();
+}
+
+/*void ScrlBkgWnd::getNonClientRect(RECT *r) {
+ SCRLBKGWND_PARENT::getClientRect(r); // my non client rect is my parent's client rect
+ return;
+}*/
+
+int ScrlBkgWnd::getHeaderHeight()
+{
+ return 0;
+}
+
+void ScrlBkgWnd::setLineHeight(int h)
+{
+ lineHeight = h;
+}
+
+int ScrlBkgWnd::getLinesPerPage()
+{
+ RECT r;
+ getClientRect(&r);
+ int h = r.bottom - r.top;
+ return h / lineHeight;
+}
+
+int ScrlBkgWnd::getScrollX()
+{
+ return scrollX;
+}
+
+int ScrlBkgWnd::getScrollY()
+{
+ return scrollY;
+}
+
+int ScrlBkgWnd::getScrollbarWidth()
+{
+ // TODO: maybe do if (hScroll.isVisible())
+ return hScroll.getWidth();
+ return vScroll.getWidth();
+ return 0;
+}
+
+/*void ScrlBkgWnd::clientToScreen(RECT *r) {
+ POINT p;
+ p.x = r->left;
+ p.y = r->top;
+ SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
+ r->left = p.x;
+ r->top = p.y;
+
+ p.x = r->right;
+ p.y = r->bottom;
+ SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
+ r->right = p.x;
+ r->bottom = p.y;
+}
+
+void ScrlBkgWnd::clientToScreen(int *x, int *y) {
+ SCRLBKGWND_PARENT::clientToScreen(x, y);
+}
+
+void ScrlBkgWnd::clientToScreen(POINT *p) {
+ TREEWND_PARENT::clientToScreen((int *)&p->x, (int *)&p->y);
+}*/
+
+void ScrlBkgWnd::makeWindowOverlayMask(api_region *r)
+{
+
+ return ;
+#ifdef WIN32
+ // With this routine empty, I'm just nuking the code from x-plat builds < KP
+ HDC dc = GetDC(getOsWindowHandle());
+
+ //if (getRandomRgn)
+ {
+ RECT cr;
+ getClientRect(&cr);
+ RECT wr;
+ getWindowRect(&wr);
+
+ RegionI sr;
+ Wasabi::Std::Wnd::getRandomRegion(dc, sr.getOSHandle());
+ sr.offset( -wr.left, -wr.top);
+
+ r->setRect(&cr);
+ r->subtractRegion(&sr);
+
+ }
+
+ ReleaseDC(getOsWindowHandle(), dc);
+#endif
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/scbkgwnd.h b/Src/Wasabi/api/wnd/wndclass/scbkgwnd.h
new file mode 100644
index 00000000..549e6f90
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/scbkgwnd.h
@@ -0,0 +1,463 @@
+#ifndef __SCRLBKGWND_H
+#define __SCRLBKGWND_H
+
+#include <tataki/canvas/canvas.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <api/wnd/wndclass/labelwnd.h>
+#include <api/wnd/wndclass/scrollbar.h>
+#include <api/wnd/wndclass/sepwnd.h>
+
+#define SCRLBKGWND_PARENT LabelWnd
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ScrlBkgWnd : public SCRLBKGWND_PARENT {
+protected:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ScrlBkgWnd();
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~ScrlBkgWnd();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onPaint(Canvas *c);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void drawBackground(Canvas *canvas);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onEraseBkgnd(HDC dc);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onResize();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void getClientRect(RECT *r);
+// virtual void getNonClientRect(RECT *r);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int getHeaderHeight();
+ virtual void timerCallback (int id);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onHScrollToggle(int set);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onVScrollToggle(int set);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onSetVisible(int show);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int wantHScroll() { return 1; }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int wantVScroll() { return 1; }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void makeWindowOverlayMask(api_region *r);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ SkinBitmap *getBgBitmap(void);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setBgBitmap(const wchar_t *b);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setBgColor(ARGB32 rgb);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ARGB32 getBgColor(void);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int getContentsWidth(); // not safe to call getclientrect!
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int getContentsHeight(); // not safe to call getclientrect!
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setLineHeight(int h);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getLinesPerPage();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getScrollX();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getScrollY();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getScrollbarWidth();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void scrollToY(int y, int signal=TRUE);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void scrollToX(int x, int signal=TRUE);
+
+protected:
+
+ virtual void onScrollY(int y) { }
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setSlidersPosition();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int needDoubleBuffer();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ bool needHScroll();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ bool needVScroll();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getMaxScrollY();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getMaxScrollX();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void updateScrollY(bool smooth=false);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void updateScrollX(bool smooth=false);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void smoothScrollToY(int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void smoothScrollToX(int x);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void updateVScroll(int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void updateHScroll(int x);
+
+ AutoSkinBitmap bmp;
+
+ int dbbuffer;
+ bool inDestroy;
+
+ ScrollBar hScroll;
+ ScrollBar vScroll;
+ SepWnd hSep;
+ SepWnd vSep;
+
+ ARGB32 bgColor;
+
+ int scrollX;
+ int scrollY;
+
+ bool needSetSliders;
+ bool wantsep;
+ bool wantTileBg;
+
+ int lineHeight;
+
+ float smoothScrollYInc, smoothScrollXInc;
+ float smoothScrollYCur, smoothScrollXCur;
+ int smoothScrollYTimerCount, smoothScrollXTimerCount;
+ int smoothYTimer, smoothXTimer;
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void killSmoothYTimer();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void killSmoothXTimer();
+ double lastratio;
+ RECT smsqr;
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void _setSlidersPosition();
+ int in_set_slider_position;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/scrollbar.cpp b/Src/Wasabi/api/wnd/wndclass/scrollbar.cpp
new file mode 100644
index 00000000..ce3e5b03
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/scrollbar.cpp
@@ -0,0 +1,679 @@
+#include <precomp.h>
+
+#include <bfc/wasabi_std.h>
+
+#include "scrollbar.h"
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/notifmsg.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define TIMER_ID 9871
+#define TIMER_ID2 9872
+
+#define FIRST_DELAY 350
+#define NEXT_DELAY 75
+
+ScrollBar::ScrollBar() {
+ leftrgn = NULL;
+ rightrgn = NULL;
+ buttonrgn = NULL;
+
+ position = 0;
+ moving = 0;
+ lefting = 0;
+ righting = 0;
+ clicked = 0;
+ height = DEFAULT_HEIGHT;
+ buttonx = 0;
+
+ shiftleft = 0;
+ shiftright = 0;
+
+ curmouseposition = POS_NONE;
+ clickmouseposition = POS_NONE;
+ pageing = 0;
+ timer = timer2 = 0;
+ npages = 100;
+ pageway = PAGE_NONE;
+ updown = 256;
+ insetpos = 0;
+ clickbuttonx = 0;
+ vertical = 0;
+ firstdelay = 0;
+ lastx = lasty = 0;
+}
+
+ScrollBar::~ScrollBar() {
+ deleteResources();
+}
+
+void ScrollBar::deleteResources() {
+ delete leftrgn; leftrgn = NULL;
+ delete buttonrgn; buttonrgn = NULL;
+ delete rightrgn; rightrgn = NULL;
+}
+
+// this one is inherited
+void ScrollBar::freeResources() {
+ SCROLLBAR_PARENT::freeResources();
+ deleteResources();
+}
+
+void ScrollBar::reloadResources() {
+ SCROLLBAR_PARENT::reloadResources();
+ loadBmps();
+}
+
+
+int ScrollBar::onMouseMove (int x, int y) {
+
+ SCROLLBAR_PARENT::onMouseMove(x, y);
+ lastx = x;
+ lasty = y;
+
+ if (clicked && clickmouseposition == POS_BUTTON) {
+
+ POINT pt={x,y};
+ int x;
+ if (!vertical)
+ x = pt.x - clickpos.x;
+ else
+ x = pt.y - clickpos.y;
+
+ RECT r;
+ getClientRect(&r);
+ int maxwidth;
+ if (!vertical)
+ maxwidth = (r.right-r.left)-(shiftright+shiftleft+bmpbutton.getWidth())+1;
+ else
+ maxwidth = (r.bottom-r.top)-(shiftright+shiftleft+bmpbutton.getHeight())+1;
+ buttonx = MIN(MAX(clickbuttonx + x, 0), maxwidth);
+ calcPosition();
+ invalidate();
+
+ } else {
+
+ int oldposition = curmouseposition;
+ curmouseposition = getMousePosition();
+ if (oldposition != curmouseposition) invalidate();
+
+ if (curmouseposition != POS_NONE && !getCapture())
+ beginCapture();
+
+ if (curmouseposition == POS_NONE && getCapture() && !clicked && !pageing)
+ endCapture();
+ }
+
+
+ return 1;
+}
+
+int ScrollBar::getWidth() {
+ if (!bmpbutton) return 0;
+ if (!vertical)
+ return bmpbutton.getHeight();
+ else
+ return bmpbutton.getWidth();
+ return 0;
+}
+
+int ScrollBar::getMousePosition() {
+ int v = POS_NONE;
+
+ POINT pt={lastx, lasty};
+
+ RECT c;
+ getClientRect(&c);
+ pt.x -= c.left;
+ pt.y -= c.top;
+
+ api_region *l, *b, *r;
+ l = leftrgn->clone();
+ b = buttonrgn->clone();
+ if (!vertical)
+ b->offset(buttonx+shiftleft, 0);
+ else
+ b->offset(0, buttonx+shiftleft);
+ r = rightrgn->clone();
+ if (!vertical)
+ r->offset(c.right-c.left-bmpleft.getWidth(), 0);
+ else
+ r->offset(0, c.bottom-c.top-bmpleft.getHeight());
+
+ if (b->ptInRegion(&pt))
+ v = POS_BUTTON;
+ if (l->ptInRegion(&pt))
+ v = POS_LEFT;
+ if (r->ptInRegion(&pt))
+ v = POS_RIGHT;
+
+ leftrgn->disposeClone(l);
+ buttonrgn->disposeClone(b);
+ rightrgn->disposeClone(r);
+
+ return v;
+}
+
+int ScrollBar::onLeftButtonDown(int x, int y) {
+ clickmouseposition = getMousePosition();
+ if (!pageing && clickmouseposition != POS_NONE) {
+ clicked = 1;
+ if (clickmouseposition == POS_LEFT || clickmouseposition == POS_RIGHT)
+ handleUpDown();
+ if (clickmouseposition) {
+ clickpos.x = lastx;
+ clickpos.y = lasty;
+ clickbuttonx = buttonx;
+ }
+ } else {
+ clicked = 0;
+ pageing = 1;
+ handlePageUpDown();
+ }
+ invalidate();
+ return 1;
+}
+
+void ScrollBar::handleUpDown() {
+ setTimer(TIMER_ID2, FIRST_DELAY);
+ timer2 = 1;
+ firstdelay = 1;
+
+ checkUpDown();
+}
+
+int ScrollBar::checkUpDown() {
+ if (!clicked) {
+ if (timer2) {
+ killTimer(TIMER_ID2);
+ timer2 = 0;
+ return 1;
+ }
+ }
+
+ if (getMousePosition() == clickmouseposition)
+ upDown(clickmouseposition);
+
+ return 1;
+
+}
+
+void ScrollBar::handlePageUpDown() {
+
+ setTimer(TIMER_ID, FIRST_DELAY);
+ timer = 1;
+ firstdelay = 1;
+
+ checkPageUpDown();
+}
+
+int ScrollBar::checkPageUpDown() {
+
+ if (!pageing) {
+ if (timer) {
+ killTimer(TIMER_ID);
+ timer = 0;
+ pageway = PAGE_NONE;
+ return 1;
+ }
+ }
+
+ POINT pt={lastx,lasty};
+ RECT c;
+ getClientRect(&c);
+ pt.x -= c.left;
+ pt.y -= c.top;
+
+ if (!vertical) {
+ int middlebutton = shiftleft + buttonx + bmpbutton.getWidth()/2;
+ api_region *r = buttonrgn->clone();
+ r->offset(buttonx+shiftleft, 0);
+ if (pt.x > middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_DOWN)
+ pageUp();
+ if (pt.x < middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_UP)
+ pageDown();
+ buttonrgn->disposeClone(r);
+ } else {
+ int middlebutton = shiftleft + buttonx + bmpbutton.getHeight()/2;
+ api_region *r = buttonrgn->clone();
+ r->offset(0, buttonx+shiftleft);
+ if (pt.y > middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_DOWN)
+ pageUp();
+ if (pt.y < middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_UP)
+ pageDown();
+ buttonrgn->disposeClone(r);
+ }
+ return 1;
+
+}
+
+int ScrollBar::onLeftButtonUp(int x, int y) {
+ clicked = 0;
+ clickmouseposition = POS_NONE;
+ curmouseposition = POS_NONE;
+ onMouseMove(x,y);
+ if (pageing) {
+ pageing = 0;
+ checkPageUpDown();
+ }
+ onSetFinalPosition();
+ invalidate();
+ return 1;
+}
+
+int ScrollBar::onRightButtonDown(int x, int y) {
+ return 1;
+}
+
+int ScrollBar::onRightButtonUp(int x, int y) {
+ return 1;
+}
+
+int ScrollBar::onMouseWheelUp(int clicked, int lines) {
+ return 1;
+}
+
+int ScrollBar::onMouseWheelDown(int clicked, int lines) {
+ return 1;
+}
+
+int ScrollBar::onPaint(Canvas *canvas) {
+ AutoSkinBitmap &thisleft = curmouseposition == POS_LEFT ? (clicked ? bmplpressed : bmplhilite) : bmpleft;
+ AutoSkinBitmap &thisbutton = curmouseposition == POS_BUTTON ? (clicked ? bmpbpressed : bmpbhilite) : bmpbutton;
+ AutoSkinBitmap &thisright = curmouseposition == POS_RIGHT ? (clicked ? bmprpressed : bmprhilite) : bmpright;
+
+ if (curmouseposition != clickmouseposition && clicked) {
+ thisleft = bmpleft;
+ thisbutton = bmpbutton;
+ thisright = bmpright;
+ }
+
+ RECT r;
+ PaintBltCanvas paintcanvas;
+
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ SCROLLBAR_PARENT::onPaint(canvas);
+
+ getClientRect(&r);
+
+ renderBaseTexture(canvas, r);
+
+ if (!vertical) {
+ RECT c;
+
+ c.left = r.left;
+ c.right = r.left;
+ c.top = r.top;
+ c.bottom = r.bottom;
+ if (bmpbackgroundleft.getBitmap()) {
+ c.right = c.left + bmpbackgroundleft.getWidth();
+ bmpbackgroundleft.getBitmap()->stretchToRectAlpha(canvas, &c);
+ }
+ int l = c.right;
+ c.left = r.right;
+ c.right = r.right;
+ if (bmpbackgroundright.getBitmap()) {
+ c.left = r.right - bmpbackgroundright.getWidth();
+ bmpbackgroundright.getBitmap()->stretchToRectAlpha(canvas, &c);
+ }
+ c.right = c.left;
+ c.left = l;
+ if (bmpbackgroundmiddle.getBitmap()) {
+ bmpbackgroundmiddle.getBitmap()->stretchToRectAlpha(canvas, &c);
+ }
+
+ c.left = r.left + buttonx+shiftleft;
+ c.top = r.top + 0;
+ c.right = r.left + buttonx+thisbutton.getWidth()+shiftleft;
+ c.bottom = r.top + getWidth();
+
+ thisbutton.stretchToRectAlpha(canvas, &c);
+
+ c.left = r.left;
+ c.top = r.top;
+ c.right = r.left + thisleft.getWidth();
+ c.bottom = r.top + getWidth();
+
+ thisleft.stretchToRectAlpha(canvas, &c);
+
+ c.left = r.right-thisright.getWidth();
+ c.top = r.top;
+ c.right = r.right;
+ c.bottom = r.top+getWidth();
+
+ thisright.stretchToRectAlpha(canvas, &c);
+ } else {
+ RECT c;
+
+ c.top = r.top;
+ c.bottom = r.top;
+ c.left = r.left;
+ c.right = r.right;
+ if (bmpbackgroundleft.getBitmap()) {
+ c.bottom = c.top + bmpbackgroundleft.getHeight();
+ bmpbackgroundleft.getBitmap()->stretchToRectAlpha(canvas, &c);
+ }
+ int l = c.bottom;
+ c.top = r.bottom;
+ c.bottom = r.bottom;
+ if (bmpbackgroundright.getBitmap()) {
+ c.top = r.bottom - bmpbackgroundright.getHeight();
+ bmpbackgroundright.getBitmap()->stretchToRectAlpha(canvas, &c);
+ }
+ c.bottom = c.top;
+ c.top = l;
+ if (bmpbackgroundmiddle.getBitmap()) {
+ bmpbackgroundmiddle.getBitmap()->stretchToRectAlpha(canvas, &c);
+ }
+
+ c.left = r.right - thisleft.getWidth();
+ c.top = r.top+buttonx + shiftleft;
+ c.right = r.right;
+ c.bottom = r.top+buttonx+thisbutton.getHeight() + shiftleft;
+
+ thisbutton.stretchToRectAlpha(canvas, &c);
+
+ c.left = r.right - thisleft.getWidth();
+ c.top = r.top;
+ c.right = r.right;
+ c.bottom = r.top+thisleft.getHeight();
+
+ thisleft.stretchToRectAlpha(canvas, &c);
+
+ c.left = r.right-thisright.getWidth();
+ c.top = r.bottom-thisright.getHeight();
+ c.right = r.right;
+ c.bottom = r.bottom;
+
+ thisright.stretchToRectAlpha(canvas, &c);
+ }
+
+ return 1;
+}
+
+int ScrollBar::getHeight() {
+ return height;
+}
+
+void ScrollBar::setHeight(int newheight) {
+ height = newheight;
+}
+
+int ScrollBar::onResize() {
+ calcXPosition();
+ invalidate();
+ return 1;
+}
+
+int ScrollBar::onInit() {
+ SCROLLBAR_PARENT::onInit();
+ return 1;
+}
+
+void ScrollBar::setBitmaps(wchar_t *left, wchar_t *lpressed, wchar_t *lhilite,
+ wchar_t *right, wchar_t *rpressed, wchar_t *rhilite,
+ wchar_t *button, wchar_t *bpressed, wchar_t *bhilite) {
+
+ deleteResources();
+
+ bmpleft = left;
+ bmplpressed = lpressed;
+ bmplhilite = lhilite;
+ bmpright = right;
+ bmprpressed = rpressed;
+ bmprhilite = rhilite;
+ bmpbutton = button;
+ bmpbpressed = bpressed;
+ bmpbhilite = bhilite;
+
+ loadBmps();
+}
+
+void ScrollBar::setBackgroundBitmaps(const wchar_t *left, const wchar_t *middle, const wchar_t *right) {
+ bmpbackgroundleft = left;
+ bmpbackgroundmiddle = middle;
+ bmpbackgroundright = right;
+}
+
+void ScrollBar::loadBmps() {
+
+ if (bmpleft.getBitmap()) leftrgn = new RegionI(bmpleft);
+ if (bmpbutton.getBitmap()) buttonrgn = new RegionI(bmpbutton);
+ if (bmpright.getBitmap()) rightrgn = new RegionI(bmpright);
+
+ calcOverlapping();
+ calcXPosition();
+}
+
+void ScrollBar::setPosition(int pos) {
+ setPrivatePosition(pos, FALSE);
+}
+
+void ScrollBar::setPrivatePosition(int pos, bool signal, bool smooth) {
+ if (insetpos) return; // helps stupid people (like me)
+ insetpos = 1;
+ position = MIN(SCROLLBAR_FULL, pos);
+ position = MAX(0, position);
+ calcXPosition();
+ if (signal) onSetPosition(smooth);
+ if (isInited() && isVisible())
+ invalidate();
+ insetpos = 0;
+}
+
+int ScrollBar::getPosition() {
+ return position;
+}
+
+int ScrollBar::onSetPosition(bool smooth) {
+ notifyParent(ChildNotify::SCROLLBAR_SETPOSITION, smooth);
+ return 1;
+}
+
+int ScrollBar::onSetFinalPosition() {
+ notifyParent(ChildNotify::SCROLLBAR_SETFINALPOSITION);
+ return 1;
+}
+
+void ScrollBar::calcOverlapping() {
+
+ if (!vertical) {
+
+ shiftleft = bmpleft.getWidth();
+ if (leftrgn && buttonrgn) {
+ int i;
+ for (i=shiftleft;i>=0;i--) {
+ api_region *reg = buttonrgn->clone();
+ reg->offset(i, 0);
+ if (leftrgn->doesIntersectRgn(reg)) {
+ i++;
+ buttonrgn->disposeClone(reg);
+ break;
+ }
+ buttonrgn->disposeClone(reg);
+ }
+ if (i >= 0)
+ shiftleft = i;
+ }
+
+ shiftright = bmpright.getWidth();
+ if (rightrgn && buttonrgn) {
+ int i;
+ for (i=0;i>=-shiftright;i--) {
+ api_region *reg = rightrgn->clone();
+ reg->offset(i+bmpbutton.getWidth(), 0);
+ if (reg->doesIntersectRgn(buttonrgn)) {
+ i++;
+ rightrgn->disposeClone(reg);
+ break;
+ }
+ rightrgn->disposeClone(reg);
+ }
+ if (i >= -shiftright)
+ shiftright += i;
+ }
+
+ } else {
+
+ shiftleft = bmpleft.getHeight();
+ if (leftrgn && buttonrgn) {
+ int i;
+ for (i=shiftleft;i>=0;i--) {
+ api_region *reg = buttonrgn->clone();
+ reg->offset(0, i);
+ if (leftrgn->doesIntersectRgn(reg)) {
+ i++;
+ buttonrgn->disposeClone(reg);
+ break;
+ }
+ buttonrgn->disposeClone(reg);
+ }
+ if (i >= 0)
+ shiftleft = i;
+ }
+
+ shiftright = bmpright.getHeight();
+ if (rightrgn && buttonrgn) {
+ int i;
+ for (i=0;i>=-shiftright;i--) {
+ api_region *reg = rightrgn->clone();
+ reg->offset(0, i+bmpbutton.getHeight());
+ if (reg->doesIntersectRgn(buttonrgn)) {
+ i++;
+ rightrgn->disposeClone(reg);
+ break;
+ }
+ rightrgn->disposeClone(reg);
+ }
+ if (i >= -shiftright)
+ shiftright += i;
+ }
+
+ }
+
+}
+
+void ScrollBar::calcXPosition() {
+
+ if (!isInited()) return;
+
+ RECT r;
+ getClientRect(&r);
+
+ int maxwidth;
+
+ if (!vertical)
+ maxwidth = (r.right-r.left)-(bmpbutton.getWidth()+shiftleft+shiftright)+1;
+ else
+ maxwidth = (r.bottom-r.top)-(bmpbutton.getHeight()+shiftleft+shiftright)+1;
+ int oldx = buttonx;
+ buttonx = (int)(((float)getPosition() / SCROLLBAR_FULL) * maxwidth);
+ if (buttonx != oldx)
+ invalidate();
+}
+
+void ScrollBar::calcPosition() {
+
+ if (!isInited()) return;
+
+ RECT r;
+ getClientRect(&r);
+
+ int maxwidth;
+
+ if (!vertical)
+ maxwidth = r.right-r.left-(bmpbutton.getWidth()+shiftleft+shiftright)+1;
+ else
+ maxwidth = r.bottom-r.top-(bmpbutton.getHeight()+shiftleft+shiftright)+1;
+ setPrivatePosition((int)((float)buttonx / maxwidth * SCROLLBAR_FULL));
+ //invalidate();
+}
+
+void ScrollBar::timerCallback(int id) {
+ switch (id) {
+ case TIMER_ID:
+ if (firstdelay) {
+ killTimer(TIMER_ID);
+ setTimer(TIMER_ID, NEXT_DELAY);
+ timer = 1;
+ firstdelay = 0;
+ }
+ checkPageUpDown();
+ break;
+ case TIMER_ID2:
+ if (firstdelay) {
+ killTimer(TIMER_ID2);
+ setTimer(TIMER_ID2, NEXT_DELAY);
+ timer2 = 1;
+ firstdelay = 0;
+ }
+ checkUpDown();
+ break;
+ default:
+ SCROLLBAR_PARENT::timerCallback(id);
+ }
+}
+
+// FG> smooth scrolling forced on, sorry, microsoft does it too so the user perceives IE scrolling as faster than it actually is
+// eventho they tell you "The smooth-scrolling effect for list boxes should be disabled when this setting is FALSE. Your application must do this if it creates customized list boxes", they
+// break their own rule so people don't bitch too much. ergo there is no reason we should not do that too.
+
+int ScrollBar::pageUp() {
+
+ pageway = PAGE_UP;
+
+ setPrivatePosition((int)MAX(0.f, (float)getPosition() + (float)SCROLLBAR_FULL / (npages-1)), TRUE, 1/*Std::osparam_getSmoothScroll()*/);
+
+ return 1;
+};
+
+int ScrollBar::pageDown() {
+
+ pageway = PAGE_DOWN;
+
+ setPrivatePosition((int)MIN((float)SCROLLBAR_FULL, (float)getPosition() - (float)SCROLLBAR_FULL / (npages-1)), TRUE, 1/*Std::osparam_getSmoothScroll()*/);
+
+ return 1;
+};
+
+void ScrollBar::setNPages(int n) {
+ //ASSERT(n >= 2);
+ if (n < 2) n = 2;
+ npages = n;
+}
+
+void ScrollBar::gotoPage(int page) {
+
+ page = MIN(page, npages-1);
+ page = MAX(page, 0);
+
+ setPrivatePosition((int)((float)SCROLLBAR_FULL / (npages-1) * page), TRUE, FALSE);
+
+}
+
+void ScrollBar::setUpDownValue(int newupdown) {
+ updown = newupdown;
+}
+
+int ScrollBar::upDown(int which) {
+ switch (which) {
+ case POS_LEFT:
+ setPrivatePosition(getPosition()-updown);
+ break;
+ case POS_RIGHT:
+ setPrivatePosition(getPosition()+updown);
+ break;
+ }
+ return 1;
+}
+
+void ScrollBar::setVertical(bool isvertical) {
+ vertical = isvertical;
+ calcOverlapping();
+ if (isInited())
+ invalidate();
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/scrollbar.h b/Src/Wasabi/api/wnd/wndclass/scrollbar.h
new file mode 100644
index 00000000..98be5400
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/scrollbar.h
@@ -0,0 +1,423 @@
+#ifndef __SCROLLBAR_H
+#define __SCROLLBAR_H
+
+#include <api/wnd/virtualwnd.h>
+#include <tataki/region/region.h>
+#include <api/wnd/usermsg.h>
+#include <tataki/bitmap/autobitmap.h>
+
+#define SCROLLBAR_FULL 65535
+
+#define POS_NONE 0
+#define POS_LEFT 1
+#define POS_BUTTON 2
+#define POS_RIGHT 3
+
+#define PAGE_NONE 0
+#define PAGE_DOWN 1
+#define PAGE_UP 2
+
+#define DEFAULT_HEIGHT 16
+
+#define SCROLLBAR_PARENT VirtualWnd
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ScrollBar : public SCROLLBAR_PARENT {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ ScrollBar();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~ScrollBar();
+
+ virtual int onMouseMove (int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onLeftButtonDown(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onLeftButtonUp(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onRightButtonDown(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onRightButtonUp(int x, int y);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onMouseWheelUp(int clicked, int lines);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onMouseWheelDown(int clicked, int lines);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onResize();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void timerCallback(int id);
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int wantDoubleClicks() { return 0; };
+
+
+ virtual int onSetPosition(bool smooth=false);
+
+ virtual int onSetFinalPosition();
+
+ void setBitmaps(wchar_t *left, wchar_t *lpressed, wchar_t *lhilite,
+ wchar_t *right, wchar_t *rpressed, wchar_t *rhilite,
+ wchar_t *button, wchar_t *bpressed, wchar_t *bhilite);
+
+ void setBackgroundBitmaps(const wchar_t *left, const wchar_t *middle, const wchar_t *right);
+
+ void setPosition(int pos);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getPosition();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getHeight();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setHeight(int newheight);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setNPages(int n);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void gotoPage(int n);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setUpDownValue(int newupdown);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setVertical(bool isvertical);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getWidth();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void freeResources();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void reloadResources();
+
+private:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void deleteResources();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int getMousePosition();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void calcOverlapping();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void calcXPosition();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void calcPosition();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void handlePageUpDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int checkPageUpDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void handleUpDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int checkUpDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int pageUp();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int pageDown();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ int upDown(int which);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void setPrivatePosition(int pos, bool signal=true, bool smooth=false);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void loadBmps();
+
+ AutoSkinBitmap bmpleft, bmplpressed, bmplhilite,
+ bmpright, bmprpressed, bmprhilite,
+ bmpbutton, bmpbpressed, bmpbhilite,
+ bmpbackgroundleft, bmpbackgroundmiddle, bmpbackgroundright;
+
+ RegionI *leftrgn, *rightrgn, *buttonrgn;
+ int position;
+
+ int moving;
+ int lefting;
+ int righting;
+ int clicked;
+
+ int buttonx;
+
+ int curmouseposition;
+ int clickmouseposition;
+ int height;
+
+ int shiftleft, shiftright;
+ POINT clickpos;
+ int clickbuttonx;
+ int pageing;
+ int firstdelay;
+ int timer;
+ int npages;
+ int pageway;
+ int updown;
+ int timer2;
+ int insetpos;
+
+ int vertical;
+ int lastx, lasty;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/sepwnd.cpp b/Src/Wasabi/api/wnd/wndclass/sepwnd.cpp
new file mode 100644
index 00000000..da45b11b
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/sepwnd.cpp
@@ -0,0 +1,63 @@
+#include <precomp.h>
+
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/basewnd.h>
+#include "sepwnd.h"
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/PaintCanvas.h>
+
+SepWnd::SepWnd() {
+ bitmap = NULL;
+ orientation = SEP_UNKNOWN;
+}
+
+SepWnd::~SepWnd() {
+ if (bitmap) delete bitmap;
+}
+
+int SepWnd::onPaint(Canvas *canvas) {
+
+ PaintBltCanvas paintcanvas;
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaintNC(this)) return 0;
+ canvas = &paintcanvas;
+ }
+
+
+ if (!bitmap) {
+ switch (orientation) {
+ case SEP_VERTICAL:
+ bitmap = new SkinBitmap(L"studio.FrameVerticalDivider");
+ break;
+ case SEP_HORIZONTAL:
+ bitmap = new SkinBitmap(L"studio.FrameHorizontalDivider");
+ break;
+ case SEP_UNKNOWN:
+ return 1;
+ }
+ ASSERT(bitmap != NULL);
+ }
+ RECT r;
+ getClientRect(&r);
+ RenderBaseTexture(canvas, r);
+ if (bitmap) {
+ bitmap->stretchToRectAlpha(canvas, &r, 128);
+ }
+ return 1;
+}
+
+int SepWnd::setOrientation(int which) {
+ orientation = which;
+ return 1;
+}
+
+int SepWnd::onInit() {
+ SEPWND_PARENT::onInit();
+ return 1;
+}
+
+void SepWnd::freeResources() {
+ SEPWND_PARENT::freeResources();
+ if (bitmap) delete bitmap;
+ bitmap = NULL;
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/sepwnd.h b/Src/Wasabi/api/wnd/wndclass/sepwnd.h
new file mode 100644
index 00000000..60f55b72
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/sepwnd.h
@@ -0,0 +1,27 @@
+#ifndef __SEPWND_H
+#define __SEPWND_H
+
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/virtualwnd.h>
+
+#define SEP_UNKNOWN -1
+#define SEP_VERTICAL 0
+#define SEP_HORIZONTAL 1
+
+#define SEPWND_PARENT VirtualWnd
+
+class SepWnd : public VirtualWnd {
+public:
+ SepWnd();
+ ~SepWnd();
+ virtual int onPaint(Canvas *c);
+ virtual int setOrientation(int which);
+ virtual int onInit();
+ virtual void freeResources();
+private:
+ SkinBitmap *bitmap;
+ int orientation;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/slider.cpp b/Src/Wasabi/api/wnd/wndclass/slider.cpp
new file mode 100644
index 00000000..51157d7f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/slider.cpp
@@ -0,0 +1,705 @@
+#include <precomp.h>
+#include "slider.h"
+
+#include <tataki/canvas/canvas.h>
+#include <api/wnd/notifmsg.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define DEFAULT_THUMBWIDTH 16
+#define DEFAULT_THUMBHEIGHT 16
+
+SliderWnd::SliderWnd()
+{
+ seeking = 0;
+ enabled = 1;
+ hilite = 0;
+ pos = 0;
+ oldpos = -1;
+ thumbwidth = DEFAULT_THUMBWIDTH;
+ captured = 0;
+ xShift = 0;
+ yShift = 0;
+
+ base_texture = NULL;
+ use_base_texture = 0;
+ no_default_background = 0;
+
+ drawOnBorders = 0;
+ hotPosition = -1;
+ origPos = 0;
+
+ vertical = 0;
+
+ thumbCentered = 1;
+ thumbOffset = 0;
+ thumbStretched = 0;
+ hotposrange = -1;
+ setLimits(START, END);
+}
+
+SliderWnd::~SliderWnd()
+{}
+
+
+int SliderWnd::onPaint(Canvas *canvas)
+{
+ if (canvas == NULL)
+ {
+ PaintBltCanvas paintcanvas;
+ if (!paintcanvas.beginPaint(this))
+ return 0;
+ SliderWnd::onPaint(&paintcanvas);
+ }
+
+ SLIDERWND_PARENT::onPaint(canvas);
+
+ RECT r, origr;
+ getClientRect(&r);
+ origr = r;
+
+ if (use_base_texture)
+ {
+ if (!base_texture)
+ {
+ renderBaseTexture(canvas, r);
+ }
+ else
+ {
+ RECT cr;
+ cr.left = xShift;
+ cr.top = yShift;
+ cr.right = cr.left + (r.right - r.left);
+ cr.bottom = cr.top + (r.bottom - r.top);
+ base_texture->blitToRect(canvas, &cr, &r);
+ }
+ }
+
+ if (vertical)
+ {
+ RECT br;
+ br.left = r.left;
+ br.right = r.right;
+
+ if (left.getBitmap())
+ {
+ br.top = r.top;
+ br.bottom = left.getHeight();
+ left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
+ }
+
+ if (right.getBitmap())
+ {
+ br.top = r.bottom - right.getHeight();
+ br.bottom = r.bottom;
+ right.stretchToRectAlpha(canvas, &br, getPaintingAlpha());
+ }
+
+ if (middle.getBitmap())
+ {
+ br.top = r.top + (left.getBitmap() ? left.getHeight() : 0);
+ br.bottom = r.bottom - (right.getBitmap() ? right.getHeight() : 0);
+ middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
+ }
+ }
+ else
+ {
+ RECT br;
+ br.top = r.top;
+ br.bottom = r.bottom;
+
+ if (left.getBitmap())
+ {
+ br.left = r.left;
+ br.right = br.left + left.getWidth();
+ left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
+ }
+
+ if (right.getBitmap())
+ {
+ br.left = r.right - right.getWidth();
+ br.right = r.right;
+ right.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
+ }
+
+ if (middle.getBitmap())
+ {
+ br.left = r.left + (left.getBitmap() ? left.getWidth() : 0);
+ br.right = r.right - (right.getBitmap() ? right.getWidth() : 0);
+ middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
+ }
+ }
+
+ if (vertical)
+ {
+ int w = (r.bottom - r.top) - thumbHeight();
+ // ASSERT(w > 0); // if the control paints off the edge of the screen, this will needlessly assert.
+ if (w < 0) w = 0;
+ r.top += (pos * w) / length;
+ r.bottom = r.top + thumbHeight();
+ if (!thumbStretched)
+ {
+ if (!thumbCentered)
+ {
+ r.left = origr.left + thumbOffset;
+ r.right = origr.left + thumbWidth() + thumbOffset;
+ }
+ else
+ {
+ int w = ((r.right - r.left) - thumbWidth()) / 2;
+ r.left = origr.left + w + thumbOffset;
+ r.right = origr.right - w + thumbOffset;
+ }
+ }
+ else
+ {
+ r.left = origr.left;
+ r.right = origr.right;
+ }
+
+ }
+ else
+ {
+ // offset for left bitmap
+ if (!drawOnBorders)
+ {
+ if (left.getBitmap() != NULL) r.left += left.getWidth();
+ if (right.getBitmap() != NULL) r.right -= right.getWidth();
+ }
+
+ int w = (r.right - r.left) - thumbWidth();
+ if (w < 0) w = 0;
+ r.left += (pos * w) / length;
+ r.right = r.left + thumbWidth();
+ if (r.right > origr.right)
+ {
+ r.left -= r.right - origr.right;
+ r.right = origr.right;
+ }
+
+ if (!thumbStretched)
+ {
+ int thumbh = thumb.getBitmap() ? thumb.getHeight() : DEFAULT_THUMBWIDTH;
+ if (thumbCentered)
+ {
+ int h = ((r.bottom - r.top) - thumbh) / 2;
+ r.top = origr.top + h;
+ r.bottom = origr.bottom - h;
+ }
+ else
+ {
+ r.top = origr.top + thumbOffset;
+ r.bottom = origr.top + thumbh + thumbOffset;
+ }
+ }
+ else
+ {
+ r.top = origr.top;
+ r.bottom = origr.bottom;
+ }
+ }
+
+ SkinBitmap *sb = getSeekStatus() ? (thumbdown.getBitmap() ? thumbdown.getBitmap() : thumb.getBitmap()) : ((hilite && thumbhilite.getBitmap()) ? thumbhilite.getBitmap() : thumb.getBitmap());
+
+ if (sb != NULL)
+ sb->stretchToRectAlpha(canvas, &r, getPaintingAlpha());
+ else
+ canvas->fillRect(&r, RGB(255, 0, 0));
+
+ return 1;
+}
+
+int SliderWnd::onInit()
+{
+ SLIDERWND_PARENT::onInit();
+ if (!no_default_background)
+ {
+ if (vertical)
+ {
+ // Please note that these bitmaps here do not yet exist.
+ if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.vertical.top");
+ if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.vertical.middle");
+ if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.vertical.bottom");
+ if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.vertical.button");
+ if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.vertical.button.pressed");
+ }
+ else
+ {
+ if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.horizontal.left");
+ if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.horizontal.middle");
+ if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.horizontal.right");
+ if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.horizontal.button");
+ if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.horizontal.button.pressed");
+ }
+ }
+
+
+ return 1;
+}
+
+int SliderWnd::onLeftButtonDown(int x, int y)
+{
+ SLIDERWND_PARENT::onLeftButtonDown(x, y);
+ if (!enabled) return 0;
+ seeking = 1;
+
+ origPos = 0;
+ RECT r;
+ getClientRect(&r);
+ if (vertical)
+ {
+ int w = (r.bottom - r.top) - thumbHeight();
+ if (w < 0) w = 0;
+ r.top += (pos * w) / length;
+ origPos = (y - r.top) - 1;
+ /*if(origPos<0 || origPos>thumbHeight())*/ origPos = (thumbHeight() / 2) - 2;
+ }
+ else
+ {
+ if (!drawOnBorders)
+ {
+ if (left.getBitmap() != NULL) r.left += left.getWidth();
+ if (right.getBitmap() != NULL) r.right -= right.getWidth();
+ }
+ int w = (r.right - r.left) - thumbWidth();
+ if (w < 0) w = 0;
+ r.left += (pos * w) / length;
+ origPos = (x - r.left) - 1;
+ if (origPos < 0 || origPos > thumbWidth()) origPos = (thumbWidth() / 2) - 2;
+ }
+
+ if (!captured)
+ {
+ captured = 1;
+ beginCapture();
+ }
+ oldpos = pos;
+ onMouseMove(x, y);
+ return 1;
+}
+
+//FG>
+//removed cross-hierarchy deletion (crashs due to ancestor in common.dll trying to delete pointers in a different
+//heap scope than the one in which they were allocated)
+void SliderWnd::setBitmaps(const wchar_t *thumbbmp, const wchar_t *thumbdownbmp, const wchar_t *thumbhighbmp, const wchar_t *leftbmp, const wchar_t *middlebmp, const wchar_t *rightbmp)
+{
+ setThumbBmp(thumbbmp);
+ setThumbDownBmp(thumbdownbmp);
+ setThumbHiliteBmp(thumbhighbmp);
+ setLeftBmp(leftbmp);
+ setRightBmp(rightbmp);
+ setMiddleBmp(middlebmp);
+}
+
+void SliderWnd::setLeftBmp(const wchar_t *name)
+{
+ left = name;
+ invalidate();
+}
+
+void SliderWnd::setMiddleBmp(const wchar_t *name)
+{
+ middle = name;
+ invalidate();
+}
+
+void SliderWnd::setRightBmp(const wchar_t *name)
+{
+ right = name;
+ invalidate();
+}
+
+void SliderWnd::setThumbBmp(const wchar_t *name)
+{
+ thumb = name;
+ invalidate();
+}
+
+void SliderWnd::setThumbDownBmp(const wchar_t *name)
+{
+ thumbdown = name;
+ invalidate();
+}
+
+void SliderWnd::setThumbHiliteBmp(const wchar_t *name)
+{
+ thumbhilite = name;
+ invalidate();
+}
+
+SkinBitmap *SliderWnd::getLeftBitmap()
+{
+ return left;
+}
+
+SkinBitmap *SliderWnd::getRightBitmap()
+{
+ return right;
+}
+
+SkinBitmap *SliderWnd::getMiddleBitmap()
+{
+ return middle;
+}
+
+SkinBitmap *SliderWnd::getThumbBitmap()
+{
+ return thumb;
+}
+
+SkinBitmap *SliderWnd::getThumbDownBitmap()
+{
+ return thumbdown;
+}
+
+SkinBitmap *SliderWnd::getThumbHiliteBitmap()
+{
+ return thumbhilite;
+}
+
+int SliderWnd::getWidth()
+{
+ if (vertical)
+ return (getThumbBitmap() ? getThumbBitmap()->getWidth() : 0);
+ else
+ {
+ return 64;
+ }
+}
+
+int SliderWnd::getHeight()
+{
+ if (!vertical)
+ return (getThumbBitmap() ? getThumbBitmap()->getHeight() : 0);
+ else
+ {
+ return 64;
+ }
+}
+
+void SliderWnd::setEnable(int en)
+{
+ if (enabled != en) invalidate();
+ enabled = en;
+}
+
+int SliderWnd::getEnable(void)
+{
+ return enabled;
+}
+
+void SliderWnd::setPosition(int newpos, int wantcb)
+{
+ if (newpos < minlimit) newpos = minlimit;
+ else if (newpos > maxlimit) newpos = maxlimit;
+
+ if (vertical) pos = maxlimit - newpos;
+ else /* horizontal */ pos = newpos - minlimit;
+
+ if (wantcb)
+ onSetPosition();
+
+ invalidate();
+}
+
+int SliderWnd::onMouseMove(int x, int y)
+{
+ int p, w, mouseover;
+
+ SLIDERWND_PARENT::onMouseMove(x, y);
+
+ POINT po = {x, y};
+ clientToScreen(&po);
+ mouseover = (WASABI_API_WND->rootWndFromPoint(&po) == this);
+ if (mouseover && !seeking && !captured)
+ {
+ beginCapture();
+ captured = 1;
+ onEnterArea();
+ }
+ int lasthilite = hilite;
+ hilite = enabled && mouseover;
+ if (hilite != lasthilite)
+ {
+ if (!mouseover && !seeking && captured)
+ {
+ endCapture();
+ captured = 0;
+ onLeaveArea();
+ invalidate();
+ return 0;
+ }
+ invalidate();
+ }
+
+ if (!enabled) return 1;
+
+ RECT r, origr;
+ getClientRect(&r);
+ x -= r.left;
+ y -= r.top;
+
+ origr = r;
+ if (vertical)
+ {
+ w = (r.bottom - r.top) - thumbHeight();
+ // p = (y - (r.top-origr.top)) - (thumbHeight()/2-2);
+ p = (y - (r.top - origr.top)) - origPos;
+ }
+ else
+ {
+ if (!drawOnBorders)
+ {
+ if (left != NULL) r.left += left.getWidth();
+ if (right != NULL) r.right -= right.getWidth();
+ }
+ w = (r.right - r.left) - thumbWidth();
+ // p = (x - (r.left - origr.left)) - (thumbWidth()/2-2);
+ p = (x - (r.left - origr.left)) - origPos;
+ }
+
+ if (seeking)
+ {
+ pos = (p * length) / w;
+ if (pos < 0) pos = 0;
+ else if (pos > length) pos = length;
+
+ if (hotPosition != -1)
+ {
+ int a, c;
+ if (vertical) a = r.bottom - r.top;
+ else a = r.right - r.left;
+ c = getHotPosRange();
+ if (c == -1)
+ {
+ int b = (int)(a * 0.075);
+ c = (b * length) / a;
+ }
+
+ /**
+ EQBand: minlimit -127, maxlimit 127, hotpos 0
+ PanBar: minlimit 0, maxlimit 225, hotpos 127
+
+ VSliders pos starts from top by 0 (winamp behaviour reversed!)
+ */
+
+ if (vertical)
+ {
+ //if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition;
+ if ((maxlimit - pos) > (hotPosition - c) && (maxlimit - pos) < (hotPosition + c)) pos = hotPosition - minlimit; // Hehe, now it works ;)
+ }
+ else
+ {
+ if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition;
+ //if ((pos - maxlimit)> (hotPosition - c) && (pos - maxlimit) < (hotPosition + c)) pos = hotPosition - minlimit;
+ }
+ }
+
+ onSetPosition();
+ invalidate();
+ }
+
+ return 1;
+}
+
+void SliderWnd::onCancelCapture()
+{
+ SLIDERWND_PARENT::onCancelCapture();
+ if (seeking && captured)
+ abort();
+}
+
+int SliderWnd::onLeftButtonUp(int x, int y)
+{
+ SLIDERWND_PARENT::onLeftButtonUp(x, y);
+ int wasseeking = seeking;
+ seeking = 0;
+ captured = 0;
+ oldpos = -1;
+ endCapture();
+ if (wasseeking)
+ onSetFinalPosition();
+ invalidate();
+ return 1;
+}
+
+int SliderWnd::onRightButtonDown(int x, int y)
+{
+ SLIDERWND_PARENT::onRightButtonDown(x, y);
+ if (seeking && captured)
+ {
+ abort();
+ }
+ return 1;
+}
+
+int SliderWnd::onChar(unsigned int c)
+{
+ SLIDERWND_PARENT::onChar(c);
+ if (seeking && captured && (c == 27))
+ {
+ abort();
+ }
+ return 1;
+}
+
+int SliderWnd::onSetPosition()
+{
+ if (!isInited()) return 0;
+ notifyParent(ChildNotify::SLIDER_INTERIM_POSITION, getSliderPosition());
+ return 0;
+}
+
+int SliderWnd::onSetFinalPosition()
+{
+ if (!isInited()) return 0;
+ notifyParent(ChildNotify::SLIDER_FINAL_POSITION, getSliderPosition());
+ return 0;
+}
+
+int SliderWnd::getSliderPosition()
+{
+ if (vertical) return maxlimit -pos;
+ else return pos + minlimit;
+}
+
+int SliderWnd::getSeekStatus()
+{
+ return seeking;
+}
+
+int SliderWnd::thumbWidth()
+{
+ if (thumb.getBitmap() == NULL) return DEFAULT_THUMBWIDTH;
+ return thumb.getWidth();
+}
+
+int SliderWnd::thumbHeight()
+{
+ if (thumb.getBitmap() == NULL) return DEFAULT_THUMBHEIGHT;
+ return thumb.getHeight();
+}
+
+void SliderWnd::setUseBaseTexture(int useit)
+{
+ use_base_texture = useit;
+ invalidate();
+}
+
+void SliderWnd::setBaseTexture(SkinBitmap *bmp, int x, int y)
+{
+ base_texture = bmp;
+ use_base_texture = TRUE;
+ xShift = x;
+ yShift = y;
+ invalidate();
+}
+
+void SliderWnd::setNoDefaultBackground(int no)
+{
+ no_default_background = no;
+}
+
+void SliderWnd::setDrawOnBorders(int draw)
+{
+ drawOnBorders = draw;
+}
+
+void SliderWnd::onEnterArea()
+{
+ SLIDERWND_PARENT::onEnterArea();
+}
+
+void SliderWnd::onLeaveArea()
+{
+ SLIDERWND_PARENT::onLeaveArea();
+}
+
+void SliderWnd::setOrientation(int o)
+{
+ vertical = o;
+}
+
+void SliderWnd::setHotPosition(int h)
+{
+ hotPosition = h;
+}
+
+void SliderWnd::setThumbCentered(int c)
+{
+ thumbCentered = c;
+}
+
+void SliderWnd::setThumbStretched(int c)
+{
+ thumbStretched = c;
+}
+
+
+void SliderWnd::setThumbOffset(int o)
+{
+ thumbOffset = o;
+}
+
+void SliderWnd::abort()
+{
+ if (oldpos != -1)
+ {
+ seeking = 0;
+ captured = 0;
+ endCapture();
+ pos = oldpos;
+ onSetPosition();
+ invalidate();
+ oldpos = -1;
+ }
+ return ;
+}
+
+void SliderWnd::setLimits(int pminlimit, int pmaxlimit)
+{
+ minlimit = pminlimit;
+ maxlimit = pmaxlimit;
+ length = maxlimit - minlimit;
+}
+
+int SliderWnd::onKeyDown(int vkcode)
+{
+ switch (vkcode)
+ {
+ case VK_LEFT: move_left(Std::keyModifier(STDKEY_CONTROL)); return 1;
+ case VK_RIGHT: move_right(Std::keyModifier(STDKEY_CONTROL)); return 1;
+ case VK_HOME: move_start(); return 1;
+ case VK_END: move_end(); return 1;
+ default: return SLIDERWND_PARENT::onKeyDown(vkcode);
+ }
+}
+
+void SliderWnd::move_left(int bigstep)
+{
+ int pos = getSliderPosition();
+ if (!bigstep) pos--; else pos -= (ABS(maxlimit - minlimit) / 10);
+ if (pos < minlimit) pos = minlimit;
+ setPosition(pos);
+}
+
+void SliderWnd::move_right(int bigstep)
+{
+ int pos = getSliderPosition();
+ if (!bigstep)
+ pos++;
+ else
+ pos += (ABS(maxlimit - minlimit) / 10);
+ if (pos > maxlimit)
+ pos = maxlimit;
+ setPosition(pos);
+}
+
+void SliderWnd::move_start()
+{
+ setPosition(minlimit);
+}
+
+void SliderWnd::move_end()
+{
+ setPosition(maxlimit);
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/slider.h b/Src/Wasabi/api/wnd/wndclass/slider.h
new file mode 100644
index 00000000..55c451ea
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/slider.h
@@ -0,0 +1,451 @@
+#ifndef _SLIDER_H
+#define _SLIDER_H
+
+#include <bfc/common.h>
+#include <tataki/bitmap/autobitmap.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+#define SLIDERWND_PARENT GuiObjectWnd
+/**
+ Slider style control.
+
+ @short Slider style control.
+ @author Nullsoft
+ @ver 1.0
+*/
+class SliderWnd : public SLIDERWND_PARENT
+{
+public:
+ /**
+ Sets the defaults for the slider. Defaults to a horizontal
+ slider with the thumb in the center and is enabled.
+ */
+ SliderWnd();
+
+ /**
+ Nothing is handled by the destructor.
+ */
+ virtual ~SliderWnd();
+
+ /**
+ Event is triggered when the window requires a repaint.
+ Override this to implement your own behavior.
+
+ Paints the slider on canvas according to current
+ state of the slider.
+
+ @ret 0, Failed; 1, Success;
+ @param canvas The canvas on which to paint.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ Event is triggered when the left mouse button is pressed while
+ the slider has focus. Override this to implement your
+ own behavior.
+
+ @ret
+ @param x X coordinate of the mouse pointer.
+ @param y Y coordinate of the mouse pointer.
+ */
+ virtual int onLeftButtonDown(int x, int y);
+
+ /**
+ Event is triggered when the mouse has capture on the slider
+ and is being moved. Override this to implement your own
+ behavior.
+
+ @ret 0, Failed; 1, Success;
+ @param x The X position of the mouse.
+ @param y The Y position of the mouse.
+ */
+ virtual int onMouseMove(int x, int y); // only called when mouse captured
+
+ /**
+ Event is triggered when the left mouse button is released.
+ Note that the mouse button must have been previously pressed
+ for this event to happen. Override this to implement your
+ own behavior.
+
+ @ret 1, If you handle the event; 0, If you don't handle the event;
+ @param x The X position of the mouse.
+ @param y The Y position of the mouse.
+ */
+ virtual int onLeftButtonUp(int x, int y);
+
+ /**
+ Event is triggered when the right mouse button is pressed.
+ Override this to implement your own behavior.
+ */
+ virtual int onRightButtonDown(int x, int y);
+
+ /**
+ Event is triggered when a key is pressed and the slider
+ has focus. Override this to implement your own behavior.
+
+ @ret 1, If you handle the event; 0, If you don't handle the event;
+ @param c The key that was pressed.
+ */
+ virtual int onChar(unsigned int c);
+
+ /**
+ Event is triggered when the mouse enters the region
+ of the slider. Override this to implement your
+ own behavior.
+ */
+ virtual void onEnterArea();
+
+ /**
+ Event is triggered when the mouse leaves the region
+ of the slider. Override this to implement your
+ own behavior.
+ */
+ virtual void onLeaveArea();
+
+ /**
+ Event is triggered then the slider is about to be initialized.
+ Override this event to implement your own behavior.
+
+ By default this will render the slider according the it's current settings
+ and position of the thumb.
+
+ @ret 1, Success; 0, Failure;
+ */
+ virtual int onInit();
+
+ /**
+ Constants for positioning of the thumb.
+ */
+ enum {
+ START = 0,
+ END = 65535,
+ FULL = END
+ };
+
+ /**
+ Set the sliders position.
+
+ @param newpos The sliders new position.
+ @param wantcb !0, Generate a callback after the position has been set; 0, No callback;
+ */
+ virtual void setPosition(int newpos, int wantcb=1);
+
+ /**
+ Get the sliders current position. The range is from
+ START (0) to END (65535).
+
+ @ret The sliders position (ranges from 0 to 65535).
+ */
+ int getSliderPosition();
+
+ //void cancelSeek();
+
+ /**
+ Use a base texture when rendering the slider.
+
+ @see setBaseTexture()
+ @param useit 0, Do not use; 1, Use base texture;
+ */
+ void setUseBaseTexture(int useit);
+
+ /**
+ Set the base texture of the slider.
+
+ @see setUseBaseTexture()
+ @see SkinBitmap
+ @param bmp The bitmap to use as a texture.
+ @param x The X position of the base texture.
+ @param y The Y position of the base texture.
+ */
+ void setBaseTexture(SkinBitmap *bmp, int x, int y);
+
+ /**
+ Set the draw area to include the edge borders.
+
+ @param draw 0, Do not include the edges; 1, Include the edges;
+ */
+ void setDrawOnBorders(int draw);
+
+ /**
+ Do not use the default background provided
+ by the current skin?
+
+ If you set this to 1, you MUST specify your bitmaps.
+
+ @param no 0, Use default background; 1, Do not use default;
+ */
+ void setNoDefaultBackground(int no);
+
+ /**
+ Set the bitmaps to be used to render the slider.
+ These include bitmaps for the left, middle, right of
+ the slider. For the thumb, we have bitmaps for the
+ normal, hilited and pushed thumb.
+
+ The bitmaps are set using their xml id or "name".
+ The name should resemble something like this:
+ "studio.seekbar.left".
+
+ @see setLeftBmp()
+ @see setMiddleBmp()
+ @see setRightBmp()
+ @see setThumbBmp()
+ @see setThumbDownBmp()
+ @see setThumbHiliteBmp()
+ @param thumbbmp The normal thumb bitmap name.
+ @param thumbdownbmp The thumb down bitmap name.
+ @param thumbhighbmp The hilited thumb bitmap name.
+ @param leftbmp The left bitmap of the slider name.
+ @param middlebmp The middle bitmap of the slider name.
+ @param rightbmp The right bitmap of the slider name.
+ */
+ void setBitmaps(const wchar_t *thumbbmp, const wchar_t *thumbdownbmp, const wchar_t *thumbhighbmp, const wchar_t *leftbmp, const wchar_t *middlebmp, const wchar_t *rightbmp);
+
+ /**
+ Set the left bitmap of the slider.
+
+ @param name The left bitmap name.
+ */
+ void setLeftBmp(const wchar_t *name);
+
+ /**
+ Set the middle bitmap of the slider.
+
+ @param name The middle bitmap name.
+ */
+ void setMiddleBmp(const wchar_t *name);
+
+ /**
+ Set the right bitmap of the slider.
+
+ @param name The right bitmap name.
+ */
+ void setRightBmp(const wchar_t *name);
+
+ /**
+ Set the normal thumb bitmap of the slider.
+
+ @param name The normal thumb bitmap name.
+ */
+ void setThumbBmp(const wchar_t *name);
+
+ /**
+ Set the thumb down bitmap of the slider.
+
+ @param name The thumb down bitmap name.
+ */
+ void setThumbDownBmp(const wchar_t *name);
+
+ /**
+ Set the hilited thumb bitmap of the slider.
+
+ @param name The hilited thumb bitmap name.
+ */
+ void setThumbHiliteBmp(const wchar_t *name);
+
+ /**
+ Get the height of the slider in pixels.
+
+ @ret The height of the slider (in pixels).
+ */
+ virtual int getHeight();
+
+ /**
+ Get the width of the slider in pixels.
+
+ @ret The width of the slider (in pixels).
+ */
+ virtual int getWidth();
+
+ /**
+ Get the left bitmap of the slider.
+
+ @see SkinBitmap
+ @ret The left SkinBitmap.
+ */
+ SkinBitmap *getLeftBitmap();
+
+ /**
+ Get the right bitmap of the slider.
+
+ @see SkinBitmap
+ @ret The right SkinBitmap.
+ */
+ SkinBitmap *getRightBitmap();
+
+ /**
+ Get the middle bitmap of the slider.
+
+ @see SkinBitmap
+ @ret The middle SkinBitmap.
+ */
+ SkinBitmap *getMiddleBitmap();
+
+ /**
+ Get the thumb bitmap of the slider.
+
+ @see SkinBitmap
+ @ret The thumb SkinBitmap.
+ */
+ SkinBitmap *getThumbBitmap();
+
+ /**
+ Get the thumb down bitmap of the slider.
+
+ @see SkinBitmap
+ @ret The thumb down SkinBitmap.
+ */
+ SkinBitmap *getThumbDownBitmap();
+
+ /**
+ Get the thumb hilite bitmap of the slider.
+
+ @see SkinBitmap
+ @ret The thumb hilite SkinBitmap.
+ */
+ SkinBitmap *getThumbHiliteBitmap();
+
+ /**
+ Set the sliders enable state.
+
+ @param en 1, Enabled; 0, Disabled;
+ */
+
+ virtual void setEnable(int en);
+
+ /**
+ Get the sliders enable state.
+
+ @ret 1, Enabled; 0, Disabled;
+ */
+ virtual int getEnable(void);
+
+ /**
+ Set the orientation of the slider
+ (horizontal or vertical).
+
+ @param o 0, Horizontal; 1, Vertical;
+ */
+ virtual void setOrientation(int o);
+
+ /**
+ This will set a "jump-to" position (like "center" for a balance slider).
+ The parameter is in thumb coordinates (0 to 65535).
+
+ @param h The jump-to position (ranges from 0 to 65535, or START to END).
+ */
+ virtual void setHotPosition(int h);
+ virtual int getHotPosRange() { return hotposrange; }
+ virtual void setHotPosRange(int range) { hotposrange = range; }
+
+ /**
+ Set the thumb center flag. If on, this flag will
+ cause the thumb of the slider to be centered
+ automatically.
+
+ @param c 1, Centered; 0, No centering;
+ */
+ virtual void setThumbCentered(int c);
+ virtual void setThumbStretched(int c);
+
+ /**
+ Set the thumb offset (from the left hand side).
+ This offset will be added to the zero position of the thumb.
+ Note, if you're using centering also, this will cause the slider
+ thumb to be passed the middle of the slider.
+
+ @param o The offset of the thumb (in pixels).
+ */
+ virtual void setThumbOffset(int o);
+
+ /**
+ Set the minimum and maximum limit for the slider.
+
+ @param minlimit The minimum value.
+ @param maxlimit The maximum value.
+ */
+ virtual void setLimits(int minlimit, int maxlimit);
+
+ virtual int getMaxLimit() { return maxlimit; }
+ virtual int getMinLimit() { return minlimit; }
+ virtual int getRange() { return maxlimit-minlimit; }
+
+ virtual int onKeyDown(int vkcode);
+
+ virtual void onCancelCapture();
+protected:
+ /**
+ Abort the current seek and end capture.
+ */
+ void abort();
+
+ // override this to get position change notification
+ /**
+ Event is triggered when the mouse is moving the thumb
+ is being moved. Override this to implment your own behavior.
+
+ @ret The thumb's position (ranges from 0 to 65535 or START to END).
+ */
+ virtual int onSetPosition(); // called constantly as mouse moves
+
+ /**
+ Event is triggered when the thumb is released and the final position
+ is about to be set.
+
+ @ret The thumb's position (ranges from 0 to 65535 or START to END).
+ */
+ virtual int onSetFinalPosition(); // called once after move done
+
+ /**
+ Get the seeking status.
+
+ @ret 1, User is seeking; 0, User is not seeking;
+ */
+ int getSeekStatus(); // returns 1 if user is sliding tab
+
+ int vertical; // set to 1 for up-n-down instead
+
+ /**
+ Get the width of the thumb bitmap, in pixels.
+
+ @ret The thumb's width (in pixels).
+ */
+ int thumbWidth();
+
+ /**
+ Get the height of the thumb bitmap, in pixels.
+
+ @ret The thumb's width (in pixels).
+ */
+ int thumbHeight();
+ // keyboard
+ void move_left(int bigstep);
+ void move_right(int bigstep);
+ void move_start();
+ void move_end();
+
+ int minlimit, maxlimit, length;
+
+private:
+ int seeking;
+ int enabled;
+ int hilite;
+ int pos;
+ int oldpos;
+ int thumbwidth;
+ int captured;
+ int xShift, yShift;
+ SkinBitmap *base_texture;
+ int use_base_texture;
+ int no_default_background;
+ int drawOnBorders;
+ int hotPosition;
+ int origPos;
+ int thumbCentered, thumbOffset, thumbStretched;
+ int hotposrange;
+
+ AutoSkinBitmap left, middle, right;
+ AutoSkinBitmap thumb, thumbdown, thumbhilite;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/status.cpp b/Src/Wasabi/api/wnd/wndclass/status.cpp
new file mode 100644
index 00000000..9ef5af9a
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/status.cpp
@@ -0,0 +1,242 @@
+#include <precomp.h>
+#include "status.h"
+
+#include <tataki/color/skinclr.h>
+#include <tataki/canvas/canvas.h>
+
+#include <api/wnd/wndclass/buttbar.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <api/wndmgr/appcmds.h>
+#include <bfc/parse/paramparser.h>
+
+#include <api/script/objects/c_script/c_text.h>
+
+#define STATUS_TIMER_DECAY 1
+
+#define COMPLETED_WIDTH 96
+
+static SkinColor textcolor(L"wasabi.statusbar.text");
+
+class CmdButton : public ButtonWnd
+{
+public:
+ CmdButton(const wchar_t *name, AppCmds *_cmd, int _id) : ButtonWnd(name), cmd(_cmd), id(_id) {}
+
+ virtual void onLeftPush(int x, int y) {
+ cmd->appcmds_onCommand(id, &windowRect(), AppCmds::LEFT_CLICK);
+ }
+
+ virtual void onRightPush(int x, int y) {
+ cmd->appcmds_onCommand(id, &windowRect(), AppCmds::RIGHT_CLICK);
+ }
+
+ virtual int wantAutoContextMenu() { return 0; }
+
+ AppCmds *cmd;
+ int id;
+};
+
+StatusBar::StatusBar() {
+ overtimer = 0;
+ max = 0;
+ completed = 0;
+ progress_width = 0;
+ bg.setContent(L"wasabi.statusbar");
+ bbleft = bbright = NULL;
+}
+
+StatusBar::~StatusBar()
+{
+ killTimer(STATUS_TIMER_DECAY);
+ delete bbleft;
+ delete bbright;
+}
+
+int StatusBar::onInit() {
+ STATUSBAR_PARENT::onInit();
+
+ bg.init(this);
+
+ #ifdef WASABI_COMPILE_WNDMGR
+ getGuiObject()->guiobject_registerStatusCB(this); // watched
+ #endif
+
+ regenerate();
+
+ return 1;
+}
+
+void StatusBar::timerCallback(int id) {
+ switch (id) {
+ case STATUS_TIMER_DECAY: {
+ killTimer(STATUS_TIMER_DECAY);
+ onSetStatusText(status_text, FALSE); // revert to main text
+ }
+ break;
+ default:
+ STATUSBAR_PARENT::timerCallback(id);
+ break;
+ }
+}
+
+void StatusBar::pushCompleted(int _max) {
+ max = MAX(_max, 0);
+ completed = 0;
+
+ GuiObject *outer = bg.findObject(L"wasabi.statusbar.progress.outline");
+ outer->guiobject_setXmlParam(L"visible", L"0");
+ ASSERT(outer != NULL);
+ ifc_window *outerw = outer->guiobject_getRootWnd();
+ RECT cr;
+ outerw->getClientRect(&cr);
+ progress_width = cr.right - cr.left;
+
+ outerw->setVisible(TRUE);//CUT
+ outer->guiobject_setTargetA(255);
+ outer->guiobject_setTargetSpeed(0.1f);
+ outer->guiobject_gotoTarget();
+
+ GuiObject *inner = bg.findObject(L"wasabi.statusbar.progress.inside");
+ inner->guiobject_setTargetA(255);
+ inner->guiobject_setTargetSpeed(1.0f);
+ inner->guiobject_gotoTarget();
+ inner->guiobject_setXmlParam(L"visible", L"0");
+
+ incCompleted(0);
+}
+
+void StatusBar::incCompleted(int add) {
+ setCompleted(completed + add);
+}
+
+void StatusBar::setCompleted(int _completed) {
+ completed = _completed;
+ GuiObject *inner = bg.findObject(L"wasabi.statusbar.progress.inside");
+ ASSERT(inner != NULL);
+ if (!inner->guiobject_getRootWnd()->isVisible(1)) {
+ inner->guiobject_setXmlParam(L"visible", L"1");
+ inner->guiobject_setTargetA(255);
+ inner->guiobject_setTargetSpeed(0.75);
+ inner->guiobject_gotoTarget();
+ }
+ int pos = (int)(((float)completed / (float)max)*(float)progress_width);
+ inner->guiobject_setXmlParam(L"w", StringPrintfW(L"%d", pos));
+}
+
+void StatusBar::popCompleted() {
+ completed = 0;
+ max = 0;
+ GuiObject *inner = bg.findObject(L"wasabi.statusbar.progress.inside");
+ inner->guiobject_setXmlParam(L"w", L"0");
+ inner->guiobject_setTargetA(0);
+ inner->guiobject_setTargetSpeed(0.75);
+ inner->guiobject_gotoTarget();
+
+//CUT later
+ inner->guiobject_setXmlParam(L"visible", L"0");
+ GuiObject *outer = bg.findObject(L"wasabi.statusbar.progress.outline");
+ outer->guiobject_setXmlParam(L"visible", L"0");
+}
+
+int StatusBar::onResize() {
+ STATUSBAR_PARENT::onResize();
+
+ RECT cr = clientRect();
+
+ bbleft->resize(cr.left, cr.top, bbleft->getWidth(), cr.bottom - cr.top);
+
+ bbright->resize(cr.right-bbright->getWidth(), cr.top, bbright->getWidth(), cr.bottom - cr.top);
+
+ cr.left += bbleft->getWidth();
+ cr.right -= bbright->getWidth();
+
+ bg.resizeToRect(&cr); // put bg group in place
+
+ invalidate();
+ return 1;
+}
+
+void StatusBar::onSetStatusText(const wchar_t *text, int overlay)
+{
+ killTimer(STATUS_TIMER_DECAY);
+ if (!overlay)
+ status_text = text;
+ else setTimer(STATUS_TIMER_DECAY, 4000);
+ ScriptObject *tx = bg.findScriptObject(L"wasabi.statusbar.text");
+ if (tx == NULL) return;
+ C_Text(tx).setText(text ? text : L"");
+}
+
+void StatusBar::onAddAppCmds(AppCmds *commands) {
+ if (appcmds.haveItem(commands)) appcmds.removeItem(commands);
+ appcmds.addItem(commands);
+ regenerate();
+}
+
+void StatusBar::onRemoveAppCmds(AppCmds *commands) {
+ if (appcmds.haveItem(commands)) {
+ appcmds.removeItem(commands);
+ regenerate();
+ }
+}
+
+void StatusBar::regenerate() {
+ if (!isInited()) return;
+
+ delete bbleft; bbleft = new ButtBar;
+ delete bbright; bbright = new ButtBar;
+ bbleft->init(this);
+ bbright->init(this);
+
+ ParamParser exclude(exclude_list, L";");
+ ParamParser showonly(include_only, L";");
+
+ foreach(appcmds)
+ int n = appcmds.getfor()->appcmds_getNumCmds();
+ for (int i = 0; i < n; i++) {
+ int side, id;
+ const wchar_t *name = appcmds.getfor()->appcmds_enumCmd(i, &side, &id);
+ if (name == NULL) break;
+ if (exclude.hasString(name)) continue; // exclusion list
+ if (showonly.getNumItems()) {
+ if (!showonly.hasString(name)) continue; // include-only list
+ }
+ CmdButton *cb = new CmdButton(name, appcmds.getfor(), id);
+// cb->setXmlParam("wantfocus", "1");
+ if (side == AppCmds::SIDE_LEFT) bbleft->addChild(cb);
+ else bbright->addChild(cb);
+ }
+ endfor
+ if (isPostOnInit())
+ onResize();
+}
+
+void StatusBar::fakeButtonPush(const wchar_t *name) {
+ if (!fakeButtonPush(bbleft, name))
+ fakeButtonPush(bbright, name);
+}
+
+int StatusBar::fakeButtonPush(ButtBar *bb, const wchar_t *name)
+{
+ for (int i = 0; i < bb->getNumChildren(); i++) {
+ ButtonWnd *cmdb = bb->enumChild(i);
+ if (!WCSICMP(cmdb->getName(), name)) {
+ int x, y;
+ Wasabi::Std::getMousePos(&x, &y);
+ cmdb->screenToClient(&x, &y);
+ cmdb->onLeftPush(x, y);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void StatusBar::setExclude(const wchar_t *val) {
+ exclude_list = val;
+ regenerate();
+}
+
+void StatusBar::setIncludeOnly(const wchar_t *val) {
+ include_only = val;
+ regenerate();
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/status.h b/Src/Wasabi/api/wnd/wndclass/status.h
new file mode 100644
index 00000000..426c0723
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/status.h
@@ -0,0 +1,178 @@
+#ifndef _STATUS_H
+#define _STATUS_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/string/StringW.h>
+#include <api/wndmgr/guistatuscb.h>
+#include <bfc/depend.h>
+
+class ButtBar;
+class AppCmds;
+
+#define STATUSBAR_PARENT GuiObjectWnd
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class StatusBar : public STATUSBAR_PARENT, public GuiStatusCallbackI {
+public:
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ StatusBar();
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual ~StatusBar();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onInit();
+
+ // completeness indicator
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void pushCompleted(int max);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void incCompleted(int add);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void setCompleted(int pos);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void popCompleted();
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void timerCallback(int id);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual int onResize();
+
+ virtual api_dependent *status_getDependencyPtr() { return this; }
+
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onSetStatusText(const wchar_t *text, int overlay);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onAddAppCmds(AppCmds *commands);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ virtual void onRemoveAppCmds(AppCmds *commands);
+
+ /**
+ Method
+
+ @see
+ @ret
+ @param
+ */
+ void fakeButtonPush(const wchar_t *name);
+
+protected:
+
+ int fakeButtonPush(ButtBar *bb, const wchar_t *name);
+ void setExclude(const wchar_t *val);
+
+ void setIncludeOnly(const wchar_t *val);
+ StringW exclude_list, include_only;
+
+protected:
+ void regenerate();
+
+private:
+ StringW contentgroupname;
+
+ StringW status_text;
+ int overtimer;
+
+ // completeness
+ int max;
+ int completed;
+ int progress_width;
+
+ GuiObjectWnd bg;
+
+ ButtBar *bbleft, *bbright;
+
+ PtrList<AppCmds> appcmds;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/svcwndhold.cpp b/Src/Wasabi/api/wnd/wndclass/svcwndhold.cpp
new file mode 100644
index 00000000..9620ce4d
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/svcwndhold.cpp
@@ -0,0 +1,53 @@
+#include <precomp.h>
+
+#include "svcwndhold.h"
+
+#include <bfc/common.h>
+
+#include <api/service/svcs/svc_wndcreate.h>
+
+#include <api/wnd/wndclass/blankwnd.h>
+
+ServiceWndHolder::ServiceWndHolder(ifc_window *_child, svc_windowCreate *_svc) :
+ child(NULL), svc(NULL)
+ {
+ setChild(_child, _svc);
+}
+
+ServiceWndHolder::~ServiceWndHolder()
+{
+ if (svc != NULL)
+ {
+ svc->destroyWindow(child);
+ if (!svc->refcount())
+ WASABI_API_SVC->service_release(svc);
+ } else {
+ delete static_cast<BaseWnd*>(child);
+ }
+}
+
+int ServiceWndHolder::setChild(ifc_window *_child, svc_windowCreate *_svc)
+{
+ if (child == _child && svc == _svc) return 0;
+
+ if (child != NULL) {
+ if (svc != NULL) {
+ svc->destroyWindow(child);
+ if (!svc->refcount())
+ WASABI_API_SVC->service_release(svc);
+ svc = NULL;
+ } else {
+ delete static_cast<BaseWnd*>(child);
+ }
+ child = NULL;
+ }
+
+ child = _child;
+ svc = _svc;
+
+ return 1;
+}
+
+ifc_window *ServiceWndHolder::rootwndholder_getRootWnd() {
+ return child ? child : SERVICEWNDHOLDER_PARENT::rootwndholder_getRootWnd();
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/svcwndhold.h b/Src/Wasabi/api/wnd/wndclass/svcwndhold.h
new file mode 100644
index 00000000..d671951e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/svcwndhold.h
@@ -0,0 +1,51 @@
+#ifndef _SVCWNDHOLD_H
+#define _SVCWNDHOLD_H
+
+#include <api/wnd/wndclass/rootwndholder.h>
+#include <bfc/common.h>
+
+class svc_windowCreate;
+
+// for some reason if this derives from virtualwnd typesheet won't show it
+#define SERVICEWNDHOLDER_PARENT RootWndHolder
+
+/**
+ class ServiceWndHolder .
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class ServiceWndHolder : public SERVICEWNDHOLDER_PARENT {
+public:
+ /**
+ ServiceWndHolder constructor .
+
+ @param _child A pointer to the child we want to set.
+ @param _svc A pointer to the window creation service associated with the window we want to set as a child.
+ */
+ ServiceWndHolder(ifc_window *child=NULL, svc_windowCreate *svc=NULL);
+
+ /**
+ ServiceWndHolder destructor
+ */
+ virtual ~ServiceWndHolder();
+
+ /**
+ ServiceWndHolder method setChild .
+
+ @ret 1
+ @param _child A pointer to the child we want to set.
+ @param _svc A pointer to the window creation service associated with the window we want to set as a child.
+ */
+ int setChild(ifc_window *child, svc_windowCreate *svc);
+
+ virtual ifc_window *rootwndholder_getRootWnd();
+
+private:
+ ifc_window *child;
+ svc_windowCreate *svc;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/tabsheet.cpp b/Src/Wasabi/api/wnd/wndclass/tabsheet.cpp
new file mode 100644
index 00000000..6323fcc2
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/tabsheet.cpp
@@ -0,0 +1,544 @@
+#include "precomp.h"
+#include "tabsheet.h"
+#include "buttwnd.h"
+#include "buttbar.h"
+#include "tabsheetbar.h"
+
+#include <bfc/wasabi_std.h>
+#include <api/wnd/notifmsg.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/objects/c_script/c_group.h>
+#include <api/wnd/PaintCanvas.h>
+
+TabSheet::TabSheet(int bbtype) {
+ leftscroll = rightscroll = NULL;
+ background = NULL;
+ tabrowmargin = 0;
+ active = NULL;
+ type = bbtype;
+ bb = NULL;
+ tsb = NULL;
+ content_margin_top = content_margin_right = content_margin_left = content_margin_bottom = 0;
+ contentwnd = NULL;
+
+ if (bbtype == TABSHEET_GROUPS) {
+ tsb = new TabSheetBar();
+ tsb->setParent(this);
+ } else { // schweitn rulz
+ bb = new ButtBar((bbtype == -1) ? ButtBar::NORMAL : bbtype);
+ bb->setParent(this);
+ if (bbtype == TABSHEET_NOTABS)
+ bb->setStartHidden(1);
+ }
+}
+
+TabSheet::~TabSheet() {
+ delete bb; // kills tabs and child wnds
+ delete tsb;
+ delete leftscroll;
+ delete rightscroll;
+ delete background;
+ delete contentwnd;
+}
+
+void TabSheet::setButtonType(int _type) {
+ type = _type;
+ if (contentwnd != NULL) {
+ if (type == ButtBar::STACK)
+ contentwnd->setContent(L"wasabi.tabsheet.content.noborder");
+ else if (type != TABSHEET_NOTABS)
+ contentwnd->setContent(L"wasabi.tabsheet.content");
+ else
+ contentwnd->setContent(NULL);
+ }
+ if (_type == TABSHEET_GROUPS && bb != NULL) {
+ PtrList<BaseWnd> l;
+ foreach(tabs)
+ l.addItem(tabs.getfor()->getBaseWnd());
+ tabs.getfor()->setNoDeleteLinked(1);
+ endfor;
+ delete bb; bb = NULL;
+ tabs.removeAll();
+ tsb = new TabSheetBar();
+ tsb->setParent(this);
+ if (isInited())
+ tsb->init(this);
+ foreach(l)
+ addChild(l.enumItem(foreach_index));
+ endfor;
+ } else if (_type != TABSHEET_GROUPS && tsb != NULL) {
+ PtrList<BaseWnd> l;
+ foreach(tabs)
+ l.addItem(tabs.getfor()->getBaseWnd());
+ tabs.getfor()->setNoDeleteLinked(1);
+ endfor;
+ delete tsb; tsb = NULL;
+ tabs.removeAll();
+ bb = new ButtBar((type == -1) ? ButtBar::NORMAL : type);
+ bb->setParent(this);
+ if (type == TABSHEET_NOTABS)
+ bb->setStartHidden(1);
+ if (isInited())
+ bb->init(this);
+ foreach(l)
+ addChild(l.enumItem(foreach_index));
+ endfor;
+ }
+ if (bb != NULL) bb->setResizeMode(type);
+}
+
+void TabSheet::killChildren() {
+ if (bb) {
+ delete bb; // kills tabs and child wnds
+ bb = new ButtBar((type == -1) ? ButtBar::NORMAL : type);
+ bb->setParent(this);
+ if (type == TABSHEET_NOTABS)
+ bb->setStartHidden(1);
+ bb->init(this);
+ }
+ if (tsb) {
+ delete tsb; // kills tabs and child wnds
+ tsb = new TabSheetBar;
+ tsb->setParent(this);
+ tsb->init(this);
+ }
+
+ // mig: if you don't do this, you crash changing tabsheets at runtime.
+ tabs.removeAll();
+ active = NULL;
+}
+
+int TabSheet::onInit() {
+ TABSHEET_PARENT::onInit();
+
+ contentwnd = new GuiObjectWnd;
+ if (type == ButtBar::STACK)
+ contentwnd->setContent(L"wasabi.tabsheet.content.noborder");
+ else if (type != TABSHEET_NOTABS)
+ contentwnd->setContent(L"wasabi.tabsheet.content");
+ else
+ contentwnd->setContent(NULL);
+ contentwnd->setParent(this);
+ contentwnd->init(this);
+ rootwndholder_setRootWnd(contentwnd);
+
+ if (leftscroll != NULL) {
+ leftscroll->init(this);
+ leftscroll->setParent(this);
+ }
+ if (rightscroll != NULL) {
+ rightscroll->init(this);
+ rightscroll->setParent(this);
+ }
+
+ // init the windows
+ foreach(tabs)
+ if (foreach_index != 0) tabs.getfor()->getBaseWnd()->setStartHidden(TRUE);
+ tabs.getfor()->getBaseWnd()->init(this);
+ endfor
+
+ if (bb) {
+ bb->setParent(this);
+ if (type == TABSHEET_NOTABS)
+ bb->setStartHidden(1);
+ bb->init(this); // inits the tabs
+ }
+ if (tsb) {
+ tsb->setParent(this);
+ tsb->init(this); // inits the tabs
+ }
+
+ if (tabs.getNumItems() > 0) {
+ active = tabs[0]->getBaseWnd();
+ //tabs[0]->setHilite(TRUE); // FG: FIX!
+ }
+
+ if (isPostOnInit())
+ onResize();
+
+ return 1;
+}
+
+void TabSheet::getClientRect(RECT *r) {
+ TABSHEET_PARENT::getClientRect(r);
+ if (bb) {
+ if (type != TABSHEET_NOTABS)
+ r->top += bb->getHeight();
+ } else
+ r->top += tsb->getHeight();
+
+ r->left += content_margin_left;
+ r->top += content_margin_top;
+ r->right -= content_margin_right;
+ r->bottom -= content_margin_bottom;
+}
+
+#ifdef WASABI_COMPILE_IMGLDR
+void TabSheet::setBackgroundBmp(const wchar_t *name)
+{
+ if (background) delete background;
+ background = NULL;
+ if (name && *name)
+ background = new SkinBitmap(name);
+}
+#endif
+
+SkinBitmap *TabSheet::getBackgroundBitmap() {
+ return background;
+}
+
+int TabSheet::onPaint(Canvas *canvas) {
+
+ PaintBltCanvas paintcanvas;
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaintNC(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ TABSHEET_PARENT::onPaint(canvas);
+
+ RECT r;
+ TABSHEET_PARENT::getClientRect(&r);
+
+ if (bb) {
+ if (type != TABSHEET_NOTABS)
+ r.bottom = r.top + bb->getHeight();
+ }
+ else if (tsb)
+ r.bottom = r.top + tsb->getHeight();
+
+ RECT br = r;
+ if (leftscroll) br.left += leftscroll->getWidth();
+ if (rightscroll) br.right -= rightscroll->getWidth();
+
+ if (br.right <= br.left) return 1;
+
+ if (background != NULL) {
+#if 0
+ int i, x = tilex;
+ for (i = 0; ; i++) {
+ tile->stretch(canvas, x, 0, tile->getWidth(), tabrowheight);
+ x += tile->getWidth();
+ if (x >= r.right) break;
+ }
+#else
+#if 0
+ if (background->getAlpha()) api->skin_renderBaseTexture(canvas, br);
+ background->stretchToRectAlpha(canvas, &br);
+#else
+ background->stretchToRect(canvas, &br);
+#endif
+#endif
+ } else {
+#if 0
+ r.top = 0;
+ r.bottom = tabrowheight;
+ r.left = tilex;
+ r.right = tilex + tilew;
+ canvas->fillRect(&r, RGB(64, 64, 64));
+#else
+// api->skin_renderBaseTexture(canvas, r);
+#endif
+ }
+
+ return 1;
+}
+
+void TabSheet::setTabRowMargin(int newmargin) {
+ ASSERT(newmargin >= 0);
+ tabrowmargin = newmargin;
+ onResize();
+}
+
+int TabSheet::addChild(BaseWnd *newchild, const wchar_t *tip) {
+
+ ASSERT(newchild != NULL);
+
+ int first=0;
+ if (tabs.getNumItems() == 0) first = 1;
+
+ if (isInited() && !newchild->isInited()) {
+ if (!first) newchild->setStartHidden(TRUE);
+
+ ifc_window *holder = this;
+ if (contentwnd != NULL) {
+ if (contentwnd->getContentRootWnd() != NULL) {
+ GuiObject *o = contentwnd->getContent()->guiobject_findObject(L"content");
+ if (o != NULL)
+ holder = o->guiobject_getRootWnd();
+ }
+ }
+ newchild->setParent(holder);
+ newchild->init(holder);
+ }
+
+ if (bb)
+ {
+ TabButton *tab = new TabButton(newchild, this, tip);
+ tabs.addItem(tab);
+ bb->addChild(tab);
+ }
+ else if (tsb)
+ {
+ GroupTabButton *tab = new GroupTabButton(newchild, this, tip);
+ tabs.addItem(tab);
+ tsb->addChild(tab);
+ }
+ if (isInited()) {
+ if (first) {
+ activateChild(newchild);
+ }
+ }
+ if (isPostOnInit()) onResize();
+ return tabs.getNumItems()-1;
+}
+
+void TabSheet::activateChild(BaseWnd *newactive) {
+ BaseWnd *prevactive = active;
+ if (newactive == NULL) newactive = active;
+
+ if (prevactive == newactive) return; // not a switch
+
+#if 0
+ RECT r = clientRect();
+
+ int w = r.right - r.left + 1;
+ int h = r.bottom - r.top + 1;
+#endif
+
+ int prevpos=-1, nextpos=-1;
+
+ for (int i = 0; i < tabs.getNumItems(); i++) {
+ if (prevactive == tabs[i]->getBaseWnd()) prevpos = i;
+ if (newactive == tabs[i]->getBaseWnd()) nextpos = i;
+ }
+
+ if (prevpos != -1) tabs[prevpos]->btn_setHilite(FALSE);
+ if (nextpos < tabs.getNumItems()) tabs[nextpos]->btn_setHilite(TRUE);
+
+#if 0
+ // reveal tha new winder
+ if (newactive!= NULL) newactive->setVisible(TRUE);
+
+ enable(FALSE);
+ if (prevactive!= NULL) prevactive->enable(FALSE);
+ if (newactive!= NULL) newactive->enable(FALSE);
+
+#define STEPS 6
+
+ // find which window is now active
+ for (int c = 0; c < STEPS; c++) {
+ int x;
+ if (prevpos > nextpos) x = (w * c) / STEPS; // right to left
+ else x = (w * (STEPS - c)) / STEPS; // left to right
+ int y = r.top;
+ if (prevpos > nextpos) {
+ if (newactive!= NULL) newactive->move(x - w, y);
+ if (prevactive!= NULL) prevactive->move(x, y);
+ } else {
+ if (newactive!= NULL) newactive->move(x, y);
+ if (prevactive!= NULL) prevactive->move(x - w, y);
+ }
+ if (newactive!= NULL) newactive->repaint();
+ if (prevactive!= NULL) prevactive->repaint();
+ Sleep(15);
+ }
+#endif
+
+ if (newactive!= NULL) newactive->setVisible(TRUE);
+
+ if (prevactive!= NULL) prevactive->setVisible(FALSE);
+
+#if 0
+ enable(TRUE);
+ if (prevactive!= NULL) prevactive->enable(TRUE);
+ if (newactive!= NULL) newactive->enable(TRUE);
+#endif
+
+ if (bb && newactive)
+ bb->setGroupLabel(newactive->getName());
+ active = newactive;
+ onSetPage(nextpos);
+}
+
+int TabSheet::onResize() {
+ TABSHEET_PARENT::onResize();
+
+ if (!isInited()) return 1;
+
+ RECT r = clientRect();
+
+ // put buttbar at the top
+ if (bb) bb->resize(r.left, r.top-bb->getHeight(), r.right-r.left, bb->getHeight()+1);
+ if (tsb) tsb->resize(r.left, r.top-tsb->getHeight(), r.right-r.left, tsb->getHeight()+1);
+
+ // resize content group if it's there
+ if (contentwnd) {
+ contentwnd->resize(&r);
+ // since its holder is not resizing its content, we need to do it ourselves
+ foreach(tabs)
+ BaseWnd *c = tabs.getfor()->getBaseWnd();
+ if (c->getParent() != NULL && c->getParent() != this && c->getParent()->getParent() == contentwnd->getContentRootWnd()) {
+ RECT r;
+ c->getParent()->getClientRect(&r);
+ c->resize(&r);
+ } else {
+ // if we're holding it directly, resize it to our rect
+ c->resize(&r);
+ }
+ endfor
+ }
+
+ invalidate();
+ if (leftscroll)
+ leftscroll->invalidate();
+ if (rightscroll)
+ rightscroll->invalidate();
+
+ return 1;
+}
+
+BaseWnd *TabSheet::enumChild(int child) {
+ TabButtonBase *tb = tabs[child];
+ if (tb == NULL) return NULL;
+ return tb->getBaseWnd();
+}
+
+int TabSheet::getNumChild() {
+ return tabs.getNumItems();
+}
+
+void TabSheet::setCurPage(int page) {
+ BaseWnd *e = enumChild(page);
+ if (e != NULL) activateChild(e);
+}
+
+TabButtonBase *TabSheet::enumButton(int i) {
+ if (i < tabs.getNumItems())
+ return tabs[i];
+ else
+ return NULL;
+}
+
+int TabSheet::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+ if (msg == ChildNotify::NAMECHANGED)
+ {
+ foreach(tabs)
+ ifc_window *w = tabs.getfor()->getBaseWnd();
+ if (w == child || w == child->getParent()) {
+ const wchar_t *name = child->getRootWndName();
+ tabs.getfor()->btn_setText(name && *name ? name : L"[?]");
+ }
+ endfor;
+ }
+ if (msg == ChildNotify::GROUPRELOAD && child == contentwnd) {
+ foreach(tabs)
+ ifc_window *holder = this;
+ if (contentwnd->getContentRootWnd() != NULL) {
+ GuiObject *o = contentwnd->getContent()->guiobject_findObject(L"content");
+ if (o != NULL)
+ holder = o->guiobject_getRootWnd();
+ }
+ tabs.getfor()->getBaseWnd()->reparent(holder);
+ endfor;
+ }
+ return TABSHEET_PARENT::childNotify(child, msg, param1, param2);
+}
+
+
+void TabSheet::setContentMarginLeft(int cm) {
+ content_margin_left = cm;
+ if (isInited())
+ onResize();
+}
+
+void TabSheet::setContentMarginTop(int cm) {
+ content_margin_top = cm;
+ if (isInited())
+ onResize();
+}
+
+void TabSheet::setContentMarginRight(int cm) {
+ content_margin_right = cm;
+ if (isInited())
+ onResize();
+}
+
+void TabSheet::setContentMarginBottom(int cm) {
+ content_margin_bottom = cm;
+ if (isInited())
+ onResize();
+}
+
+int TabSheet::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
+ if (!WCSICMP(action, L"Tabsheet:NextPage")) { nextPage(); return 1; }
+ if (!WCSICMP(action, L"Tabsheet:PreviousPage")) { previousPage(); return 1; }
+ return TABSHEET_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
+}
+
+// TabButton
+
+TabButtonBase::TabButtonBase(BaseWnd *linkwnd, TabSheet *par, const wchar_t *tip)
+: linked(linkwnd), parent(par) {
+ nodeletelinked = 0;
+ ASSERT(linked != NULL);
+}
+
+TabButtonBase::~TabButtonBase() {
+ if (!nodeletelinked) delete linked;
+}
+
+int TabButton::onInit()
+{
+ TABBUTTON_PARENT::onInit();
+ setButtonText(linked->getNameSafe(L"[?]"));
+ return 1;
+}
+
+void TabButton::onLeftPush(int x, int y) {
+ ASSERT(parent != NULL);
+ ASSERT(linked != NULL);
+ parent->activateChild(linked);
+}
+
+void TabButton::btn_setHilite(int tf) {
+ setHilite(tf);
+}
+
+void TabButton::btn_setText(const wchar_t *text)
+{
+ setButtonText(text);
+}
+
+// GroupTabButton
+
+void GroupTabButton::grouptoggle_onLeftPush() {
+ GROUPTABBUTTON_PARENT::grouptoggle_onLeftPush();
+ ASSERT(parent != NULL);
+ ASSERT(linked != NULL);
+ parent->activateChild(linked);
+}
+
+void GroupTabButton::btn_setHilite(int tf) {
+ setStatus(tf ? STATUS_ON : STATUS_OFF);
+}
+
+void GroupTabButton::btn_setText(const wchar_t *text)
+{
+ for (int i=0;i<getNumGroups();i++) {
+ GuiObject *grp = enumGroups(i)->getContent();
+ if (grp != NULL) {
+ GuiObject *o = grp->guiobject_findObject(L"text");
+ if (o != NULL) {
+ C_Text txt(o->guiobject_getScriptObject());
+ txt.setText(text);
+ }
+ }
+ }
+}
+
+int GroupTabButton::onInit() {
+ int rt = GROUPTABBUTTON_PARENT::onInit();
+ btn_setText(linked->getNameSafe(L"[?]"));
+ return rt;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/tabsheet.h b/Src/Wasabi/api/wnd/wndclass/tabsheet.h
new file mode 100644
index 00000000..73426ec9
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/tabsheet.h
@@ -0,0 +1,268 @@
+#ifndef _TABSHEET_H
+#define _TABSHEET_H
+
+#include <api/skin/widgets/grouptgbutton.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <bfc/common.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/ptrlist.h>
+
+class ButtonWnd;
+class SkinBitmap;
+class TabButtonBase;
+class ButtBar;
+class TabSheetBar;
+
+#define TABSHEET_GROUPS -2
+#define TABSHEET_NOTABS -3
+
+#define TABSHEET_PARENT GuiObjectWnd
+/**
+ class TabSheet
+
+ @short A TabSheet Control.
+ @author Nullsoft
+ @ver 1.0
+ @see
+ @cat SDK
+*/
+class TabSheet : public TABSHEET_PARENT
+{
+public:
+ /**
+ TabSheet constructor
+
+ @see ~TabSheet()
+ @param bbtype The type of button bar to use in the tabsheet.
+ */
+ TabSheet(int bbtype=-1);
+
+ /**
+ TabSheet destructor
+ @see TabSheet()
+ */
+ virtual ~TabSheet();
+
+ /**
+ TabSheet method onInit
+ @ret 1
+ */
+ virtual int onInit();
+
+ /**
+ TabSheet method getClientRect
+
+ @param r A pointer to the RECT that will be filled.
+ */
+ virtual void getClientRect(RECT *);
+
+ /**
+ TabSheet method onPaint
+
+ @ret 1
+ @param canvas The canvas upon which we'll paint ourself.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ TabSheet method onResize
+
+ @ret 1
+ */
+ virtual int onResize();
+
+ /**
+ TabSheet method setButtonType .
+
+ @param type The button type.
+ */
+ void setButtonType(int type);
+
+ /**
+ TabSheet method setTabRowMargin
+
+ @assert newmargin is non-negative
+ @param newmargin The new margin width in pixels.
+ */
+ void setTabRowMargin(int pixels);
+
+ /**
+ TabSheet method addChild
+
+ @ret One less than the number of tabs
+ @param newchild A pointer to the new child window to add.
+ @param tip The tooltip for the button associated with this child.
+ */
+ int addChild(BaseWnd *newchild, const wchar_t *tooltip=NULL);
+
+ /**
+ TabSheet method activateChild
+
+ @see addChild()
+ @see killChildren()
+ @ret None
+ @param newactive A pointer to the child window to render active.
+ */
+ virtual void activateChild(BaseWnd *activechild);
+
+ /**
+ TabSheet method killChildren .
+ */
+ virtual void killChildren();
+
+ /**
+ TabSheet method childNotify .
+
+ @ret Returns 1 when complete.
+ @param child The child that's being notified.
+ @param msg The message.
+ @param param1 Custom parameter 1.
+ @param param2 Custom parameter 2.
+ */
+ virtual int childNotify(ifc_window *child, int msg,
+ intptr_t param1=0, intptr_t param2=0);
+
+ void setContentMarginLeft(int cm);
+ void setContentMarginTop(int cm);
+ void setContentMarginRight(int cm);
+ void setContentMarginBottom(int cm);
+
+ /**
+ TabSheet method enumChild
+ @ret The base window of the specified tab button, or NULL if there is none.
+ */
+ BaseWnd *enumChild(int child);
+
+ /**
+ TabSheet method getNumChild
+ @ret The number of tabs
+ */
+ int getNumChild();
+
+ BaseWnd *getActiveChild() { return active; }
+ virtual void onSetPage(int n) { lastpage = n; }
+ int getCurPage() { return lastpage; }
+ void setCurPage(int page);
+ int getNumPages() { return tabs.getNumItems(); }
+ void nextPage() { int n = getCurPage()+1; if (n >= getNumPages()) n = 0; setCurPage(n); }
+ void previousPage() { int n = getCurPage()-1; if (n < 0) n = getNumPages()-1; setCurPage(n); }
+ int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
+
+protected:
+ /** TabSheet method enumButton
+ @ret The specified tab, or NULL if there is none. */
+ TabButtonBase *enumButton(int button);
+
+public:
+ /**
+ TabSheet method setBackgroundBmp
+
+ @param name The name of the bitmap to use.
+ */
+#ifdef WASABI_COMPILE_IMGLDR
+ void setBackgroundBmp(const wchar_t *name); //FG
+#endif
+ SkinBitmap *getBackgroundBitmap(); //FG
+
+protected:
+ // you can set these in your constructor, they will be deleted for you
+ ButtonWnd *leftscroll, *rightscroll;
+ SkinBitmap *background;
+
+private:
+ int tabrowheight, tabrowwidth, tabrowmargin;
+ PtrList<TabButtonBase> tabs;
+
+ ButtBar *bb;
+ TabSheetBar *tsb;
+ GuiObjectWnd *contentwnd;
+
+ int tilex, tilew;
+
+ BaseWnd *active;
+ int type;
+ int content_margin_left, content_margin_top, content_margin_right, content_margin_bottom;
+ int lastpage;
+};
+
+class TabButtonBase
+{
+ public:
+ TabButtonBase(BaseWnd *linkWnd, TabSheet *par, const wchar_t *tip=NULL);
+ virtual ~TabButtonBase();
+
+ BaseWnd *getBaseWnd() const { return linked; }
+ void setNoDeleteLinked(int i) { nodeletelinked = i; }
+
+ virtual void btn_setHilite(int tf)=0;
+ virtual void btn_setText(const wchar_t *txt)=0;
+
+ protected:
+ BaseWnd *linked;
+ TabSheet *parent;
+ int nodeletelinked;
+};
+
+#define TABBUTTON_PARENT ButtonWnd
+
+/**
+ Class TabButton
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see TabButtonBase
+ @cat SDK
+*/
+class TabButton : public TABBUTTON_PARENT, public TabButtonBase {
+public:
+ /**
+ TabButton constructor
+
+ @assert The BaseWnd passed to this method must previously be linked.
+ @param linkwnd The window to associate with this button.
+ @param par A pointer to the parent tabsheet.
+ @param tip The tooltip for the window associated with this button.
+ */
+ TabButton(BaseWnd *linkWnd, TabSheet *par, const wchar_t *tip=NULL) : TabButtonBase(linkWnd, par, tip)
+ {
+ if (tip != NULL)
+ setTip(tip);
+ }
+
+ /**
+ TabButton method onInit
+
+ @ret 1
+ */
+ virtual int onInit();
+
+ /**
+ TabButton method onLeftPush .
+
+ @assert parent and linked both exist.
+ @param x The X position, of the mouse pointer, in the client screen.
+ @param y The Y position, of the mouse pointer, in the client screen.
+ */
+ virtual void onLeftPush(int x, int y);
+ virtual void btn_setHilite(int tf);
+ virtual void btn_setText(const wchar_t *text);
+};
+
+
+#define GROUPTABBUTTON_PARENT GroupToggleButton
+class GroupTabButton : public GROUPTABBUTTON_PARENT, public TabButtonBase {
+public:
+ GroupTabButton(BaseWnd *linkWnd, TabSheet *par, const wchar_t *tip=NULL) : TabButtonBase(linkWnd, par, tip)
+ {
+ setGroups(L"wasabi.tabsheet.button.selected.group", L"wasabi.tabsheet.button.unselected.group");
+ }
+ virtual int wantFullClick() { return 0; }
+ virtual int wantAutoToggle() { return 0; }
+ virtual int onInit();
+ virtual void grouptoggle_onLeftPush();
+ virtual void btn_setHilite(int tf);
+ virtual void btn_setText(const wchar_t *text);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/tabsheetbar.cpp b/Src/Wasabi/api/wnd/wndclass/tabsheetbar.cpp
new file mode 100644
index 00000000..f31dbc73
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/tabsheetbar.cpp
@@ -0,0 +1,130 @@
+#include "precomp.h"
+#include "tabsheetbar.h"
+#include "tabsheet.h"
+#include "../notifmsg.h"
+
+TabSheetBar::TabSheetBar() {
+ margin = 0;
+ spacing = -4;
+ maxheightsofar = 0;
+ bottombar.setParent(this);
+}
+
+TabSheetBar::~TabSheetBar()
+{
+ btns.deleteAll();
+}
+
+int TabSheetBar::onInit() {
+ int rt = TABSHEETBAR_PARENT::onInit();
+
+ bottombar.setContent(L"wasabi.tabsheet.nobutton.group");
+ bottombar.init(this);
+
+ foreach(btns)
+ GroupTabButton *gtb = btns.getfor();
+ gtb->setParent(this);
+ if (!gtb->isInited()) {
+ gtb->init(this);
+ }
+ if (foreach_index == 0)
+ gtb->setStatus(STATUS_ON);
+ else
+ gtb->setStatus(STATUS_OFF);
+ int h = gtb->getPreferences(SUGGESTED_H);
+ if (h == AUTOWH) h = maxheightsofar;
+ maxheightsofar = MAX(maxheightsofar, h);
+ endfor;
+
+ return rt;
+}
+
+void TabSheetBar::addChild(GroupTabButton *child) {
+ ASSERT(!btns.haveItem(child));
+ btns.addItem(child);
+ if (isInited()) {
+ child->setParent(this);
+ if (!child->isInited()) {
+ child->init(this);
+ }
+ int h = child->getPreferences(SUGGESTED_H);
+ if (h == AUTOWH) h = maxheightsofar;
+ maxheightsofar = MAX(maxheightsofar, h);
+ onResize();
+ }
+ if (btns.getNumItems() == 1)
+ child->setStatus(STATUS_ON);
+ else
+ child->setStatus(STATUS_OFF);
+}
+
+int TabSheetBar::getHeight() {
+ return maxheightsofar;
+}
+
+int TabSheetBar::onResize() {
+ int rt = TABSHEETBAR_PARENT::onResize();
+ GroupTabButton *selected=NULL;
+ foreach(btns)
+ if (btns.getfor()->getStatus() == STATUS_ON) {
+ selected = btns.getfor();
+ break;
+ }
+ endfor;
+ if (selected == NULL) selected = btns.getFirst();
+
+ RECT r;
+ getClientRect(&r);
+
+ int x = margin;
+
+ foreach(btns)
+ GroupTabButton *gtb = btns.getfor();
+
+ int w = gtb->getPreferences(SUGGESTED_W);
+ if (w == AUTOWH) w = 66;
+
+ RECT dr;
+ dr.left = r.left + x;
+ dr.top = r.top;
+ dr.right = dr.left + w;
+ dr.bottom = dr.top + getHeight();
+
+ gtb->resize(&dr);
+
+ x += w + spacing;
+ endfor;
+
+ x -= spacing;
+ RECT dr;
+ dr.left = r.left + x;
+ dr.top = r.top;
+ dr.right = r.right;
+ dr.bottom = r.top + getHeight();
+ bottombar.resize(&dr);
+
+ if (selected != NULL)
+ selected->bringToFront();
+
+ return rt;
+}
+
+int TabSheetBar::childNotify(ifc_window *child, int msg, intptr_t param1/* =0 */, intptr_t param2/* =0 */) {
+ if (msg == ChildNotify::GROUPCLICKTGBUTTON_CLICKED && btns.haveItem(static_cast<GroupTabButton *>(child))) {
+ GroupToggleButton *but = NULL;
+ foreach(btns)
+ if (btns.getfor() != child)
+ btns.getfor()->setStatus(STATUS_OFF);
+ else
+ but = btns.getfor();
+ endfor;
+ if (but != NULL)
+ but->setStatus(STATUS_ON);
+ else
+ (static_cast<GroupToggleButton *>(child))->setStatus(STATUS_ON);
+ onResize();
+ }
+ if (msg == ChildNotify::AUTOWHCHANGED && btns.haveItem(static_cast<GroupTabButton *>(child)) && isPostOnInit())
+ onResize();
+ return TABSHEETBAR_PARENT::childNotify(child, msg, param1, param2);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/tabsheetbar.h b/Src/Wasabi/api/wnd/wndclass/tabsheetbar.h
new file mode 100644
index 00000000..3070e8eb
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/tabsheetbar.h
@@ -0,0 +1,39 @@
+#ifndef __TABSHEETBAR_H
+#define __TABSHEETBAR_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+
+class GroupTabButton;
+
+#define TABSHEETBAR_PARENT GuiObjectWnd
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class TabSheetBar : public TABSHEETBAR_PARENT
+{
+public:
+ TabSheetBar();
+ virtual ~TabSheetBar();
+ virtual int onInit();
+ virtual int onResize();
+ virtual void addChild(GroupTabButton *child);
+ virtual int getHeight();
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+ void setMargin(int m) { margin = m; if (isInited()) onResize(); }
+ void setSpacing(int s) { spacing = s; if (isInited()) onResize(); }
+
+private:
+ int maxheightsofar;
+ PtrList<GroupTabButton> btns;
+ int margin, spacing;
+ GuiObjectWnd bottombar;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/textbar.cpp b/Src/Wasabi/api/wnd/wndclass/textbar.cpp
new file mode 100644
index 00000000..ae695419
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/textbar.cpp
@@ -0,0 +1,148 @@
+#include "precomp.h"
+
+#include "textbar.h"
+
+#include <bfc/ifc_canvas.h>
+#include <bfc/string/string.h>
+#include <bfc/skinclr.h>
+#include <bfc/autobitmap.h>
+#include <common/checkwnd.h>
+
+static SkinColor bgcolor("wasabi.textBar.background", "Text backgrounds");
+static SkinColor fgcolor("wasabi.textBar.text");
+
+TextBar::TextBar() {
+ size = 16;
+ usebt = 0;
+ alignment = TEXTALIGN_LEFT; //set default alignment
+ checkwndtarget = NULL;
+
+ textshadowed = 1; // display a shadow of the text in bgcolor. default: on
+ textoutlined = 0; // draw an outline of the text in bgcolor. default: off
+ drawbox = 0; // draw a box of bgcolor the size of the boundsrect. default: off
+
+// bgbitmap = "studio.textBar.background";
+}
+
+int TextBar::onLeftButtonDown(int x, int y) {
+ TEXTBAR_PARENT::onLeftButtonDown(x, y);
+ if (checkwndtarget) checkwndtarget->toggle();
+ return 1;
+}
+
+void TextBar::setUseBaseTexture(int u) {
+ usebt = u;
+ invalidate();
+}
+
+int TextBar::onPaint(Canvas *canvas) {
+ RECT r;
+
+ PaintCanvas paintcanvas;
+ if (canvas == NULL) {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ TEXTBAR_PARENT::onPaint(canvas);
+
+ getClientRect(&r);
+
+ if (!usebt) {
+ if (drawbox) {
+ canvas->fillRect(&r, bgcolor);
+ }
+/*
+ if (bgbitmap.getBitmap()->isInvalid())
+ canvas->fillRect(&r, bgcolor);
+ else {
+ RECT br;
+ br.left = 0;
+ br.top = 0;
+ br.right = bgbitmap.getWidth();
+ br.bottom = bgbitmap.getHeight();
+ bgbitmap.getBitmap()->blitToRect(canvas, &br, &r, 255);
+ }
+*/
+ } else
+ renderBaseTexture(canvas, r);
+
+ const char *name = getName();
+
+ if (name != NULL) {
+ canvas->setTextOpaque(FALSE);
+ canvas->pushTextSize(size);
+ int w, h;
+ canvas->getTextExtent(name, &w, &h);
+ int y = (r.bottom-r.top - h) / 2;
+// int x = centered ? (r.right-r.left - w) / 2 : TEXTBAR_LEFTMARGIN; //teh old code
+
+ int x = 0;
+ switch (alignment) {
+ default:
+ case TEXTALIGN_LEFT: x = TEXTBAR_LEFTMARGIN; break;
+ case TEXTALIGN_CENTER: x = (r.right-r.left - w) / 2; break;
+ case TEXTALIGN_RIGHT: x = (r.right-r.left - w); break;
+ }
+
+ if (!drawbox && textoutlined) {
+ canvas->setTextColor(bgcolor);
+ canvas->textOut(r.left+x+1, r.top+y+1, getName());
+ canvas->setTextColor(bgcolor);
+ canvas->textOut(r.left+x+1, r.top+y-1, getName());
+ canvas->setTextColor(bgcolor);
+ canvas->textOut(r.left+x-1, r.top+y+1, getName());
+ canvas->setTextColor(bgcolor);
+ canvas->textOut(r.left+x-1, r.top+y-1, getName());
+ } else if (!drawbox && textshadowed) {
+ canvas->setTextColor(bgcolor);
+ canvas->textOut(r.left+x+1, r.top+y+1, getName());
+ }
+ canvas->setTextColor(fgcolor);
+ canvas->textOut(r.left+x, r.top+y, getName());
+ canvas->popTextSize();
+ }
+ return 1;
+}
+
+int TextBar::setTextSize(int newsize) {
+ if (newsize < 1 || newsize > 72) return 0;
+ size = newsize;
+ invalidate();
+ return 1;
+}
+
+int TextBar::setInt(int i) {
+ setName(StringPrintf(i));
+ invalidate();
+ return 1;
+}
+
+void TextBar::onSetName() {
+ TEXTBAR_PARENT::onSetName();
+ invalidate();
+}
+
+int TextBar::getTextWidth() {
+ if (!getName()) return 0;
+ BltCanvas *c = new BltCanvas(10, 10);
+ c->pushTextSize(size);
+ int r = c->getTextWidth(getName());
+ c->popTextSize();
+ delete c;
+ return r+4;
+}
+
+int TextBar::getTextHeight() {
+ return size;
+}
+
+void TextBar::setAlign(TextAlign align) {
+ if (alignment != align) {
+ alignment = align;
+ invalidate();
+ }
+}
+
+TextAlign TextBar::getAlign() {
+ return alignment;
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/textbar.h b/Src/Wasabi/api/wnd/wndclass/textbar.h
new file mode 100644
index 00000000..6c6cb97e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/textbar.h
@@ -0,0 +1,219 @@
+//PORTABLE
+#ifndef _TEXTBAR_H
+#define _TEXTBAR_H
+
+#include <bfc/virtualwnd.h>
+#include <bfc/autobitmap.h>
+#include <bfc/textalign.h>
+
+class CheckWnd;
+
+#define TEXTBAR_PARENT VirtualWnd
+/**
+ TextBar uses the BaseWnd name field of the object as the text
+ to be displayed.
+
+ @short TextBar control.
+ @author Nullsoft
+ @ver 1.0
+ @see LabelWnd
+*/
+class TextBar : public VirtualWnd {
+public:
+ /**
+ Sets the default flags of the TextBar. Defaults to 16px fonts,
+ no background texture, left justified text, shadowed text in
+ the bgcolor, no outline, not box around the text.
+ */
+ TextBar();
+
+ /**
+ Event is triggered when the window requires a repaint.
+ Override this to implement your own behavior.
+
+ Paints the bitmap on canvas according to current
+ options (centering, tiling, stretching, title).
+
+ @ret 0 for failure, 1 for success
+ @param canvas The canvas on which to paint.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ Event is triggered when the name of the window is changed.
+ Override this to implement your own behavior.
+
+ @see BaseWnd::setName()
+ */
+ virtual void onSetName();
+
+ /**
+ Set the text to be displayed to an ascii representation of a numeric value.
+
+ @ret 1.
+ @param i The numeric value to be displayed.
+ */
+ int setInt(int i);
+
+ /**
+ Set the size of the text for the textbar.
+
+ @ret 1, success; 0, failure.
+ @param newsize The new text size, range is from 1 to 72 pixels.
+ */
+ int setTextSize(int newsize);
+
+ /**
+ Get the width of the text displayed, in pixels.
+
+ @ret Width of the displayed text (in pixels).
+ */
+ int getTextWidth();
+
+ /**
+ Get the height of the text displayed, in pixels.
+
+ @ret Height of the displayed text.
+ */
+ int getTextHeight();
+
+ /**
+ Use the base texture when rendering the TextBar?
+ If the base texture is used, it will be rendered as
+ the background of the textbar.
+
+ @param u !0, Use base texture; 0, Do not use base texture;
+ */
+ void setUseBaseTexture(int u);
+
+ /**
+ Event is triggered when the left mouse button is pressed while
+ the textbar has focus. Override this to implement your
+ own behavior.
+
+ @param x X coordinate of the mouse pointer.
+ @param y Y coordinate of the mouse pointer.
+ */
+ virtual int onLeftButtonDown(int x, int y);
+
+ /**
+ Center the text in the textbar? If not,
+ it will be left justified by default.
+
+ @param center !0, Center text; 0, Do not center text;
+ */
+// void setCenter(int center); //old code
+
+ /**
+ Get the center text flag.
+
+ @see setCenter()
+ @ret TRUE, Text is being centered; FALSE, No centering (left justified);
+ */
+// bool getCentered();
+
+ /**
+ Sets the alignment of the text to left, center, or right aligned
+ (possibly more later on, not too sure yet)
+ */
+ void setAlign(TextAlign alignment);
+
+ /**
+ @ret returns the alignment of the text
+ */
+ TextAlign getAlign();
+
+
+ // The following three options have ascending overriding priority --
+
+ /**
+ Sets the shadowed text flag. If enabled, the text will be shadowed
+ with the "bgcolor" value.
+
+ @see getTextShadowed()
+ @param settextshadowed !0, Shadow the text; 0, Do not shadow the text;
+ */
+ void setTextShadowed(int settextshadowed) {
+ textshadowed = !!settextshadowed;
+ }
+
+ /**
+ Get the shadowed text flag. If enabled, the text will be shadowed
+ with the "bgcolor" value.
+
+ @see setTextShadowed()
+ @ret !0, Shadow the text; 0, Do not shadow the text;
+ */
+ int getTextShadowed() {
+ return textshadowed;
+ }
+
+ /**
+ Sets the outline text flag. If enabled, the text will be
+ outlined with the "bgcolor" value.
+
+ @param settextoutlined !0, Outline the text; 0, Do not outline the text;
+ */
+ void setTextOutlined(int settextoutlined) {
+ textoutlined = !!settextoutlined;
+ }
+
+ /**
+ Get the outline text flag. If enabled, the text will be
+ outlined with the "bgcolor" value.
+
+ @ret !0, Outline the text; 0, Do not outline the text;
+ */
+ int getTextOutlined() {
+ return textoutlined;
+ }
+
+ /**
+ Set the drawbox flag. If true, the drawbox flag will cause
+ a box to be drawn around the text in the textbar.
+
+ @param setdrawbox !0, Drawbox around the text; 0, No drawbox;
+ */
+ void setDrawBox(int setdrawbox) {
+ drawbox = !!setdrawbox;
+ }
+
+ /**
+ Get the drawbox flag. If true, the drawbox flag will cause
+ a box to be drawn around the text in the textbar.
+
+ @ret !0, Drawbox around the text; 0, No drawbox;
+ */
+ int getDrawBox() {
+ return drawbox;
+ }
+
+ /**
+ Associate a checkbox with the textbar. When a textbar is linked
+ to a checkbox, it will toggle the checkbox when it receives
+ left clicks.
+
+ @param target A pointer to the CheckWnd to link.
+ */
+ void setAutoToggleCheckWnd(CheckWnd *target) {
+ checkwndtarget = target;
+ }
+
+
+private:
+ int size;
+ int usebt;
+ TextAlign alignment; //i changed this from centered, to a set text alignment thingie
+
+
+ int textshadowed; // display a shadow of the text in bgcolor. default: on
+ int textoutlined; // draw an outline of the text in bgcolor. default: off
+ int drawbox; // draw a box of bgcolor the size of the boundsrect. default: off
+
+ AutoSkinBitmap bgbitmap;
+ CheckWnd *checkwndtarget;
+};
+
+const int TEXTBAR_LEFTMARGIN = 2;
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/tooltip.cpp b/Src/Wasabi/api/wnd/wndclass/tooltip.cpp
new file mode 100644
index 00000000..a619ab45
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/tooltip.cpp
@@ -0,0 +1,47 @@
+//#include <precomp.h>
+#include "./api.h"
+#include <api/wnd/api_wnd.h>
+#include "tooltip.h"
+
+#ifdef WASABI_COMPILE_CONFIG
+#include <api/config/items/attrint.h>
+#include <api/config/items/cfgitem.h>
+#endif
+#include <api/service/svc_enum.h>
+
+Tooltip::Tooltip(const wchar_t *txt)
+{
+ WASABI_API_WND->appdeactivation_push_disallow(NULL);
+ svc = NULL;
+
+ if (!txt || !*txt) return ;
+
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ if (!_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Enable tooltips"))
+ {
+ // tooltips disabled
+ return ;
+ }
+#endif
+
+ waServiceFactory *svf = WASABI_API_SVC->service_enumService(WaSvc::TOOLTIPSRENDERER, 0);
+ svc = castService<svc_toolTipsRenderer>(svf);
+
+ if (!svc)
+ {
+ // no tooltips available!
+ return ;
+ }
+
+ svc->spawnTooltip(txt);
+}
+
+Tooltip::~Tooltip()
+{
+ if (svc != NULL)
+ WASABI_API_SVC->service_release(svc);
+ WASABI_API_WND->appdeactivation_pop_disallow(NULL);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wnd/wndclass/tooltip.h b/Src/Wasabi/api/wnd/wndclass/tooltip.h
new file mode 100644
index 00000000..18122a40
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/tooltip.h
@@ -0,0 +1,18 @@
+#ifndef __TOOLTIP_H
+#define __TOOLTIP_H
+
+#include <api/service/svcs/svc_tooltips.h>
+
+class Tooltip {
+
+ public:
+
+ Tooltip(const wchar_t *txt);
+ virtual ~Tooltip();
+
+ private:
+
+ svc_toolTipsRenderer *svc;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/treewnd.cpp b/Src/Wasabi/api/wnd/wndclass/treewnd.cpp
new file mode 100644
index 00000000..99b03c85
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/treewnd.cpp
@@ -0,0 +1,1645 @@
+#include "precomp.h"
+
+#include "treewnd.h"
+
+#include <tataki/canvas/ifc_canvas.h>
+#include <bfc/stack.h>
+#include <api/wnd/wndclass/scrollbar.h>
+#include <tataki/color/skinclr.h>
+#include <api/wnd/notifmsg.h>
+#include <api/wnd/accessible.h>
+#include <api/wnd/PaintCanvas.h>
+
+#define DEF_TEXT_SIZE 14
+#define CHILD_INDENT itemHeight
+#define X_SHIFT 2
+#define Y_SHIFT 2
+#define DRAG_THRESHOLD 4
+
+#define TIMER_EDIT_DELAY 1000
+#define TIMER_EDIT_ID 1249
+
+///////////////////////////////////////////////////////////////////////////////
+// TreeWnd
+///////////////////////////////////////////////////////////////////////////////
+
+static SkinColor textcolor(L"wasabi.tree.text");
+static SkinColor drophilitecolor(L"wasabi.tree.hiliteddrop");
+static SkinColor selectedcolor(L"wasabi.tree.selected");
+
+int CompareTreeItem::compareItem(TreeItem *p1, TreeItem *p2) {
+ return p1->getTree()->compareItem(p1, p2);
+}
+
+TreeWnd::TreeWnd() {
+ tabClosed = NULL;
+ tabOpen = NULL;
+ linkTopBottom = NULL;
+ linkTopRight = NULL;
+ linkTopRightBottom = NULL;
+ linkTabTopBottom = NULL;
+ linkTabTopRight = NULL;
+ linkTabTopRightBottom = NULL;
+ curSelected = NULL;
+ mousedown_item = NULL;
+ hitItem = NULL;
+ draggedItem = NULL;
+ tipitem = NULL;
+ edited = NULL;
+ editwnd = NULL;
+ metrics_ok = FALSE;
+ setSorted(TRUE);
+ setFontSize(DEF_TEXT_SIZE);
+ redraw = TRUE;
+ prevbdownitem = NULL;
+ autoedit=0;
+ autocollapse=1;
+
+ tabClosed = L"wasabi.tree.tab.closed";
+ tabOpen = L"wasabi.tree.tab.open";
+ linkTopBottom = L"wasabi.tree.link.top.bottom";
+ linkTopRight = L"wasabi.tree.link.top.right";
+ linkTopRightBottom = L"wasabi.tree.link.top.rightBottom";
+ linkTabTopBottom = L"wasabi.tree.link.tab.top.bottom";
+ linkTabTopRight = L"wasabi.tree.link.tab.top.right";
+ linkTabTopRightBottom = L"wasabi.tree.link.tab.top.rightBottom";
+}
+
+TreeWnd::~TreeWnd() {
+ // delete all root items
+ deleteAllItems();
+ drawList.removeAll();
+}
+
+int TreeWnd::onInit() {
+ TREEWND_PARENT::onInit();
+
+ setBgBitmap(L"wasabi.tree.background");
+ setLineHeight(itemHeight);
+
+ return 1;
+}
+
+void TreeWnd::setRedraw(bool r) {
+ int old = redraw;
+ redraw = r;
+ if (!old && redraw)
+ invalidate();
+}
+
+int TreeWnd::onPaint(Canvas *canvas) {
+
+ PaintCanvas paintcanvas;
+ PaintBltCanvas paintbcanvas;
+
+ if (canvas == NULL) {
+ if (needDoubleBuffer()) {
+ if (!paintbcanvas.beginPaintNC(this)) return 0;
+ canvas = &paintbcanvas;
+ } else {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+ }
+ TREEWND_PARENT::onPaint(canvas);
+
+/* uncomment if you add columns or anything that should be not be drawn over by onPaint in which case you'll have to clip->subtract(your_region)
+ api_region *clip = new RegionI();
+ canvas->getClipRgn(clip); */
+
+ /*RECT r;
+ getNonClientRect(&r);
+
+ int y = -getScrollY()+Y_SHIFT+r.top;
+ int x = -getScrollX()+X_SHIFT;*/
+
+ Wasabi::FontInfo fontInfo;
+ fontInfo.color = textcolor;
+ fontInfo.opaque=false;
+ fontInfo.pointSize = getFontSize();
+
+ firstItemVisible = NULL;
+ lastItemVisible = NULL;
+
+ ensureMetricsValid();
+
+ //drawSubItems(canvas, x, &y, items, r.top, r.bottom, 0);
+ drawItems(canvas, &fontInfo);
+
+ canvas->selectClipRgn(NULL); // reset cliping region - NEEDED;
+
+// delete clip; uncomment if necessary
+
+ return 1;
+}
+
+void TreeWnd::drawItems(Canvas *canvas, const Wasabi::FontInfo *fontInfo)
+{
+ RECT r, c, ir;
+ RegionI *orig=NULL;
+ getClientRect(&r);
+ if (!canvas->getClipBox(&c)) {
+ getClientRect(&c);
+ orig = new RegionI(&c);
+ } else
+ orig = new RegionI(canvas);
+
+ int first = ((c.top-r.top) + getScrollY() - Y_SHIFT) / itemHeight;
+ int last = ((c.bottom-r.top) + getScrollY() - Y_SHIFT) / itemHeight + 1;
+ POINT pt;
+ TreeItem *item;
+ bool hastab;
+
+ for (int i=first;i<=last;i++)
+ {
+
+ if (i >= drawList.getNumItems()) break;
+
+ item = drawList[i];
+ if (!item) continue;
+ item->getCurRect(&ir);
+ pt.x = r.left + X_SHIFT+item->getIndent()*itemHeight - getScrollX();//ir.left;
+ pt.y = ir.top;
+
+ // if we need the +/- icon and any of the link lines, draw them
+ if (item->needTab()) {
+// pt.x += itemHeight;
+ RECT _r={pt.x-itemHeight, pt.y, pt.x, pt.y+itemHeight};
+ (item->isCollapsed() ? tabClosed : tabOpen).stretchToRectAlpha(canvas, &_r);
+ hastab=TRUE;
+ } else hastab = FALSE;
+
+ int indent = item->getIndent();
+
+ for (int j=0;j<indent;j++)
+ {
+ RECT _r={pt.x-itemHeight*(j+1), pt.y, pt.x-itemHeight*j, pt.y+itemHeight};
+ int l = getLinkLine(item, j);
+ if (l == (LINK_RIGHT | LINK_TOP)) {
+ ((hastab && j == 0) ? linkTabTopRight : linkTopRight).stretchToRectAlpha(canvas, &_r);
+ }
+ if (l == (LINK_RIGHT | LINK_TOP | LINK_BOTTOM)) {
+ ((hastab && j == 0) ? linkTabTopRightBottom : linkTopRightBottom).stretchToRectAlpha(canvas, &_r);
+ }
+ if (l == (LINK_BOTTOM | LINK_TOP)) {
+ ((hastab && j == 0) ? linkTabTopBottom : linkTopBottom).stretchToRectAlpha(canvas, &_r);
+ }
+ }
+
+ item->customDraw(canvas, pt, itemHeight, (pt.x+getScrollX())-r.left-X_SHIFT, r, fontInfo);
+ }
+
+ delete orig;
+}
+
+TreeItem *TreeWnd::hitTest(int x, int y) {
+ POINT pt={x,y};
+ return hitTest(pt);
+}
+
+TreeItem *TreeWnd::hitTest(POINT pt) {
+ RECT r, ir;
+ getClientRect(&r);
+
+ int first = (getScrollY() - Y_SHIFT) / itemHeight;
+ int last = ((r.bottom-r.top) + getScrollY() - Y_SHIFT) / itemHeight + 1;
+
+ for (int i=first;i<=last;i++) {
+
+ if (i >= drawList.getNumItems()) break;
+
+ TreeItem *item = drawList.enumItem(i);
+
+ if (item) {
+ item->getCurRect(&ir);
+ if (Wasabi::Std::pointInRect(ir, pt) && item->isHitTestable())
+ return item;
+ }
+ }
+
+ return NULL;
+}
+
+void TreeWnd::getMetrics(int *numItemsShown, int *mWidth) {
+ *mWidth=0;
+ *numItemsShown=0;
+ drawList.removeAll();
+ countSubItems(drawList, &items, X_SHIFT, numItemsShown, mWidth, 0);
+}
+
+void TreeWnd::countSubItems(PtrList<TreeItem> &drawlist, TreeItemList *_list, int indent, int *count, int *maxwidth, int z) {
+
+ TreeItemList &list = *_list;
+
+ for (int i=0;i<list.getNumItems();i++) {
+
+ TreeItem *nextitem = list[i];
+
+ int w = nextitem->getItemWidth(itemHeight, indent-X_SHIFT);
+ if (indent+w > *maxwidth) *maxwidth = w+indent;
+
+ int j = indent-(nextitem->needTab() ? itemHeight : 0);
+ int k;
+ k = indent + w;
+
+ nextitem->setCurRect(j, Y_SHIFT+(*count * itemHeight), k, Y_SHIFT+((*count+1) * itemHeight), z);
+ (*count)++;
+
+ drawlist.addItem(nextitem);
+
+ if (nextitem->isExpanded())
+ countSubItems(drawlist, &nextitem->subitems, indent+CHILD_INDENT, count, maxwidth, z+1);
+ }
+}
+
+void TreeWnd::timerCallback(int c) {
+ switch (c) {
+ case TIMER_EDIT_ID:
+ prevbdownitem = NULL;
+ killTimer(TIMER_EDIT_ID);
+ break;
+ default:
+ TREEWND_PARENT::timerCallback(c);
+ }
+}
+
+int TreeWnd::onLeftButtonDown(int x, int y) {
+
+ if (edited)
+ {
+ delete editwnd; editwnd = NULL;
+ endEditLabel(editbuffer);
+ }
+
+ POINT pt={x,y};
+ TreeItem *item = hitTest(pt);
+
+ if (item) {
+ mousedown_item = item;
+ mousedown_anchor.x = pt.x;
+ mousedown_anchor.y = pt.y;
+ mousedown_dragdone = FALSE;
+ // only do expand/collapse if was already selected
+ setCurItem(item, autocollapse?(curSelected == item):0, FALSE);
+ beginCapture();
+ }
+
+ return 1;
+}
+
+int TreeWnd::onLeftButtonUp(int x, int y) {
+ if (getCapture())
+ endCapture();
+ TREEWND_PARENT::onLeftButtonUp(x, y);
+ POINT pt={x,y};
+ TreeItem *item = hitTest(pt);
+ if (autoedit && item == mousedown_item && item == prevbdownitem)
+ setCurItem(item, FALSE, TRUE);
+ else
+ if (autoedit) {
+ prevbdownitem = getCurItem();
+ setTimer(TIMER_EDIT_ID, TIMER_EDIT_DELAY);
+ }
+
+ mousedown_item = NULL;
+ return 1;
+}
+
+int TreeWnd::onRightButtonUp(int x, int y){
+ TREEWND_PARENT::onRightButtonUp(x, y);
+ POINT pos={x,y};
+
+ TreeItem *ti = hitTest(pos);
+ if (ti != NULL) {
+ selectItem(ti);
+ if (onPreItemContextMenu(ti, x, y) == 0) {
+ int ret = ti->onContextMenu(x, y);
+ onPostItemContextMenu(ti, x, y, ret);
+ return ret;
+ }
+ return 1;
+ } else {
+ return onContextMenu(x, y);
+ }
+}
+
+int TreeWnd::onMouseMove(int x, int y) {
+
+ TREEWND_PARENT::onMouseMove(x, y);
+
+ POINT pt={x,y};
+
+ if (mousedown_item) {
+ if (!mousedown_dragdone && (ABS(pt.x - mousedown_anchor.x) > DRAG_THRESHOLD || ABS(pt.y - mousedown_anchor.y) > DRAG_THRESHOLD)) {
+ mousedown_dragdone = TRUE;
+ if (getCapture())
+ endCapture();
+ onBeginDrag(mousedown_item);
+ }
+ }
+ else
+ {
+ TreeItem *item = hitTest(pt);
+ if (item) {
+ if (tipitem != item) {
+ tipitem = item;
+ RECT r;
+ RECT c;
+ getClientRect(&c);
+ item->getCurRect(&r);
+ const wchar_t *tt = item->getTip();
+ if (tt != NULL && *tt != '\0')
+ setLiveTip(tt);
+ else if (r.right > c.right || r.bottom > c.bottom || r.top < c.top || r.left < c.left)
+ setLiveTip(item->getLabel());
+ else
+ setLiveTip(NULL);
+ }
+ } else {
+ setLiveTip(NULL);
+ }
+ }
+
+ return 1;
+}
+
+int TreeWnd::onLeftButtonDblClk(int x, int y) {
+ TreeItem *item = hitTest(x, y);
+ if (item == NULL) return 0;
+ return item->onLeftDoubleClick();
+}
+
+int TreeWnd::onRightButtonDblClk(int x, int y) {
+ TreeItem *item = hitTest(x, y);
+ if (item == NULL) return 0;
+ return item->onRightDoubleClick();
+}
+
+void TreeWnd::setLiveTip(const wchar_t *tip)
+{
+ if (!tip)
+ {
+ setTip(oldtip);
+ oldtip = L"";
+ return;
+ }
+ oldtip = TREEWND_PARENT::getTip();
+ setTip(tip);
+}
+
+int TreeWnd::onBeginDrag(TreeItem *treeitem)
+{
+ wchar_t title[WA_MAX_PATH]=L"";
+ // item calls addDragItem()
+ if (!treeitem->onBeginDrag(title)) return 0;
+ ASSERT(draggedItem == NULL);
+ draggedItem = treeitem;
+ if (*title != 0) setSuggestedDropTitle(title);
+ handleDrag();
+ return 1;
+}
+
+int TreeWnd::dragEnter(ifc_window *sourceWnd) {
+ // uh... we don't know yet, but we can accept drops in general
+ hitItem = NULL;
+ return 1;
+}
+
+int TreeWnd::dragOver(int x, int y, ifc_window *sourceWnd) {
+ POINT pos={x,y};
+ screenToClient(&pos);
+ TreeItem *prevItem;
+
+ prevItem = hitItem;
+ hitItem = hitTest(pos);
+
+ // no dropping on yourself! :)
+ if (hitItem == draggedItem) hitItem = NULL;
+
+ // unselect previous item
+ if (prevItem != hitItem && prevItem != NULL) {
+ unhiliteDropItem(prevItem);
+ repaint(); // commit invalidation of unhilited item so no trouble with scrolling
+ prevItem->dragLeave(sourceWnd);
+ }
+
+
+ RECT r;
+ getClientRect(&r);
+ if (pos.y < r.top + 16) {
+ if (getScrollY() >= 0) {
+ scrollToY(MAX(0, getScrollY()-itemHeight));
+ }
+ } else if (pos.y > r.bottom - 16) {
+ if (getScrollY() < getMaxScrollY()) {
+ scrollToY(MIN(getMaxScrollY(), getScrollY()+itemHeight));
+ }
+ }
+
+ if (hitItem != NULL) {
+ // hilight it
+ if (prevItem != hitItem) {
+ hiliteDropItem(hitItem);
+ repaint(); // commit invalidation of hilited so no trouble with scrolling
+ }
+ }
+
+ if (hitItem == NULL) return defaultDragOver(x, y, sourceWnd);
+
+ // ask the item if it can really accept such a drop
+ return hitItem->dragOver(sourceWnd);
+}
+
+int TreeWnd::dragLeave(ifc_window *sourceWnd) {
+ if (hitItem != NULL) {
+ unhiliteDropItem(hitItem);
+ hitItem->dragLeave(sourceWnd);
+ }
+ hitItem = NULL;
+ return 1;
+}
+
+int TreeWnd::dragDrop(ifc_window *sourceWnd, int x, int y) {
+ int res;
+ if (hitItem == NULL) return defaultDragDrop(sourceWnd, x, y);
+ // unhilite the dest
+ unhiliteDropItem(hitItem);
+ // the actual drop
+ res = hitItem->dragDrop(sourceWnd);
+ if (res) {
+ onItemRecvDrop(hitItem);
+ }
+ hitItem = NULL;
+ return res;
+}
+
+int TreeWnd::dragComplete(int success) {
+ int ret;
+ ASSERT(draggedItem != NULL);
+ ret = draggedItem->dragComplete(success);
+ draggedItem = NULL;
+ return ret;
+}
+
+void TreeItem::setTip(const wchar_t *tip)
+{
+ tooltip = tip;
+}
+
+const wchar_t *TreeItem::getTip()
+{
+ return tooltip;
+}
+
+void TreeWnd::hiliteDropItem(TreeItem *item) {
+ if (item)
+ item->setHilitedDrop(TRUE);
+}
+
+void TreeWnd::hiliteItem(TreeItem *item) {
+ if (item)
+ item->setHilited(TRUE);
+}
+
+void TreeWnd::selectItem(TreeItem *item) {
+ setCurItem(item, FALSE);
+}
+
+void TreeWnd::selectItemDeferred(TreeItem *item) {
+ postDeferredCallback(DC_SETITEM, (intptr_t)item);
+}
+
+void TreeWnd::delItemDeferred(TreeItem *item) {
+ postDeferredCallback(DC_DELITEM, (intptr_t)item);
+}
+
+void TreeWnd::unhiliteItem(TreeItem *item) {
+ if (item)
+ item->setHilited(FALSE);
+}
+
+void TreeWnd::unhiliteDropItem(TreeItem *item) {
+ if (item)
+ item->setHilitedDrop(FALSE);
+}
+
+void TreeWnd::setCurItem(TreeItem *item, bool expandCollapse, bool editifselected) {
+ if (curSelected && curSelected != item) {
+ onDeselectItem(curSelected);
+ curSelected->setSelected(FALSE);
+ }
+ if (item) {
+ curSelected = item;
+ onSelectItem(curSelected);
+ item->setSelected(TRUE, expandCollapse, editifselected);
+ setSlidersPosition();
+ }
+}
+
+// Returns the current tree width in pixels
+int TreeWnd::getContentsWidth() {
+ ensureMetricsValid();
+ return maxWidth;
+}
+
+// Returns the current tree height in pixels
+int TreeWnd::getContentsHeight() {
+ ensureMetricsValid();
+ return maxHeight;
+}
+
+void TreeWnd::ensureMetricsValid() {
+ if (metrics_ok) return;
+ int n;
+ getMetrics(&n, &maxWidth);
+ maxWidth += X_SHIFT*2;
+ maxHeight = n*itemHeight+Y_SHIFT*2;
+ metrics_ok = TRUE;
+ setSlidersPosition();
+}
+
+// Gets notification from sliders
+int TreeWnd::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
+ switch (msg) {
+ case ChildNotify::EDITWND_ENTER_PRESSED:
+ if (child == editwnd && editwnd != NULL) {
+ endEditLabel(editbuffer);
+ return 1;
+ }
+ break;
+ case ChildNotify::EDITWND_CANCEL_PRESSED:
+ if (child == editwnd && editwnd != NULL) {
+ cancelEditLabel();
+ return 1;
+ }
+ break;
+ case ChildNotify::EDITWND_DATA_MODIFIED:
+ if (child == editwnd && editwnd != NULL) {
+ editUpdate();
+ return 1;
+ }
+ break;
+ }
+
+ return TREEWND_PARENT::childNotify(child, msg, param1, param2);
+}
+
+void TreeWnd::editUpdate() {
+ ASSERT(edited != NULL && editwnd != NULL);
+ if (!edited || !editwnd) return;
+ int w = editwnd->getTextLength()+16;
+ RECT i, r, e;
+ edited->getCurRect(&i);
+ getClientRect(&r);
+ editwnd->getClientRect(&e);
+ e.left += i.left;
+ e.right += i.left;
+ e.top += i.top;
+ e.bottom += i.top;
+ e.right = i.left+w;
+ e.right = MIN<int>(r.right - X_SHIFT, e.right);
+ editwnd->resize(&e);
+ editwnd->invalidate();
+}
+
+TreeItem *TreeWnd::addTreeItem(TreeItem *item, TreeItem *par, int _sorted, int haschildtab) {
+
+ ASSERT(item != NULL);
+ ASSERTPR(item->getTree() == NULL, "can't transplant TreeItems");
+ ASSERTPR(item->getLabel() != NULL, "tree items must have a label to be inserted");
+
+ item->setSorted(_sorted);
+ item->setChildTab(haschildtab ? TAB_AUTO : TAB_NO/*&& par != NULL*/);
+ item->setTree(this);
+ item->linkTo(par);
+
+ if (par == NULL)
+ items.addItem(item);
+
+ all_items.addItem(item);
+
+ metrics_ok = FALSE;
+
+ if (redraw)
+ invalidate();
+
+ item->onTreeAdd();
+
+ return item;
+}
+
+int TreeWnd::removeTreeItem(TreeItem *item) {
+ ASSERT(item != NULL);
+ ASSERT(item->getTree() == this);
+ if (item->isSelected()) item->setSelected(FALSE);
+ if (curSelected == item) curSelected = NULL;
+//CUT item->deleteSubitems();
+ TreeItem *par = item->getParent();
+ if (!par) { // is root item ?
+ ASSERT(items.haveItem(item));
+ items.removeItem(item);
+ } else {
+ if (!par->removeSubitem(item))
+ return 0;
+ }
+ all_items.removeItem(item);
+ metrics_ok = FALSE;
+ drawList.removeItem(item);
+ if (redraw)
+ invalidate();
+
+ item->setTree(NULL);
+ item->onTreeRemove();
+
+ if (par != NULL) par->onChildItemRemove(item);
+
+ return 1;
+}
+
+void TreeWnd::moveTreeItem(TreeItem *item, TreeItem *newparent) {
+ ASSERT(item != NULL);
+ ASSERTPR(item->getTree() == this, "can't move between trees (fucks up Freelist)");
+ removeTreeItem(item);
+ addTreeItem(item, newparent, item->subitems.getAutoSort(), item->childTab);
+}
+
+void TreeWnd::deleteAllItems() {
+ bool save_redraw = redraw;
+ setRedraw(FALSE);
+
+ TreeItem *item;
+ while ((item = enumRootItem(0)) != NULL)
+ delete item;
+
+ setRedraw(save_redraw);
+}
+
+void TreeWnd::setSorted(bool dosort) {
+ items.setAutoSort(dosort);
+}
+
+bool TreeWnd::getSorted() {
+ return items.getAutoSort();
+}
+
+void TreeWnd::sortTreeItems() {
+ items.sort(TRUE);
+ metrics_ok = FALSE;
+ if (redraw)
+ invalidate();
+}
+
+TreeItem *TreeWnd::getSibling(TreeItem *item) {
+ for (int i=0;i<items.getNumItems();i++) {
+ if (items[i] == item) {
+ if (i == items.getNumItems()-1) return NULL;
+ return items[i+1];
+ }
+ }
+ return NULL;
+}
+
+void TreeWnd::setAutoCollapse(bool doautocollase) {
+ autocollapse=doautocollase;
+}
+
+int TreeWnd::onContextMenu(int x, int y) {
+ POINT pos={x,y};
+ screenToClient(&pos);
+ TreeItem *ti = hitTest(pos);
+ if (ti != NULL) {
+ selectItem(ti);
+ return ti->onContextMenu(x, y);
+ }
+ return 0;
+}
+
+int TreeWnd::onDeferredCallback(intptr_t param1, intptr_t param2) {
+ switch (param1) {
+ case DC_SETITEM:
+ setCurItem((TreeItem *)param2, FALSE);
+ return 1;
+ case DC_DELITEM:
+ delete (TreeItem *)param2;
+ return 1;
+ case DC_EXPAND:
+ expandItem((TreeItem *)param2);
+ return 1;
+ case DC_COLLAPSE:
+ collapseItem((TreeItem *)param2);
+ return 1;
+ }
+ return 0;
+}
+
+int TreeWnd::getNumRootItems() {
+ return items.getNumItems();
+}
+
+TreeItem *TreeWnd::enumRootItem(int which) {
+ return items[which];
+}
+
+void TreeWnd::invalidateMetrics() {
+ metrics_ok = FALSE;
+}
+
+int TreeWnd::getLinkLine(TreeItem *item, int level) {
+
+ ASSERT(item != NULL);
+
+ int l = 0;
+ int r = 0;
+
+ if (item->parent == NULL)
+ return 0;
+
+ TreeItem *cur=item;
+
+ while (cur->getParent() && l < level) {
+ cur = cur->getParent();
+ l++;
+ }
+
+ if (cur->getSibling()) r |= LINK_BOTTOM | LINK_TOP;
+ if (level == 0) r |= LINK_RIGHT;
+ if (level == 0 && cur->getParent()) r |= LINK_TOP;
+
+ return r;
+
+}
+
+int TreeWnd::onMouseWheelDown(int clicked, int lines) {
+ if (!clicked)
+ scrollToY(MIN(getMaxScrollY(), getScrollY()+itemHeight));
+ else
+ scrollToX(MIN(getMaxScrollX(), getScrollX()+itemHeight));
+ return 1;
+}
+
+int TreeWnd::onMouseWheelUp(int clicked, int lines) {
+ if (!clicked)
+ scrollToY(MAX(0, getScrollY()-itemHeight));
+ else
+ scrollToX(MAX(0, getScrollX()-itemHeight));
+ return 1;
+}
+
+int TreeWnd::expandItem(TreeItem *item) {
+ ASSERT(item != NULL);
+
+ return item->expand();
+}
+
+void TreeWnd::expandItemDeferred(TreeItem *item) {
+ postDeferredCallback(DC_EXPAND, (intptr_t)item);
+}
+
+int TreeWnd::collapseItem(TreeItem *item) {
+ ASSERT(item != NULL);
+
+ return item->collapse();
+}
+
+void TreeWnd::collapseItemDeferred(TreeItem *item) {
+ postDeferredCallback(DC_COLLAPSE, (intptr_t)item);
+}
+
+TreeItem *TreeWnd::getCurItem() {
+ return curSelected;
+}
+
+int TreeWnd::getItemRect(TreeItem *item, RECT *r) {
+ ASSERT(item != NULL);
+
+ return item->getCurRect(r);
+}
+
+void TreeWnd::editItemLabel(TreeItem *item) {
+
+ if (edited) {
+ edited->setEdition(FALSE);
+ edited->invalidate();
+ }
+
+
+ ASSERT(item != NULL);
+ if (item == NULL) return;
+
+ if (item->onBeginLabelEdit()) return;
+ item->setEdition(TRUE);
+ edited = item;
+
+ editwnd = new EditWnd();
+ editwnd->setModal(TRUE);
+ editwnd->setAutoSelect(TRUE);
+ editwnd->setStartHidden(TRUE);
+ editwnd->init(getOsModuleHandle(), getOsWindowHandle());
+ editwnd->setParent(this);
+ RECT r;
+ edited->getCurRect(&r);
+ RECT cr;
+ getClientRect(&cr);
+ r.right = cr.right;
+ if (r.bottom - r.top < 24) r.bottom = r.top + 24;
+ editwnd->resize(&r);
+ wcsncpy(editbuffer, edited->getLabel(), 256);
+ editwnd->setBuffer(editbuffer, 255);
+ editUpdate();
+ editwnd->setVisible(TRUE);
+}
+
+void TreeWnd::endEditLabel(const wchar_t *newlabel)
+{
+ editwnd = NULL; // editwnd self destructs
+ if (edited->onEndLabelEdit(newlabel))
+ edited->setLabel(newlabel);
+ edited->setEdition(FALSE);
+ edited->invalidate();
+ onLabelChange(edited);
+ edited = NULL;
+ invalidateMetrics();
+ setSlidersPosition();
+}
+
+void TreeWnd::cancelEditLabel(int destroyit) {
+ ASSERT(edited != NULL);
+ if (!edited) return;
+
+ if (destroyit)
+ delete editwnd;
+
+ editwnd = NULL; // editwnd self destructs (update> except if destroyit for cancelling from treewnd)
+ edited->setEdition(FALSE);
+ edited->invalidate();
+ edited = NULL;
+}
+
+void TreeWnd::setAutoEdit(int ae) {
+ autoedit = ae;
+}
+
+int TreeWnd::getAutoEdit() {
+ return autoedit;
+}
+
+TreeItem *TreeWnd::getByLabel(TreeItem *item, const wchar_t *name)
+{
+ TreeItem *ti;
+ // handle root-level searching
+ if (item == NULL) {
+ int n = getNumRootItems();
+ for (int i = 0; i < n; i++) {
+ ti = enumRootItem(i);
+ if (!wcscmp(name, ti->getLabel())) return ti;
+ ti = getByLabel(ti, name);
+ if (ti) return ti;
+ }
+ return NULL;
+ }
+
+ // check the given item
+ if (!wcscmp(name, item->getLabel())) return item;
+
+ // depth first search
+ ti = item->getChild();
+ if (ti != NULL) {
+ ti = getByLabel(ti, name);
+ if (ti != NULL) return ti;
+ }
+
+ // recursively check siblings
+ ti = item->getSibling();
+ if (ti != NULL) ti = getByLabel(ti, name);
+
+ return ti;
+}
+
+int TreeWnd::onGetFocus() {
+ int r = TREEWND_PARENT::onGetFocus();
+
+#if 0
+DebugString("yay got focus");
+ TreeItem *ti = getCurItem();
+ if (ti != NULL) {
+ ti->setSelected(FALSE);
+ selectItemDeferred(ti);
+ }
+#endif
+
+ return r;
+}
+
+int TreeWnd::onKillFocus() {
+
+ TREEWND_PARENT::onKillFocus();
+ mousedown_item=NULL;
+/* if (edited)
+ cancelEditLabel();*/
+#if 0
+DebugString("no mo focus");
+#endif
+
+ return 1;
+}
+
+int TreeWnd::onChar(unsigned int c)
+{
+ int r = 0;
+
+ if (c == 27) {
+ if (edited)
+ cancelEditLabel(1);
+ }
+
+ if (curSelected != NULL && (r = curSelected->onChar(c)) != 0) return r;
+
+ wchar_t b = TOUPPERW(c);
+ if (b >= 'A' && b <= 'Z')
+ {
+ jumpToNext(b);
+ r = 1;
+ }
+
+ return r ? r : TREEWND_PARENT::onChar(c);
+}
+
+int TreeWnd::getNumVisibleChildItems(TreeItem *c) {
+ int nb=0;
+ for(int i=0;i<c->getNumChildren();i++) {
+ TreeItem *t=c->getNthChild(i);
+ if(t->hasSubItems() && t->isExpanded())
+ nb+=getNumVisibleChildItems(t);
+ nb++;
+ }
+ return nb;
+}
+
+int TreeWnd::getNumVisibleItems() {
+ int nb=0;
+ for(int i=0;i<items.getNumItems();i++) {
+ TreeItem *t=items.enumItem(i);
+ if(t->hasSubItems() && t->isExpanded())
+ nb+=getNumVisibleChildItems(t);
+ nb++;
+ }
+ return nb;
+}
+
+TreeItem *TreeWnd::enumVisibleChildItems(TreeItem *c, int n) {
+ int nb=0;
+ for(int i=0;i<c->getNumChildren();i++) {
+ TreeItem *t=c->getNthChild(i);
+ if(nb==n) return t;
+ if(t->hasSubItems() && t->isExpanded()) {
+ TreeItem *t2=enumVisibleChildItems(t, n-nb-1);
+ if(t2) return t2;
+ nb+=getNumVisibleChildItems(t);
+ }
+ nb++;
+ }
+ return NULL;
+}
+
+TreeItem *TreeWnd::enumVisibleItems(int n) {
+ int nb=0;
+ for(int i=0;i<items.getNumItems();i++) {
+ TreeItem *t=items.enumItem(i);
+ if(nb==n) return t;
+ if(t->hasSubItems() && t->isExpanded()) {
+ TreeItem *t2=enumVisibleChildItems(t, n-nb-1);
+ if(t2) return t2;
+ nb+=getNumVisibleChildItems(t);
+ }
+ nb++;
+ }
+ return NULL;
+}
+
+int TreeWnd::findChildItem(TreeItem *c, TreeItem *i, int *nb) {
+ for(int j=0;j<c->getNumChildren();j++) {
+ TreeItem *t=c->getNthChild(j); (*nb)++;
+ if (t == i) return *nb;
+ if(t->hasSubItems() && t->isExpanded()) {
+ int n = findChildItem(t, i, nb);
+ if (n != -1) return *nb;
+ }
+ }
+ return -1;
+}
+
+int TreeWnd::findItem(TreeItem *i) {
+ int nb=-1;
+ for(int j=0;j<items.getNumItems();j++) {
+ TreeItem *t=items.enumItem(j); nb++;
+ if (t == i) return nb;
+ if(t->hasSubItems() && t->isExpanded()) {
+ int n = findChildItem(t, i, &nb);
+ if (n != -1) return nb;
+ }
+ }
+ return -1;
+}
+
+
+TreeItem *TreeWnd::enumAllItems(int n) {
+ return all_items[n];
+}
+
+int TreeWnd::onKeyDown(int keycode)
+{
+ switch(keycode)
+ {
+ case 113: {
+ TreeItem *item = getCurItem();
+ if (item)
+ item->editLabel();
+ return 1;
+ }
+ case STDKEY_UP: {
+ TreeItem *t=getCurItem();
+ int l=getNumVisibleItems();
+ if (t == NULL) {
+ if (l > 0) setCurItem(enumVisibleItems(getNumVisibleItems()-1), FALSE, FALSE);
+ } else {
+ for(int i=0;i<l;i++)
+ if(enumVisibleItems(i)==t) {
+ if(i-1>=0) {
+ TreeItem *t2=enumVisibleItems(i-1);
+ if(t2) setCurItem(t2,FALSE,FALSE);
+ }
+ }
+ }
+ return 1;
+ }
+ case STDKEY_DOWN: {
+ TreeItem *t=getCurItem();
+ int l=getNumVisibleItems();
+ if (t == NULL) {
+ if (l > 0) setCurItem(enumVisibleItems(0), FALSE, FALSE);
+ } else {
+ for(int i=0;i<l;i++)
+ if(enumVisibleItems(i)==t) {
+ TreeItem *t2=enumVisibleItems(i+1);
+ if(t2) setCurItem(t2,FALSE,FALSE);
+ }
+ }
+ return 1;
+ }
+ case VK_PRIOR: {
+ TreeItem *t=getCurItem();
+ int l=getNumVisibleItems();
+ for(int i=0;i<l;i++)
+ if(enumVisibleItems(i)==t) {
+ int a=MAX(i-5,0);
+ TreeItem *t2=enumVisibleItems(a);
+ if(t2) setCurItem(t2,FALSE,FALSE);
+ }
+ return 1;
+ }
+ case VK_NEXT: {
+ TreeItem *t=getCurItem();
+ int l=getNumVisibleItems();
+ for(int i=0;i<l;i++)
+ if(enumVisibleItems(i)==t) {
+ int a=MIN(i+5,l-1);
+ TreeItem *t2=enumVisibleItems(a);
+ if(t2) setCurItem(t2,FALSE,FALSE);
+ }
+ return 1;
+ }
+ case STDKEY_HOME: {
+ TreeItem *t=enumVisibleItems(0);
+ if(t) setCurItem(t,FALSE,FALSE);
+ return 1;
+ }
+ case STDKEY_END: {
+ TreeItem *t=enumVisibleItems(getNumVisibleItems()-1);
+ if(t) setCurItem(t,FALSE,FALSE);
+ return 1;
+ }
+ case STDKEY_LEFT: {
+ TreeItem *t=getCurItem();
+ if(t) t->collapse();
+ return 1;
+ }
+ case STDKEY_RIGHT: {
+ TreeItem *t=getCurItem();
+ if(t) t->expand();
+ return 1;
+ }
+ }
+
+ return TREEWND_PARENT::onKeyDown(keycode);
+}
+
+void TreeWnd::jumpToNext(wchar_t c) {
+ firstFound=FALSE;
+ if (jumpToNextSubItems(&items, c)) return;
+ firstFound=TRUE;
+ jumpToNextSubItems(&items, c);
+}
+
+int TreeWnd::jumpToNextSubItems(TreeItemList *list, wchar_t c) {
+
+ for (int i=0;i<list->getNumItems();i++) {
+
+ TreeItem *nextitem = list->enumItem(i);
+ const wchar_t *l = nextitem->getLabel();
+ wchar_t b = l ? TOUPPERW(*l) : 0;
+ if (b == c && firstFound)
+ {
+ selectItem(nextitem);
+ nextitem->ensureVisible();
+ return 1;
+ }
+
+ if (nextitem->isSelected()) firstFound = TRUE;
+
+ if (nextitem->isExpanded())
+ if (jumpToNextSubItems(&nextitem->subitems, c)) return 1;
+ }
+ return 0;
+}
+
+void TreeWnd::ensureItemVisible(TreeItem *item) {
+ ASSERT(item != NULL);
+
+ // walk the parent tree to make sure item is visible
+ for (TreeItem *cur = item->getParent(); cur; cur = cur->getParent()) {
+ if (cur->isCollapsed()) cur->expand();
+ }
+
+ RECT r;
+ RECT c;
+ item->getCurRect(&r);
+ getClientRect(&c);
+ if (r.top < c.top || r.bottom > c.bottom) {
+ if (r.top + (c.bottom - c.top) <= getContentsHeight())
+ scrollToY(r.top);
+ else {
+ scrollToY(getContentsHeight()-(c.bottom-c.top));
+ }
+ }
+}
+
+void TreeWnd::setHilitedColor(const wchar_t *colorname) {
+ // we have to store it in a String because SkinColor does not make a copy
+ hilitedColorName = colorname;
+ hilitedColor = hilitedColorName;
+}
+
+ARGB32 TreeWnd::getHilitedColor() {
+ return hilitedColor;
+}
+
+int TreeWnd::compareItem(TreeItem *p1, TreeItem *p2)
+{
+ int r = wcscmp(p1->getLabel(), p2->getLabel());
+ if (r == 0) return CMP3(p1, p2);
+ return r;
+}
+
+int TreeWnd::setFontSize(int newsize)
+{
+ TREEWND_PARENT::setFontSize(newsize);
+ if (newsize >= 0) textsize = newsize;
+ TextInfoCanvas c(this);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = getFontSize();
+ itemHeight = c.getTextHeight(&fontInfo);
+ redraw = 1;
+ metrics_ok = 0;
+ invalidate();
+ return 1;
+}
+
+int TreeWnd::getFontSize() {
+#ifndef WASABINOMAINAPI
+ return textsize + api->metrics_getDelta();
+#else
+ //MULTIAPI-FIXME: not handling delta
+ return textsize;
+#endif
+}
+
+
+void TreeWnd::onSelectItem(TreeItem *i) {
+ Accessible *a = getAccessibleObject();
+ if (a != NULL)
+ a->onGetFocus(findItem(i));
+}
+
+void TreeWnd::onDeselectItem(TreeItem *i) {
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// TreeItem
+////////////////////////////////////////////////////////////////////////////////////
+
+TreeItem::TreeItem(const wchar_t *label) {
+ parent=NULL;
+ MEMZERO(&curRect, sizeof(RECT));
+ childTab = TAB_AUTO;
+ tree = NULL;
+ expandStatus = STATUS_COLLAPSED;
+ icon = NULL;
+ _z = 0;
+
+ if (label != NULL)
+ setLabel(label);
+
+ selected = FALSE;
+ hilitedDrop = FALSE;
+ hilited = FALSE;
+ being_edited = FALSE;
+
+ setSorted(TRUE);
+}
+
+TreeItem::~TreeItem() {
+ // the subitem will call parent tree which will remove item from our list
+ deleteSubitems();
+
+ // remove from parent tree
+ if (tree) tree->removeTreeItem(this);
+
+ delete icon;
+}
+
+void TreeItem::deleteSubitems() {
+ while (subitems.getNumItems() > 0) {
+ delete subitems.enumItem(0);
+ }
+}
+
+void TreeItem::setSorted(int issorted) {
+ subitems.setAutoSort(!!issorted);
+}
+
+void TreeItem::setChildTab(int haschildtab) {
+ childTab = haschildtab;
+}
+
+void TreeItem::linkTo(TreeItem *par) {
+ parent = par;
+
+ if (par == NULL) return;
+
+ par->addSubItem(this);
+}
+
+void TreeItem::addSubItem(TreeItem *item) {
+ subitems.addItem(item);
+}
+
+int TreeItem::removeSubitem(TreeItem *item) {
+ if (subitems.searchItem(item) == -1) return 0;
+ subitems.removeItem(item);
+ if (tree->redraw)
+ tree->invalidate();
+ return 1;
+}
+
+TreeItem *TreeItem::getChild() {
+ return subitems.getFirst();
+}
+
+TreeItem *TreeItem::getChildSibling(TreeItem *item) { // locate item in children and return its sibling
+ for (int i=0;i<subitems.getNumItems();i++) {
+ if (subitems.enumItem(i) == item) {
+ if (i == subitems.getNumItems()-1) return NULL;
+ return subitems.enumItem(i+1);
+ }
+ }
+return NULL;
+}
+
+TreeItem *TreeItem::getSibling() { // returns next item
+ if (!parent)
+ return tree->getSibling(this);
+ else
+ return parent->getChildSibling(this);
+}
+
+void TreeItem::setTree(TreeWnd *newtree) {
+ tree = newtree;
+ // recursively reset tree for children, if any
+ for (int i = 0; ; i++) {
+ TreeItem *item = getNthChild(i);
+ if (item == NULL) break;
+ item->setTree(tree);
+ }
+}
+
+void TreeItem::ensureVisible()
+{
+ if (tree) tree->ensureItemVisible(this);
+}
+
+const wchar_t *TreeItem::getLabel()
+{
+ return label;
+}
+
+void TreeItem::setLabel(const wchar_t *newlabel)
+{
+ label = newlabel;
+ if (newlabel) {
+ if (tree)
+ tree->invalidateMetrics();
+ invalidate();
+ }
+}
+
+int TreeItem::customDraw(Canvas *canvas, const POINT &pt, int txtHeight, int indentation, const RECT &clientRect, const Wasabi::FontInfo *fontInfo)
+{
+ if (being_edited) return 0;
+
+ SkinBitmap *icon = getIcon();
+
+ int cw = clientRect.right - clientRect.left;
+
+ int iconw = MIN(icon ? icon->getWidth() : 0, cw);
+
+ if (isSelected() || isHilitedDrop())
+ {
+ RECT r;
+ r.left = pt.x;
+ r.top = pt.y;
+ //r.right = r.left + canvas->getTextWidth(label)+2+(icon ? txtHeight : 0);
+ r.right = r.left + canvas->getTextWidth(label, fontInfo)+2+iconw;
+ r.bottom = r.top + txtHeight;
+ canvas->fillRect(&r, isHilitedDrop() ? drophilitecolor : selectedcolor);
+ }
+
+ if (isHilited())
+ {
+ RECT r;
+ r.left = pt.x;
+ r.top = pt.y;
+ //r.right = r.left + canvas->getTextWidth(label)+2+(icon ? txtHeight : 0);
+ r.right = r.left + canvas->getTextWidth(label, fontInfo)+2+iconw;
+ r.bottom = r.top + txtHeight;
+ canvas->drawRect(&r, 1, tree->getHilitedColor());
+ }
+
+ POINT d=pt;
+
+ if (icon) {
+ RECT i;
+ i.left = pt.x+1;
+ i.right = i.left + iconw;
+// i.top = pt.y+1;
+ int lh = MIN(icon->getHeight(), txtHeight);
+ i.top = pt.y + (txtHeight - lh) / 2;
+// i.bottom = i.top + txtHeight-2;
+ i.bottom = i.top + lh;
+ icon->stretchToRectAlpha(canvas, &i);
+ //d.x += txtHeight;
+ d.x += icon->getWidth();
+ }
+
+ canvas->textOut(d.x+1, d.y, label, fontInfo);
+
+ return canvas->getTextWidth(label, fontInfo)+2+iconw;
+}
+
+int TreeItem::getItemWidth(int txtHeight, int indentation) {
+ SkinBitmap *icon = getIcon();
+ if (!label) return (icon ? txtHeight : 0);
+ TextInfoCanvas c(tree);
+ Wasabi::FontInfo fontInfo;
+ fontInfo.pointSize = getTree()->getFontSize();
+ int width = c.getTextWidth(label, &fontInfo)+2;
+ width += (icon ? txtHeight : 0);
+ return width;
+}
+
+int TreeItem::getNumChildren() {
+ return subitems.getNumItems();
+}
+
+TreeItem *TreeItem::getNthChild(int nth) {
+ if (nth >= subitems.getNumItems()) return NULL;
+ return subitems.enumItem(nth);
+}
+
+void TreeItem::setCurRect(int x1, int y1, int x2, int y2, int z) {
+ curRect.left = x1;
+ curRect.right = x2;
+ curRect.top = y1;
+ curRect.bottom = y2;
+ _z = z;
+}
+
+int TreeItem::getIndent() {
+ return _z;
+}
+
+bool TreeItem::hasSubItems() {
+ return subitems.getNumItems()>0;
+}
+
+bool TreeItem::needTab() {
+ return (childTab == TAB_YES || (childTab == TAB_AUTO && hasSubItems()));
+}
+
+bool TreeItem::isExpanded() {
+ if (!hasSubItems()) return FALSE;
+ return expandStatus == STATUS_EXPANDED;
+}
+
+bool TreeItem::isCollapsed() {
+ if (!hasSubItems()) return TRUE;
+ return expandStatus == STATUS_COLLAPSED;
+}
+
+int TreeItem::getCurRect(RECT *r) {
+ r->left = curRect.left-tree->getScrollX();
+ r->top = curRect.top-tree->getScrollY();
+ r->right = curRect.right-tree->getScrollX();
+ r->bottom = curRect.bottom-tree->getScrollY();
+ RECT c;
+ tree->getClientRect(&c);
+ r->top += c.top;
+ r->bottom += c.top;
+ r->left += c.left;
+ r->right += c.left;
+ return 1;
+}
+
+TreeWnd *TreeItem::getTree() const {
+ return tree;
+}
+
+void TreeItem::setSelected(bool isSelected, bool expandCollapse, bool editifselected) {
+ bool wasselected = selected;
+ selected = !!isSelected;
+
+ if (selected != wasselected) {
+ invalidate();
+ tree->repaint();
+ if (selected) {
+ onSelect();
+ ASSERT(tree != NULL);
+ tree->onItemSelected(this);
+ } else {
+ onDeselect();
+ ASSERT(tree != NULL);
+ tree->onItemDeselected(this);
+ }
+ } else {
+ if (selected && editifselected) {
+ editLabel();
+ }
+ }
+
+ if (expandCollapse) {
+ if (isCollapsed())
+ expand();
+ else
+ collapse();
+ }
+}
+
+void TreeItem::invalidate() {
+ if (tree) {
+ RECT r;
+ getCurRect(&r);
+ tree->invalidateRect(&r);
+ }
+}
+
+bool TreeItem::isSelected() {
+ return selected;
+}
+
+int TreeItem::collapse() {
+ int old = expandStatus;
+
+ if (hasSubItems()) {
+ if (expandStatus == STATUS_COLLAPSED)
+ return 0;
+ expandStatus = STATUS_COLLAPSED;
+ RECT c;
+ tree->getClientRect(&c);
+ RECT r;
+ getCurRect(&r);
+ r.bottom = c.bottom;
+ r.left = c.left;
+ r.right = c.right;
+ if (tree) {
+ tree->invalidateRect(&r);
+ tree->invalidateMetrics();
+ }
+ }
+
+ onCollapse();
+
+ return old != expandStatus;
+}
+
+int TreeItem::expand() {
+ int old = expandStatus;
+
+ if (hasSubItems()) {
+ if (expandStatus == STATUS_EXPANDED)
+ return 0;
+ expandStatus = STATUS_EXPANDED;
+ RECT c;
+ tree->getClientRect(&c);
+ RECT r;
+ getCurRect(&r);
+ r.bottom = c.bottom;
+ r.left = c.left;
+ r.right = c.right;
+ if (tree) {
+ tree->invalidateRect(&r);
+ tree->invalidateMetrics();
+ }
+ }
+
+ onExpand();
+
+ return old != expandStatus;
+}
+
+int TreeItem::onContextMenu(int x, int y) {
+ return 0;
+}
+
+void TreeItem::setHilitedDrop(bool ishilitedDrop) {
+ bool washilighted = hilitedDrop;
+ hilitedDrop = !!ishilitedDrop;
+
+ if (washilighted != hilitedDrop)
+ invalidate();
+}
+
+void TreeItem::setHilited(bool ishilited) {
+ bool washilighted = hilited;
+ hilited = !!ishilited;
+
+ if (washilighted != hilited)
+ invalidate();
+}
+
+TreeItem *TreeItem::getParent() {
+ return parent;
+}
+
+bool TreeItem::isHilitedDrop() {
+ return hilitedDrop;
+}
+
+bool TreeItem::isHilited() {
+ return hilited;
+}
+
+void TreeItem::setIcon(SkinBitmap *newicon) {
+ if (icon) {
+ delete icon;
+ icon = NULL;
+ }
+ icon = newicon;
+ invalidate();
+}
+
+SkinBitmap *TreeItem::getIcon() {
+ return icon;
+}
+
+void TreeItem::sortItems() {
+ subitems.sort();
+}
+
+void TreeItem::editLabel() {
+ if (!tree) return;
+ tree->editItemLabel(this);
+}
+
+int TreeItem::onBeginLabelEdit() {
+ return 1; // disable editing by default
+}
+
+int TreeItem::onEndLabelEdit(const wchar_t *newlabel)
+{
+ return 1; // accept new label by default
+}
+
+void TreeItem::setEdition(bool isedited) {
+ being_edited = !!isedited;
+ invalidate();
+}
+
+bool TreeItem::getEdition() {
+ return being_edited;
+}
+
+bool TreeItem::isSorted()
+{
+ return subitems.getAutoSort();
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/treewnd.h b/Src/Wasabi/api/wnd/wndclass/treewnd.h
new file mode 100644
index 00000000..454b9349
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/treewnd.h
@@ -0,0 +1,624 @@
+#ifndef _TREEWND_H
+#define _TREEWND_H
+
+// BU: lots of changes
+// - all items must be deletable, and will be deleted on destructor
+// - root items list not allocated w/ new
+// - items set sorting within their PtrListSorted instead of manually calling it
+// - setting an item to auto-sort does *not* make subitems autosort too
+
+#include <api/wnd/wndclass/scbkgwnd.h>
+#include <bfc/ptrlist.h>
+#include <api/wnd/wndclass/editwnd.h>
+#include <bfc/common.h>
+#include <tataki/color/skinclr.h>
+
+#define TREEWND_PARENT ScrlBkgWnd
+
+#define STATUS_EXPANDED 0
+#define STATUS_COLLAPSED 1
+
+#define HITTEST_BEFORE 0
+#define HITTEST_IN 1
+#define HITTEST_AFTER 2
+
+#define LINK_RIGHT 1
+#define LINK_TOP 2
+#define LINK_BOTTOM 4
+
+#define TAB_NO FALSE
+#define TAB_YES TRUE
+#define TAB_AUTO 2
+
+#define WM_SETITEMDEFERRED WM_USER+6546
+
+#define DC_SETITEM 10
+#define DC_DELITEM 20
+#define DC_EXPAND 30
+#define DC_COLLAPSE 40
+
+// Forward references
+
+class TreeItemList;
+class TreeItem;
+class TreeWnd;
+
+class FontSize;
+
+// classes & structs
+class CompareTreeItem {
+public:
+ static int compareItem(TreeItem *p1, TreeItem *p2);
+};
+
+class TreeItemList : public PtrListQuickSorted<TreeItem, CompareTreeItem> { };
+
+class TreeItem
+{
+friend class TreeWnd;
+public:
+ TreeItem(const wchar_t *label=NULL);
+ virtual ~TreeItem();
+
+ virtual SkinBitmap *getIcon();
+ virtual void setIcon(SkinBitmap *newicon);
+
+ virtual void onTreeAdd() {}
+ virtual void onTreeRemove() {}
+ virtual void onChildItemRemove(TreeItem *item) {}
+ // override this to keep from being selected
+ virtual int isHitTestable() { return 1; }
+ virtual void onSelect() {}
+ virtual void onDeselect() {}
+ virtual int onLeftDoubleClick() { return 0; }
+ virtual int onRightDoubleClick() { return 0; }
+ virtual int onContextMenu(int x, int y);
+ virtual int onChar(UINT key) { return 0; } // return 1 if you eat the key
+
+ // these are called after the expand/collapse happens
+ virtual void onExpand() {}
+ virtual void onCollapse() {}
+
+ virtual int onBeginLabelEdit();
+ virtual int onEndLabelEdit(const wchar_t *newlabel);
+
+ virtual void setLabel(const wchar_t *label);
+ virtual const wchar_t *getLabel();
+
+ void setTip(const wchar_t *tip);
+ const wchar_t *getTip();
+
+ // override to draw by yourself. Return the width of what you've drawn
+ virtual int customDraw(Canvas *canvas, const POINT &pt, int defaultTxtHeight, int indentation, const RECT &clientRect, const Wasabi::FontInfo *fontInfo);
+
+ // return 0 to refuse being dragged
+ // else return 1 and install the droptype and dropitem
+ // also, write suggested title into suggestedTitle if any
+ virtual int onBeginDrag(wchar_t *suggestedTitle) { return 0; }
+
+ virtual int dragOver(ifc_window *sourceWnd) { return 0; }
+ virtual int dragLeave(ifc_window *sourceWnd) { return 0; }
+ virtual int dragDrop(ifc_window *sourceWnd) { return 0; }
+
+ virtual int dragComplete(int success) { return 0; }
+
+ void ensureVisible();
+
+ TreeItem *getNthChild(int nth); // enumerates children (zero based)
+ TreeItem *getChild();
+ TreeItem *getChildSibling(TreeItem *item);
+ TreeItem *getSibling();
+ TreeItem *getParent();
+
+ void editLabel();
+
+ int getNumChildren();
+ bool hasSubItems();
+
+ void setSorted(int issorted);
+ void setChildTab(int haschildtab);
+ bool isSorted();
+
+ bool isCollapsed();
+ bool isExpanded();
+
+ void invalidate();
+ bool isSelected();
+ bool isHilited();
+ void setHilited(bool ishilited);
+
+ int collapse();
+ int expand();
+
+ int getCurRect(RECT *r);
+
+ void setCurrent(bool tf);
+
+ TreeWnd *getTree() const;
+
+protected:
+
+ bool isHilitedDrop();
+ void setHilitedDrop(bool ishilitedDrop);
+
+ void linkTo(TreeItem *linkto);
+// void childDeleted(TreeItem *child);
+ void setTree(TreeWnd *newtree);
+ void addSubItem(TreeItem *item);
+ void setCurRect(int x1, int y1, int x2, int y2, int z);
+ int getIndent();
+
+ bool needTab();
+ void sortItems(); // sorts the children of this item
+ void setEdition(bool isedited);
+ bool getEdition();
+
+private:
+ void setSelected(bool isselected, bool expandCollapse=false, bool editifselected=false);
+ // this really calls delete on the subitems
+ void deleteSubitems();
+
+ int removeSubitem(TreeItem *item);
+
+ int getItemWidth(int txtHeight, int indentation);
+
+ StringW label;
+ class TreeItem *parent;
+ TreeItemList subitems; // children
+ RECT curRect;
+ int childTab;
+ TreeWnd *tree;
+ int expandStatus;
+ SkinBitmap *icon;
+ int _z;
+ StringW tooltip; // if empty, falls back to livetip
+
+ bool selected:1;
+ bool hilitedDrop:1;
+ bool hilited:1;
+ bool being_edited:1;
+};
+
+
+/**
+
+
+ @short Tree-like view with leaf items.
+ @ver 1.0
+ @author Nullsoft
+ @see TreeItem
+*/
+class TreeWnd : public TREEWND_PARENT {
+
+friend class TreeItem;
+
+public:
+
+ /**
+ Sets up the default values for the TreeWnd. These defaults are
+ auto collapse enabled and sets the TreeWnd bitmaps to the default Wasabi
+ values.
+ */
+ TreeWnd();
+
+ /**
+ Deletes all the root items (including subitems).
+ */
+ virtual ~TreeWnd();
+
+ /**
+ Event is triggered when the button is about to be initialized.
+ Override this event to implement your own behavior.
+
+ @ret 1
+ */
+ virtual int onInit();
+
+ /**
+ Paints the bitmap on canvas according
+ to current options (centering, tiling, stretching, title).
+
+ @ret 0 for failure, 1 for success
+ @param canvas The canvas on which to paint.
+ */
+ virtual int onPaint(Canvas *canvas);
+
+ /**
+ Notify a child window via a generic message system.
+
+ @see addChild()
+ @ret
+ @param child A pointer to the child window which will receive the notify.
+ @param msg The message you want to send to the child.
+ @param p1 A user parameter.
+ @param p2 A user parameter.
+ */
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+
+ /**
+ Event triggered when the left mouse
+ button is pressed over the TreeWnd.
+
+ Override this to implement your own behavior.
+
+ Default behavior is to stop editing a TreeItem label
+ (if editing was occuring). Also will cause a collapse
+ or expansion of the subitems if an item was previously
+ selected.
+
+ @ret 1, If you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The Y coordinate of the mouse.
+ */
+ virtual int onLeftButtonDown(int x, int y);
+
+ /**
+ Event is triggered when the left mouse button
+ is released from a previously pressed state.
+
+ Override this to implement your own behavior.
+
+ @ret 1, If you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The Y coordinate of the mouse.
+ */
+ virtual int onLeftButtonUp(int x, int y);
+
+ /**
+ Event is triggered when the right mouse button
+ is released from a previously pressed state.
+
+ Override this to implement your own behavior.
+
+ @ret 1, If you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The Y coordinate of the mouse.
+ */
+ virtual int onRightButtonUp(int x, int y);
+
+ /**
+ Event is triggered when the mouse is moved
+ over the TreeWnd.
+
+ Override this to implement your own behavior.
+
+ Default is to handle drops (drag and drop).
+
+ @ret 1, If you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The Y coordinate of the mouse.
+ */
+ virtual int onMouseMove(int x, int y);
+
+ /**
+ Do we want the context command menu to pop-up
+ on right clicks?
+
+ Default is no.
+
+ @see ContextCmdI
+ @ret 0, AutoContextMenu off; 1, AutoContextMenu on;
+ */
+ virtual int wantAutoContextMenu() { return 0; }
+
+ /**
+ Event is triggered when the left mouse button
+ is double clicked and the cursor is over the
+ TreeWnd.
+
+ Default is to check if the doubleclick
+ happened over an item, if it did, it calls
+ the item's handler of this event.
+
+ @ret 1, if you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The Y coordinate of the mouse.
+ */
+ virtual int onLeftButtonDblClk(int x, int y);
+
+ /**
+ Event is triggered when the right mouse button
+ is double clicked and the cursor is over the
+ TreeWnd.
+
+ Default is to check if the doubleclick
+ happened over an item, if it did, it calls
+ the item's handler of this event.
+
+ @ret 1, If you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The y coordinate of the mouse.
+ */
+ virtual int onRightButtonDblClk(int x, int y);
+
+ /**
+ Event is triggered when the mouse wheel
+ is rolled up.
+
+ Override this to implement your own behavior.
+
+ Default is to scroll vertically as required.
+ When the wheel is clicked and rolled, the
+ TreeWnd is scrolled horizontally.
+
+ @ret 1, If you handle the event.
+ @param clicked The pushed state of the mouse wheel.
+ @param lines The number of lines to scroll (or columns if horizontally scrolling).
+ */
+ virtual int onMouseWheelUp(int clicked, int lines);
+
+ /**
+ Event is triggered when the mouse wheel
+ is rolled down.
+
+ Override this to implement your own behavior.
+
+ Default is to scroll vertically as required.
+ When the wheel is clicked and rolled, the
+ TreeWnd is scrolled horizontally.
+
+ @ret 1, If you handle the event.
+ @param clicked The pushed state of the mouse wheel.
+ @param lines The number of lines to scroll (or columns if horizontally scrolling).
+ */
+ virtual int onMouseWheelDown(int clicked, int lines);
+
+ /**
+ */
+ virtual void timerCallback(int c);
+
+ /**
+ Event is triggered when the right click occurs over
+ the TreeWnd, but not on a TreeItem.
+
+ Override this to implement your own behavior.
+
+ @ret 1, If you handle the event.
+ @param x The X coordinate of the mouse.
+ @param y The Y coordinate of the mouse.
+ */
+ virtual int onContextMenu(int x, int y);
+
+ // override and return 1 to abort calling context menu on item
+ virtual int onPreItemContextMenu(TreeItem *item, int x, int y) { return 0; }
+ // override to catch when item context menu complete
+ virtual void onPostItemContextMenu(TreeItem *item, int x, int y, int retval) { }
+
+ /**
+ Event is triggered when a scheduled deferred callback
+ occurs.
+
+ Override this to implement your own behavior.
+
+ @ret 1, If you handle this event; 0, If you do not handle this event;
+ @param param1 Generic user paramater 1.
+ @param param2 Generic user paramater 2.
+ */
+ virtual int onDeferredCallback(intptr_t param1, intptr_t param2);
+
+ /**
+ Event is triggered when a key is pressed
+ and the TreeWnd has focus.
+
+ Override this to implement your own behavior.
+
+ @ret 1, If you handle the event.
+ @param c The key that was pressed.
+ */
+ virtual int onChar(unsigned int c);
+
+ /**
+ Event is triggered when a key is pressed
+ and the TreeWnd has focus.
+
+ This method handles extended keys.
+
+ @ret 1, If you handle the event.
+ */
+ virtual int onKeyDown(int keycode);
+
+ /**
+
+ */
+ virtual void jumpToNext(wchar_t c);
+
+ /**
+ Verifies if the item received is in the
+ viewable area of the TreeWnd. If not, it
+ will make it visible by scrolling to the
+ appropriate position.
+
+ @param item A pointer to the item to verify.
+ */
+ void ensureItemVisible(TreeItem *item);
+
+ // don't need to override this: just calls thru to the treeitem
+ virtual int onBeginDrag(TreeItem *treeitem);
+
+ virtual int dragEnter(ifc_window *sourceWnd);
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual int dragLeave(ifc_window *sourceWnd);
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
+
+ virtual int dragComplete(int success);
+
+ int wantFocus() { return 1; }
+
+ // override this if you want to control the item sort order
+ virtual int compareItem(TreeItem *p1, TreeItem *p2);
+
+protected:
+ // these will be called if the pointer is not over a treeitem
+ virtual int defaultDragOver(int x, int y, ifc_window *sourceWnd) { return 0; }
+ virtual int defaultDragDrop(ifc_window *sourceWnd, int x, int y) { return 0; }
+
+ // called with item that received a drop
+ virtual void onItemRecvDrop(TreeItem *item) {}
+
+ virtual void onLabelChange(TreeItem *item) {}
+
+ virtual void onItemSelected(TreeItem *item) {}
+ virtual void onItemDeselected(TreeItem *item) {}
+
+ virtual int onGetFocus();
+ virtual int onKillFocus();
+
+public:
+
+ virtual int getContentsWidth();
+ virtual int getContentsHeight();
+
+ void setRedraw(bool r);
+
+ TreeItem *addTreeItem(TreeItem *item, TreeItem *par=NULL, int sorted=TRUE, int haschildtab=FALSE);
+
+ // just removes a TreeItem from the tree, doesn't delete it... this is for
+ // ~TreeItem to call only
+ int removeTreeItem(TreeItem *item);
+
+ void moveTreeItem(TreeItem *item, TreeItem *newparent);
+
+ void deleteAllItems();
+
+ int expandItem(TreeItem *item);
+ void expandItemDeferred(TreeItem *item);
+ int collapseItem(TreeItem *item);
+ void collapseItemDeferred(TreeItem *item);
+
+ void selectItem(TreeItem *item); // selects.
+ void selectItemDeferred(TreeItem *item);// selects. posted.
+ void delItemDeferred(TreeItem *item);
+ void hiliteItem(TreeItem *item);
+ void unhiliteItem(TreeItem *item);
+ void setHilitedColor(const wchar_t *colorname);
+ ARGB32 getHilitedColor();
+
+ TreeItem *getCurItem();
+
+ TreeItem *hitTest(POINT pos);
+ TreeItem *hitTest(int x, int y);
+
+ void editItemLabel(TreeItem *item);
+ void cancelEditLabel(int destroyit=0);
+ void setAutoEdit(int ae);
+ int getAutoEdit();
+ // use a NULL item to search all items. returns first item found
+ TreeItem *getByLabel(TreeItem *item, const wchar_t *name);
+
+ int getItemRect(TreeItem *item, RECT *r);
+
+ int ownerDraw();
+
+ int getNumRootItems();
+ TreeItem *enumRootItem(int which);
+
+ void setSorted(bool dosort);
+ bool getSorted();
+
+ void sortTreeItems();
+
+ TreeItem *getSibling(TreeItem *item);
+
+ TreeItem *getItemFromPoint(POINT *pt);
+
+ void setAutoCollapse(bool doautocollapse);
+
+ virtual int setFontSize(int newsize);
+ int getFontSize();
+
+ int getNumVisibleChildItems(TreeItem *c);
+ int getNumVisibleItems();
+ TreeItem *enumVisibleItems(int n);
+ TreeItem *enumVisibleChildItems(TreeItem *c, int n);
+ int findItem(TreeItem *i); // reverse
+ int findChildItem(TreeItem *c, TreeItem *i, int *n);
+
+ TreeItem *enumAllItems(int n); // unsorted
+
+ void onSelectItem(TreeItem *i);
+ void onDeselectItem(TreeItem *i);
+
+protected:
+ void hiliteDropItem(TreeItem *item);
+ void unhiliteDropItem(TreeItem *item);
+ void invalidateMetrics();
+
+private:
+ TreeItemList items; // root-level stuff
+
+ PtrList<TreeItem> all_items; // unsorted
+
+ TreeItem *curSelected;
+
+ BltCanvas *dCanvas;
+
+ void drawItems(Canvas *c, const Wasabi::FontInfo *fontInfo);
+ void setCurItem(TreeItem *item, bool expandCollapse=true, bool editifselected=false);
+ void countSubItems(PtrList<TreeItem> &drawlist, TreeItemList *list, int indent, int *c, int *m, int z);
+ void getMetrics(int *numItemsShow, int *maxWidth);
+ void ensureMetricsValid();
+ int getLinkLine(TreeItem *item, int level);
+ void endEditLabel(const wchar_t *newlabel);
+ void editUpdate();
+ int jumpToNextSubItems(TreeItemList *list, wchar_t c);
+
+ int itemHeight;
+
+ AutoSkinBitmap tabClosed, tabOpen;
+ AutoSkinBitmap linkTopRight, linkTopBottom, linkTopRightBottom;
+ AutoSkinBitmap linkTabTopRight, linkTabTopBottom, linkTabTopRightBottom;
+
+ TreeItem *firstItemVisible;
+ TreeItem *lastItemVisible;
+
+ TreeItem *mousedown_item, *prevbdownitem;
+ POINT mousedown_anchor;
+ bool mousedown_dragdone;
+ TreeItem *hitItem, // the dest item
+ *draggedItem; // the source item
+
+ int inHitTest;
+
+ bool metrics_ok;
+ int maxWidth;
+ int maxHeight;
+
+ StringW defaultTip;
+
+ const wchar_t *getLiveTip();
+ void setLiveTip(const wchar_t *tip);
+ TreeItem *tipitem;
+
+ bool redraw;
+
+ PtrList<TreeItem> drawList;
+ TreeItem *edited;
+
+ EditWnd *editwnd;
+ wchar_t editbuffer[256];
+
+ int deleteItems;
+ bool firstFound;
+
+ TreeItem *currentItem;
+ StringW hilitedColorName;
+ SkinColor hilitedColor;
+ int autoedit;
+ int autocollapse;
+ int textsize;
+ StringW oldtip;
+ StringW accValue;
+};
+
+template<class T> class TreeItemParam : public TreeItem {
+public:
+ TreeItemParam(T _param, const wchar_t *label=NULL) : TreeItem(label) { param = _param; }
+
+ T getParam() { return param; }
+ operator T() { return getParam(); }
+
+private:
+ T param;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/typesheet.cpp b/Src/Wasabi/api/wnd/wndclass/typesheet.cpp
new file mode 100644
index 00000000..7df91946
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/typesheet.cpp
@@ -0,0 +1,38 @@
+#include <precomp.h>
+
+#include "typesheet.h"
+#include <api/wnd/wndclass/svcwndhold.h>
+#include <api/wnd/wndclass/buttbar.h>
+#include <api/service/svcs/svc_wndcreate.h>
+
+TypeSheet::TypeSheet(const wchar_t *_windowtype) :
+ TabSheet(ButtBar::STACK), windowtype(_windowtype)
+{ }
+
+int TypeSheet::onInit() {
+ TYPESHEET_PARENT::onInit();
+ load();
+ return 1;
+}
+
+void TypeSheet::setWindowType(const wchar_t *wtype) {
+ windowtype = wtype;
+}
+
+void TypeSheet::load() {
+ if (windowtype == NULL || !*windowtype) return;
+ WindowCreateByTypeEnum se(windowtype);
+ svc_windowCreate *svc;
+ while (svc = se.getNext()) {
+ for (int i = 0; ; i++) {
+ ServiceWndHolder *svcwnd = new ServiceWndHolder;
+ ifc_window *wnd = svc->createWindowOfType(windowtype, svcwnd, i);
+ if (wnd == NULL) {
+ delete svcwnd;
+ break;
+ }
+ svcwnd->setChild(wnd, svc);
+ addChild(svcwnd);
+ }
+ }
+}
diff --git a/Src/Wasabi/api/wnd/wndclass/typesheet.h b/Src/Wasabi/api/wnd/wndclass/typesheet.h
new file mode 100644
index 00000000..8f580084
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/typesheet.h
@@ -0,0 +1,49 @@
+#ifndef _TYPESHEET_H
+#define _TYPESHEET_H
+
+#include "tabsheet.h"
+
+#define TYPESHEET_PARENT TabSheet
+/**
+ Class TypeSheet
+
+ @short A Typesheet Control.
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class TypeSheet : public TYPESHEET_PARENT {
+public:
+
+ /**
+ TypeSheet constructor
+
+ @param _windowtype
+ */
+ TypeSheet(const wchar_t *windowtype);
+
+ /**
+ TypeSheet method onInit .
+
+ @ret 1
+ @param None
+ */
+ virtual int onInit();
+
+ /**
+ TypeSheet method load
+ */
+ virtual void load();
+
+ /**
+ TypeSheet method setWindowType .
+
+ @param windowtype The type of the window.
+ */
+ virtual void setWindowType(const wchar_t *windowtype);
+
+private:
+ StringW windowtype;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/virtualhostwnd.cpp b/Src/Wasabi/api/wnd/wndclass/virtualhostwnd.cpp
new file mode 100644
index 00000000..ef91ebc1
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/virtualhostwnd.cpp
@@ -0,0 +1,198 @@
+#include "precomp.h"
+#include "virtualhostwnd.h"
+#include <tataki/canvas/ifc_canvas.h>
+#include <tataki/region/api_region.h>
+
+VirtualHostWnd::VirtualHostWnd() {
+ group = new GuiObjectWnd();
+ fittoclient = 0;
+ xoffset = 0;
+ yoffset = 0;
+ groupwidth = 0;
+ groupheight = 0;
+ scripts_enabled = 1;
+}
+
+VirtualHostWnd::~VirtualHostWnd() {
+ delete group;
+}
+
+int VirtualHostWnd::onInit() {
+ GuiObjectWnd::onInit();
+ group->setVirtual(0);
+ group->setStartHidden(1);
+ group->setParent(this);
+ group->init(this);
+ group->deferedInvalidate();
+ group->setCloaked(1); // magic!
+ group->setVisible(1);
+ return 1;
+}
+
+void VirtualHostWnd::virtualhostwnd_setContent(const char *_groupname) {
+ group->setContent(_groupname);
+ if (isPostOnInit())
+ virtualhostwnd_onNewContent();
+}
+
+void VirtualHostWnd::virtualhostwnd_setContent(SkinItem *groupitem) {
+ group->setContentBySkinItem(groupitem);
+ if (isPostOnInit())
+ virtualhostwnd_onNewContent();
+}
+
+void VirtualHostWnd::virtualhostwnd_onNewContent() {
+}
+
+#ifdef WASABI_COMPILE_SCRIPT
+ScriptObject *VirtualHostWnd::virtualhostwnd_findScriptObject(const char *object_id) {
+ return group->findScriptObject(object_id);
+}
+#endif
+
+#ifdef WASABI_COMPILE_SKIN
+GuiObject *VirtualHostWnd::virtualhostwnd_getContent() {
+ return group->getContent();
+}
+
+ScriptObject *VirtualHostWnd::virtualhostwnd_getContentScriptObject() {
+ return group->getContentScriptObject();
+}
+
+GuiObject *VirtualHostWnd::virtualhostwnd_findObject(const char *object_id) {
+ return group->findObject(object_id);
+}
+#endif
+
+api_window *VirtualHostWnd::virtualhostwnd_getContentRootWnd() {
+ return group->getContentRootWnd();
+}
+
+int VirtualHostWnd::onPaint(Canvas *c) {
+ GuiObjectWnd::onPaint(c);
+
+ virtualhostwnd_onPaintBackground(c);
+
+ if (group == NULL) return 1;
+
+ RECT wr;
+ Canvas *cv = NULL;
+
+ group->getNonClientRect(&wr);
+ group->paint(NULL, NULL);
+
+ cv = group->getFrameBuffer();
+
+ if (cv != NULL) {
+ BltCanvas *bltcanvas = static_cast<BltCanvas *>(cv); // HACK!
+ bltcanvas->/*getSkinBitmap()->*/blitAlpha(c, xoffset, yoffset);
+ }
+ return 1;
+}
+
+void VirtualHostWnd::virtualhostwnd_onPaintBackground(Canvas *c) {
+ RECT r;
+ getClientRect(&r);
+ c->fillRect(&r, RGB(255,255,255));
+}
+
+int VirtualHostWnd::onResize() {
+ GuiObjectWnd::onResize();
+ if (group != NULL) {
+ RECT r;
+ getClientRect(&r);
+ if (fittoclient) {
+ xoffset = 0;
+ yoffset = 0;
+ groupwidth = r.right-r.left;
+ groupheight = r.bottom-r.top;
+ } else {
+ groupwidth = group->getGuiObject()->guiobject_getAutoWidth();
+ groupheight = group->getGuiObject()->guiobject_getAutoHeight();
+ if (groupwidth == AUTOWH) groupwidth = 320;
+ if (groupheight == AUTOWH) groupheight = 200;
+ int cw = r.right-r.left;
+ int ch = r.bottom-r.top;
+ xoffset = (cw - groupwidth)/2;
+ yoffset = (ch - groupheight)/2;
+ }
+ group->resize(xoffset+r.left, yoffset+r.top, groupwidth, groupheight);
+ }
+ return 1;
+}
+
+void VirtualHostWnd::virtualhostwnd_getContentRect(RECT *r) {
+ ASSERT(r != NULL);
+ getClientRect(r);
+ r->left += xoffset;
+ r->top += yoffset;
+ r->right = r->left + groupwidth;
+ r->bottom = r->top + groupheight;
+}
+
+
+void VirtualHostWnd::virtualhostwnd_fitToClient(int fit) {
+ fittoclient = fit;
+ if (isPostOnInit()) {
+ onResize();
+ invalidate();
+ }
+}
+
+void VirtualHostWnd::onChildInvalidate(api_region *r, api_window *who) {
+ GuiObjectWnd::onChildInvalidate(r, who);
+ api_region *clone = r->clone();
+ clone->offset(xoffset, yoffset);
+ invalidateRgn(clone);
+ r->disposeClone(clone);
+}
+
+int VirtualHostWnd::onLeftButtonDown(int x, int y) {
+ // DO NOT CALL GuiObjectWnd::onLeftButtonDown(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
+}
+
+int VirtualHostWnd::onLeftButtonUp(int x, int y){
+ // DO NOT CALL GuiObjectWnd::onLeftButtonUp(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_LBUTTONUP, 0, MAKELPARAM(x, y));
+}
+
+int VirtualHostWnd::onRightButtonDown(int x, int y){
+ // DO NOT CALL GuiObjectWnd::onRightButtonDown(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(x, y));
+}
+
+int VirtualHostWnd::onRightButtonUp(int x, int y){
+ // DO NOT CALL GuiObjectWnd::onRightButtonUp(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_RBUTTONUP, 0, MAKELPARAM(x, y));
+}
+
+int VirtualHostWnd::onLeftButtonDblClk(int x, int y){
+ // DO NOT CALL GuiObjectWnd::onLeftButtonDblClk(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_RBUTTONDBLCLK, 0, MAKELPARAM(x, y));
+}
+
+int VirtualHostWnd::onRightButtonDblClk(int x, int y){
+ // DO NOT CALL GuiObjectWnd::onRightButtonDblClk(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_LBUTTONDBLCLK, 0, MAKELPARAM(x, y));
+}
+
+int VirtualHostWnd::onMouseMove(int x, int y){
+ // DO NOT CALL GuiObjectWnd::onMouseMove(x, y);
+ x -= xoffset;
+ y -= yoffset;
+ return group->wndProc(group->gethWnd(), WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/virtualhostwnd.h b/Src/Wasabi/api/wnd/wndclass/virtualhostwnd.h
new file mode 100644
index 00000000..8dbeb93f
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/virtualhostwnd.h
@@ -0,0 +1,51 @@
+#ifndef __VIRTUALHOSTWND_H
+#define __VIRTUALHOSTWND_H
+
+#include "../../common/guiobjwnd.h"
+
+class VirtualHostWnd : public GuiObjectWnd {
+ public:
+ VirtualHostWnd();
+ virtual ~VirtualHostWnd();
+
+ virtual int onInit();
+ virtual int onPaint(Canvas *c);
+ virtual int onResize();
+ virtual void onChildInvalidate(api_region *r, ifc_window *who);
+
+ virtual int onLeftButtonDown(int x, int y);
+ virtual int onLeftButtonUp(int x, int y);
+ virtual int onRightButtonDown(int x, int y);
+ virtual int onRightButtonUp(int x, int y);
+ virtual int onLeftButtonDblClk(int x, int y);
+ virtual int onRightButtonDblClk(int x, int y);
+ virtual int onMouseMove(int x, int y);
+
+ virtual void virtualhostwnd_setContent(const wchar_t *groupid);
+ virtual void virtualhostwnd_setContent(SkinItem *item);
+ virtual void virtualhostwnd_onNewContent();
+ virtual void virtualhostwnd_onPaintBackground(Canvas *c);
+
+ virtual void virtualhostwnd_fitToClient(int fit);
+ virtual void virtualhostwnd_getContentRect(RECT *r);
+
+ virtual ifc_window *virtualhostwnd_getContentRootWnd();
+#ifdef WASABI_COMPILE_SCRIPT
+ virtual ScriptObject *virtualhostwnd_findScriptObject(const wchar_t *object_id);
+#endif
+#ifdef WASABI_COMPILE_SKIN
+ virtual GuiObject *virtualhostwnd_findObject(const wchar_t *object_id);
+ virtual GuiObject *virtualhostwnd_getContent();
+ virtual ScriptObject *virtualhostwnd_getContentScriptObject();
+#endif
+
+ private:
+
+ GuiObjectWnd *group;
+ int fittoclient;
+ int xoffset, yoffset;
+ int groupwidth, groupheight;
+ int scripts_enabled;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndclass/wndholder.cpp b/Src/Wasabi/api/wnd/wndclass/wndholder.cpp
new file mode 100644
index 00000000..272298a3
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/wndholder.cpp
@@ -0,0 +1,369 @@
+#include <precomp.h>
+#include "wndholder.h"
+#include <api/service/svcs/svc_wndcreate.h>
+#include <api/service/svc_enum.h>
+#include <api/syscb/callbacks/wndcb.h>
+
+//#pragma CHAT("lone", "benski", "needs to dispatch Layout & Containers!")
+#include <api/wndmgr/container.h>
+#include <api/wndmgr/layout.h>
+
+#define CBCLASS WindowHolderI
+START_DISPATCH;
+ CB(WNDHOLDER_ONINSERTWINDOW, onInsertWindow);
+ VCB(WNDHOLDER_ONREMOVEWINDOW, onRemoveWindow);
+ CB(WNDHOLDER_WANTGUID, wantGuid);
+ CB(WNDHOLDER_WANTGROUP, wantGroup);
+ CB(WNDHOLDER_GETROOTWNDPTR, getRootWndPtr);
+ CB(WNDHOLDER_GETCURGROUPID, getCurGroupId);
+ CB(WNDHOLDER_GETCURGUID, getCurGuid);
+ CB(WNDHOLDER_GETCURROOTWND, getCurRootWnd);
+ CB(WNDHOLDER_GETCURID, getCurId);
+ CB(WNDHOLDER_ISGENERICGUID, acceptsGenericGuid);
+ CB(WNDHOLDER_ISGENERICGROUP, acceptsGenericGroup);
+ VCB(WNDHOLDER_CANCELDEFERREDREMOVE, cancelDeferredRemove);
+ VCB(WNDHOLDER_ONNEEDRELOADGRP, wndholder_onNeedReloadGroup);
+ CB(WNDHOLDER_WANTAUTOFOCUS, wndholder_wantAutoFocus);
+ CB(WNDHOLDER_ISAUTOAVAILABLE, wndholder_isAutoAvailable);
+END_DISPATCH;
+
+WindowHolderI::WindowHolderI() {
+ wnd = NULL;
+ dr = NULL;
+ generic_guid = 1;
+ generic_group = 1;
+ cur_guid = INVALID_GUID;
+ cur_groupid = NULL;
+ wc_svc = NULL;
+ WASABI_API_WNDMGR->wndholder_register(this);
+}
+
+WindowHolderI::~WindowHolderI() {
+ delete dr;
+ if (wnd != NULL) {
+ if (wc_svc) {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ wc_svc->destroyWindow(w);
+ SvcEnum::release(wc_svc);
+ wc_svc = NULL;
+ } else {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ WASABI_API_SKIN->group_destroy(w);
+ }
+ }
+ accepted_groups.deleteAll();
+ accepted_guids.deleteAll();
+ WASABI_API_WNDMGR->wndholder_unregister(this);
+}
+
+ifc_window *WindowHolderI::onInsertWindow(GUID g, const wchar_t *groupid)
+{
+ cancelDeferredRemove();
+
+ defered_guid = INVALID_GUID;
+ if (wnd != NULL) return NULL;
+
+ cur_groupid = groupid;
+ if (g != INVALID_GUID)
+ {
+ cur_guid = g;
+ wchar_t cguid[256] = {0};
+ nsGUID::toCharW(g, cguid);
+ cur_id = cguid;
+ } else
+ cur_id = groupid;
+
+ wnd = createWindow(g == INVALID_GUID ? NULL : &g, groupid);
+ if (!wnd) {
+ cur_guid = INVALID_GUID;
+ cur_id = L"";
+ cur_groupid = L"";
+ }
+ if (wnd) {
+ onInsert(wnd, cur_id);
+ } else {
+ if (g != INVALID_GUID) {
+ defered_guid = g;
+ }
+ }
+ return wnd;
+}
+
+void WindowHolderI::onRemoveWindow(int deferred) {
+ if (deferred) {
+ if (!dr)
+ dr = new DeferredRemove(this);
+ dr->post();
+ return;
+ }
+ if (wnd != NULL) {
+ ifc_window *w = getCurRootWnd();
+ onRemove(w, cur_id);
+ destroyWindow();
+ cur_guid = INVALID_GUID;
+ cur_groupid = NULL;
+ defered_guid = INVALID_GUID;
+ }
+}
+
+void WindowHolderI::cancelDeferredRemove() {
+ delete dr;
+ dr = NULL;
+}
+
+void WindowHolderI::wndholder_onNeedReloadGroup(const wchar_t *id)
+{
+ if (cur_groupid.isempty()) return;
+ ifc_window *w = getCurRootWnd();
+ if (w == NULL) return;
+ if (w->isInited() && !WCSICMP(cur_groupid, id))
+ {
+ onRemove(w, cur_id);
+ destroyWindow();
+ createWindow(&INVALID_GUID, id);
+ onInsert(wnd, cur_id);
+ }
+}
+
+ifc_window *WindowHolderI::createWindow(const GUID *g, const wchar_t *groupid)
+{
+ ASSERT(wnd == NULL);
+ if (g != NULL && *g != INVALID_GUID) {
+ wc_svc = WindowCreateByGuidEnum(*g).getFirst();
+ if (wc_svc)
+ wnd = wc_svc->createWindowByGuid(*g, getRootWndPtr());
+ }
+ else if (groupid != NULL)
+ {
+ wc_svc = NULL;
+ wnd = WASABI_API_SKIN->group_create(groupid);
+ }
+ if (wnd) {
+ if (!wnd->isInited()) {
+ if (!wnd->getParent()) wnd->setParent(getRootWndPtr());
+ wnd->init(getRootWndPtr());
+ }
+ }
+ return wnd;
+}
+
+void WindowHolderI::destroyWindow() {
+ ASSERT(wnd != NULL);
+
+ ifc_window *w = wnd->getDesktopParent();
+
+ if (wc_svc) {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ wc_svc->destroyWindow(w);
+ SvcEnum::release(wc_svc);
+ wc_svc = NULL;
+ } else {
+ ifc_window *w = wnd;
+ wnd = NULL;
+ WASABI_API_SKIN->group_destroy(w);
+ }
+
+ if (w != NULL) {
+ if (w->getInterface(layoutGuid)) {
+ static_cast<Layout *>(w)->updateTransparency();
+ }
+ }
+
+}
+
+void WindowHolderI::addAcceptGuid(GUID g) {
+ accepted_guids.addItem(new GUID(g));
+}
+
+void WindowHolderI::addAcceptGroup(const wchar_t *groupid)
+{
+ accepted_groups.addItem(new StringW(groupid));
+}
+
+void WindowHolderI::setAcceptAllGuids(int tf) {
+ generic_guid = tf;
+}
+
+void WindowHolderI::setAcceptAllGroups(int tf) {
+ generic_group = tf;
+}
+
+int WindowHolderI::wantGuid(GUID g) {
+ if (acceptsGenericGuid()) return 1;
+ for (int i=0;i<accepted_guids.getNumItems();i++) {
+ if (*accepted_guids.enumItem(i) == g) return 1;
+ }
+ return 0;
+}
+
+int WindowHolderI::wantGroup(const wchar_t *groupid)
+{
+ if (acceptsGenericGroup()) return 1;
+ for (int i=0;i<accepted_groups.getNumItems();i++) {
+ if (!WCSICMP(accepted_groups.enumItem(i)->getValue(), groupid))
+ return 1;
+ }
+ return 0;
+}
+
+GUID *WindowHolderI::getFirstAcceptedGuid() {
+ if (accepted_guids.getNumItems() == 0) return NULL;
+ return accepted_guids.enumItem(0);
+}
+
+const wchar_t *WindowHolderI::getFirstAcceptedGroup()
+{
+ if (accepted_guids.getNumItems() == 0)
+ return NULL;
+ return
+ accepted_groups.enumItem(0)->getValue();
+}
+
+int WindowHolderI::wndholder_wantAutoFocus() {
+ return 1;
+}
+
+WindowHolderWnd::WindowHolderWnd() {
+ autoavail = 1;
+ autoopen = 1;
+ autoclose = 0;
+ nocmdbar = 0;
+ noanim = 0;
+ has_wnd = 0;
+ autofocus = 1;
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+WindowHolderWnd::~WindowHolderWnd() {
+ if (has_wnd) {
+ notifyOnRemove();
+ }
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int WindowHolderWnd::onResize() {
+ WINDOWHOLDER_PARENT::onResize();
+ if (getCurRootWnd()) {
+ RECT r;
+ getClientRect(&r);
+ if (!getCurRootWnd()->handleRatio())
+ multRatio(&r);
+ getCurRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
+ }
+ return 1;
+}
+
+int WindowHolderWnd::handleRatio() {
+ return 1;
+}
+
+int WindowHolderWnd::handleDesktopAlpha() {
+ if (getCurRootWnd()) return getCurRootWnd()->handleDesktopAlpha();
+ return 1;
+}
+
+int WindowHolderWnd::handleTransparency() {
+ if (getCurRootWnd()) return getCurRootWnd()->handleTransparency();
+ return 1;
+}
+
+int WindowHolderWnd::onInit() {
+ WINDOWHOLDER_PARENT::onInit();
+ if (isVisible() && autoopen && getFirstAcceptedGuid()) {
+ onInsertWindow(*getFirstAcceptedGuid(), NULL);
+ } else if (isVisible() && autoopen && getFirstAcceptedGroup()) {
+ onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
+ }
+ return 1;
+}
+
+#define DC_NOTIFYONREMOVE 0x205
+
+void WindowHolderWnd::onRemove(ifc_window *w, const wchar_t *id)
+{
+ ifc_window *dw = getDesktopParent();
+ if (dw) dw->removeMinMaxEnforcer(this);
+ postDeferredCallback(DC_NOTIFYONREMOVE);
+}
+
+int WindowHolderWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == DC_NOTIFYONREMOVE) {
+ notifyOnRemove();
+ } else return WINDOWHOLDER_PARENT::onDeferredCallback(p1, p2);
+ return 1;
+}
+
+void WindowHolderWnd::onInsert(ifc_window *w, const wchar_t *id)
+{
+ if (isPostOnInit())
+ onResize();
+ ifc_window *dw = getDesktopParent();
+ if (dw) dw->addMinMaxEnforcer(this);
+ notifyOnInsert();
+ if (wndholder_wantAutoFocus()) w->setFocus();
+}
+
+int WindowHolderWnd::getPreferences(int what) {
+ if (getCurRootWnd()) return getCurRootWnd()->getPreferences(what);
+ return WINDOWHOLDER_PARENT::getPreferences(what);
+}
+
+void WindowHolderWnd::notifyOnRemove() {
+ has_wnd = 0;
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l != NULL) {
+ Container *c = l->getParentContainer();
+ if (c != NULL) {
+ c->notifyRemoveContent(this);
+ }
+ }
+}
+
+void WindowHolderWnd::notifyOnInsert() {
+ has_wnd = 1;
+ Layout *l = getGuiObject()->guiobject_getParentLayout();
+ if (l != NULL) {
+ Container *c = l->getParentContainer();
+ if (c != NULL)
+ {
+ c->notifyAddContent(this, getCurGroupId(), getCurGuid());
+ }
+ }
+}
+
+int WindowHolderWnd::onGroupChange(const wchar_t *grpid)
+{
+ WINDOWHOLDER_PARENT::onGroupChange(grpid);
+ wndholder_onNeedReloadGroup(grpid);
+ return 1;
+}
+
+void WindowHolderWnd::onSetVisible(int show) {
+ if (show && getCurRootWnd() == NULL) {
+ if (autoopen && getFirstAcceptedGuid()) {
+ onInsertWindow(*getFirstAcceptedGuid(), NULL);
+ } else if (autoopen && getFirstAcceptedGroup()) {
+ onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
+ }
+ } else if (!show && getCurRootWnd() != NULL) {
+ if (autoclose && WASABI_API_SKIN->skin_getVersion() >= 1.0)
+ onRemoveWindow(0);
+ }
+ if (getDeferedGuid() != INVALID_GUID) {
+ if (show) {
+ #ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
+ int y;
+ ON_CREATE_EXTERNAL_WINDOW_GUID(getDeferedGuid(), y);
+ #endif
+ }
+ }
+ WINDOWHOLDER_PARENT::onSetVisible(show);
+}
+
+int WindowHolderWnd::wndholder_wantAutoFocus() {
+ return autofocus;
+}
+
diff --git a/Src/Wasabi/api/wnd/wndclass/wndholder.h b/Src/Wasabi/api/wnd/wndclass/wndholder.h
new file mode 100644
index 00000000..580b8ba2
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndclass/wndholder.h
@@ -0,0 +1,285 @@
+#ifndef __WINDOWHOLDER_H
+#define __WINDOWHOLDER_H
+
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <bfc/ptrlist.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include <api/timer/timerclient.h>
+
+class svc_windowCreate;
+
+#define WINDOWHOLDER_PARENT GuiObjectWnd
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class WindowHolder : public Dispatchable
+{
+ public:
+ ifc_window *onInsertWindow(GUID g, const wchar_t *groupid);
+ void onRemoveWindow(int deferred=0);
+ int wantGuid(GUID g);
+ int wantGroup(const wchar_t *groupid);
+ GUID getCurGuid();
+ const wchar_t *getCurGroupId();
+ ifc_window *getCurRootWnd();
+ const wchar_t *getCurId();
+ ifc_window *getRootWndPtr();
+ int acceptsGenericGuid();
+ int acceptsGenericGroup();
+ int wndholder_getPreferences(int what);
+ void wndholder_onNeedReloadGroup(const wchar_t *id);
+ void cancelDeferredRemove();
+ int wndholder_wantAutoFocus();
+ int wndholder_isAutoAvailable();
+
+ enum {
+ WNDHOLDER_ONINSERTWINDOW=50,
+ WNDHOLDER_ONREMOVEWINDOW=100,
+ WNDHOLDER_WANTGUID=150,
+ WNDHOLDER_WANTGROUP=200,
+ WNDHOLDER_GETROOTWNDPTR=250,
+ WNDHOLDER_GETCURGUID=300,
+ WNDHOLDER_GETCURGROUPID=350,
+ WNDHOLDER_GETCURROOTWND=400,
+ WNDHOLDER_GETCURID=450,
+ WNDHOLDER_ISGENERICGUID=500,
+ WNDHOLDER_ISGENERICGROUP=550,
+ WNDHOLDER_GETPREFERENCES=600,
+ WNDHOLDER_ONNEEDRELOADGRP=650,
+ WNDHOLDER_CANCELDEFERREDREMOVE=660,
+ WNDHOLDER_WANTAUTOFOCUS=670,
+ WNDHOLDER_ISAUTOAVAILABLE=680,
+ };
+};
+
+inline ifc_window *WindowHolder::onInsertWindow(GUID g, const wchar_t *groupid) {
+ return _call(WNDHOLDER_ONINSERTWINDOW, (ifc_window *)NULL, g, groupid);
+}
+
+inline void WindowHolder::onRemoveWindow(int def) {
+ _voidcall(WNDHOLDER_ONREMOVEWINDOW, def);
+}
+
+inline int WindowHolder::wantGuid(GUID g) {
+ return _call(WNDHOLDER_WANTGUID, 0, g);
+}
+
+inline int WindowHolder::wantGroup(const wchar_t *groupid) {
+ return _call(WNDHOLDER_WANTGROUP, 0, groupid);
+}
+
+inline ifc_window *WindowHolder::getRootWndPtr() {
+ return _call(WNDHOLDER_GETROOTWNDPTR, (ifc_window *)NULL);
+}
+
+inline GUID WindowHolder::getCurGuid() {
+ return _call(WNDHOLDER_GETCURGUID, INVALID_GUID);
+}
+
+inline const wchar_t *WindowHolder::getCurGroupId() {
+ return _call(WNDHOLDER_GETCURGROUPID, (const wchar_t *)NULL);
+}
+
+inline ifc_window *WindowHolder::getCurRootWnd() {
+ return _call(WNDHOLDER_GETCURROOTWND, (ifc_window *)NULL);
+}
+
+inline const wchar_t *WindowHolder::getCurId() {
+ return _call(WNDHOLDER_GETCURID, (const wchar_t *)NULL);
+}
+
+inline int WindowHolder::acceptsGenericGuid() {
+ return _call(WNDHOLDER_ISGENERICGUID, 0);
+}
+
+inline int WindowHolder::acceptsGenericGroup() {
+ return _call(WNDHOLDER_ISGENERICGROUP, 0);
+}
+
+inline int WindowHolder::wndholder_getPreferences(int what) {
+ return _call(WNDHOLDER_GETPREFERENCES, 0, what);
+}
+
+inline void WindowHolder::wndholder_onNeedReloadGroup(const wchar_t *id) {
+ _voidcall(WNDHOLDER_ONNEEDRELOADGRP, id);
+}
+
+inline void WindowHolder::cancelDeferredRemove() {
+ _voidcall(WNDHOLDER_CANCELDEFERREDREMOVE);
+}
+
+inline int WindowHolder::wndholder_wantAutoFocus() {
+ return _call(WNDHOLDER_WANTAUTOFOCUS, 1);
+}
+
+inline int WindowHolder::wndholder_isAutoAvailable() {
+ return _call(WNDHOLDER_ISAUTOAVAILABLE, 1);
+}
+
+class DeferredRemove;
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class WindowHolderI : public WindowHolder {
+ public:
+
+ WindowHolderI();
+ virtual ~WindowHolderI();
+
+ virtual ifc_window *onInsertWindow(GUID g, const wchar_t *groupid);
+
+
+ virtual void onRemoveWindow(int deferred);
+
+
+ void addAcceptGuid(GUID g);
+ void addAcceptGroup(const wchar_t *groupid);
+ void setAcceptAllGuids(int tf);
+
+
+ void setAcceptAllGroups(int tf);
+
+ virtual int acceptsGenericGroup() { return generic_group; }
+
+ virtual int acceptsGenericGuid() { return generic_guid; }
+
+ virtual int wantGuid(GUID g);
+ virtual int wantGroup(const wchar_t *groupid);
+
+ virtual void onInsert(ifc_window *w, const wchar_t *id) {};
+
+ virtual void onRemove(ifc_window *w, const wchar_t *id) {};
+
+ virtual ifc_window *getRootWndPtr()=0;
+ virtual GUID getCurGuid() { return cur_guid; }
+ virtual const wchar_t *getCurGroupId() { return cur_groupid; }
+
+ virtual ifc_window *getCurRootWnd() { return wnd; }
+
+ virtual GUID *getFirstAcceptedGuid();
+ virtual const wchar_t *getFirstAcceptedGroup();
+ virtual const wchar_t *getCurId() { return cur_id; }
+
+ virtual void cancelDeferredRemove();
+ virtual int wndholder_isAutoAvailable() { return 1; }
+
+ GUID getDeferedGuid() { return defered_guid; }
+
+ virtual int wndholder_getPreferences(int what)=0;
+
+ virtual void wndholder_onNeedReloadGroup(const wchar_t *id);
+
+ private:
+
+
+ ifc_window *createWindow(const GUID *g, const wchar_t *groupid);
+ virtual int wndholder_wantAutoFocus();
+
+
+ void destroyWindow();
+
+ ifc_window *wnd;
+ GUID cur_guid;
+ StringW cur_groupid;
+ StringW cur_id;
+ PtrList<GUID> accepted_guids;
+ PtrList<StringW> accepted_groups;
+ int generic_guid;
+ int generic_group;
+
+ svc_windowCreate *wc_svc;
+ GUID defered_guid;
+
+ DeferredRemove *dr;
+
+ protected:
+
+ RECVS_DISPATCH;
+};
+
+
+/**
+ Class
+
+ @short
+ @author Nullsoft
+ @ver 1.0
+ @see
+*/
+class WindowHolderWnd : public WINDOWHOLDER_PARENT, public WindowHolderI
+{
+
+ public:
+
+ WindowHolderWnd();
+ virtual ~WindowHolderWnd();
+ virtual int onInit();
+
+ virtual ifc_window *getRootWndPtr() { return this; }
+ virtual void onInsert(ifc_window *w, const wchar_t *id);
+ virtual void onRemove(ifc_window *w, const wchar_t *id);
+ virtual int onResize();
+ virtual int handleRatio();
+ virtual int handleDesktopAlpha();
+ virtual int handleTransparency();
+ virtual int wndholder_getPreferences(int what) { return getPreferences(what); }
+ virtual int getPreferences(int what);
+ void setAutoOpen(int tf) { autoopen = tf; }
+ void setAutoClose(int tf) { autoclose = tf; }
+ void setNoCmdBar(int tf) { nocmdbar = tf; if (isInited()) invalidate(); }
+ void setNoAnim(int tf) { noanim = tf; }
+ virtual int onGroupChange(const wchar_t *grpid);
+ virtual int wndholder_wantAutoFocus();
+ void setAutoFocus(int autof) { autofocus = autof; }
+ void setAutoAvailable(int autoa) { autoavail = autoa; }
+ virtual int wndholder_isAutoAvailable() { return autoavail; }
+
+ private:
+ void notifyOnRemove(); // no virtual please
+ void notifyOnInsert(); // no virtual please
+ virtual void onSetVisible(int show);
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+
+ int autoopen;
+ int autoclose;
+ int nocmdbar;
+ int noanim;
+ int has_wnd;
+ int autofocus;
+ int autoavail;
+};
+
+class DeferredRemove : public TimerClientDI
+{
+ public:
+ DeferredRemove(WindowHolderI *parent) : whi(parent) {}
+ virtual ~DeferredRemove() {}
+
+ void post() {
+ timerclient_postDeferredCallback(1, 0);
+ }
+
+ virtual int timerclient_onDeferredCallback(intptr_t p1, intptr_t p2) {
+ if (p1 == 1 && whi != NULL) whi->onRemoveWindow(0);
+ else return TimerClientDI::timerclient_onDeferredCallback(p1, p2);
+ return 0;
+ }
+
+ private:
+ WindowHolderI *whi;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndevent.h b/Src/Wasabi/api/wnd/wndevent.h
new file mode 100644
index 00000000..20ece975
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndevent.h
@@ -0,0 +1,5 @@
+#ifndef _WNDEVENT_H
+#define _WNDEVENT_H
+
+
+#endif
diff --git a/Src/Wasabi/api/wnd/wndtrack.cpp b/Src/Wasabi/api/wnd/wndtrack.cpp
new file mode 100644
index 00000000..c378550e
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndtrack.cpp
@@ -0,0 +1,945 @@
+#include <precomp.h>
+#include <bfc/ptrlist.h>
+#include <api/wnd/basewnd.h>
+#include <bfc/util/findopenrect.h>
+#include <bfc/bfc_assert.h>
+#include <api/wndmgr/resize.h>
+#include <api/wnd/wndtrack.h>
+#include <api/config/items/attrint.h>
+#include <api/config/items/attrbool.h>
+#include <bfc/wasabi_std_wnd.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/snappnt.h>
+#endif
+
+#ifdef WASABI_COMPILE_SCRIPT
+#include <api/script/scriptobj.h>
+#include <api/script/scriptguid.h>
+#include <api/wnd/wndclass/guiobjwnd.h> // for appbar define
+#endif
+
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/wndmgr/layout.h>
+#include <api/wnd/popexitcb.h>
+#endif
+
+#ifdef WASABI_COMPILE_SYSCB
+//#include <api/syscb/cbmgr.h>
+#endif
+
+WindowTracker *windowTracker;
+
+WindowTracker::WindowTracker()
+ : coopcache(0),
+ coopcachewnd(NULL)
+{
+ wascoop = 0;
+ disabledock = 0;
+ dock_enabled = 1;
+}
+
+WindowTracker::~WindowTracker()
+{
+ coopList.deleteAll();
+}
+
+void WindowTracker::addWindow(ifc_window *wnd)
+{
+ ASSERT(wnd);
+ desktopwnds.addItem(wnd);
+}
+
+void WindowTracker::removeWindow(ifc_window *wnd)
+{
+ ASSERT(wnd);
+ ASSERTPR(desktopwnds.haveItem(wnd), "removewindow on invalid wnd");
+ desktopwnds.removeItem(wnd);
+}
+
+int WindowTracker::checkWindow(ifc_window *wnd)
+{
+ return allWnd.haveItem(wnd);
+}
+
+ifc_window *WindowTracker::enumWindows(int n)
+{
+ return desktopwnds.enumItem(n);
+}
+
+ifc_window *WindowTracker::getNextDesktopWindow(ifc_window *w, int next)
+{
+ ifc_window *nw = NULL;
+ if (w == NULL) nw = desktopwnds.getFirst();
+ else
+ {
+ w = w->getDesktopParent();
+ int pos = desktopwnds.searchItem(w);
+ if (pos == -1) nw = desktopwnds.getFirst();
+ else
+ {
+ pos += next;
+ if (pos > desktopwnds.getNumItems() - 1) pos = 0;
+ if (pos == -1) pos = desktopwnds.getNumItems() - 1;
+ nw = desktopwnds.enumItem(pos);
+ }
+ }
+ if (nw == w) return w;
+ if (!nw->isVisible()) return getNextDesktopWindow(nw, next);
+ return nw;
+}
+
+ifc_window *WindowTracker::enumAllWindows(int n)
+{
+ return allWnd.enumItem(n);
+}
+
+int WindowTracker::getNumWindows()
+{
+ return desktopwnds.getNumItems();
+}
+
+int WindowTracker::getNumAllWindows()
+{
+ return allWnd.getNumItems();
+}
+
+void WindowTracker::invalidateAllWindows()
+{
+ for (int i = allWnd.getNumItems() - 1;i >= 0;i--)
+ {
+ ifc_window *w = allWnd[i];
+ w->triggerEvent(TRIGGER_INVALIDATE);
+ w->invalidate();
+ if (!w->isVirtual()) continue;
+ w->triggerEvent(TRIGGER_ONRESIZE);
+ }
+}
+
+RECT WindowTracker::findOpenRect(const RECT &prev, ifc_window *exclude)
+{
+ POINT pp = { 0, 0 };
+ //CUT if (prev != NULL) {
+ pp.x = prev.left;
+ pp.y = prev.top;
+ //CUT }
+ RECT vr; // viewport rect
+ Wasabi::Std::getViewport(&vr, &pp);
+
+ // make a rect list
+ PtrList<RECT> list;
+ for (int i = 0; ; i++)
+ {
+ ifc_window *wnd = enumWindows(i);
+ if (wnd == NULL) break;
+ if (wnd == exclude) continue;
+ if (!wnd->isPostOnInit() && !wnd->isVisible()) continue;
+ RECT *r = new RECT;
+ wnd->getWindowRect(r);
+ snapAdjustWindowRect(wnd, r);
+ list.addItem(r);
+ }
+
+ FindOpenRect fr;
+ RECT ret = fr.find(vr, list, prev);
+ list.deleteAll();
+ return ret;
+}
+
+void WindowTracker::setDockDistance(int dd)
+{
+ dockDist = MINMAX(dd, MIN_DOCK_DIST, MAX_DOCK_DIST);
+}
+
+int WindowTracker::getDockDistance()
+{
+ if (dock_enabled) return dockDist;
+ return 0;
+}
+
+void WindowTracker::setEnableDocking(int ed)
+{
+ dock_enabled = ed;
+}
+
+bool WindowTracker::touches(const RECT &r2, const RECT &r1)
+{
+ if (r2.left == r1.right || r2.right == r1.left || r2.right == r1.right || r2.left == r1.left)
+ {
+ if (r2.bottom >= r1.top && r2.top <= r1.bottom)
+ return true;
+ }
+ if (r2.top == r1.bottom || r2.bottom == r1.top || r2.bottom == r1.bottom || r2.top == r1.top)
+ {
+ if (r2.right >= r1.left && r2.left <= r1.right)
+ return true;
+ }
+ return false;
+}
+
+void WindowTracker::endCooperativeMove()
+{
+ wascoop = 1;
+ flushCoopWnds();
+ coopWnd = NULL;
+ recursList.removeAll();
+}
+
+void WindowTracker::startCooperativeMove(ifc_window *thiswnd)
+{
+ coopWnd = thiswnd;
+ wascoop = 1;
+ flushCoopWnds();
+ if (recursList.getNumItems() > 0) recursList.removeAll();
+ addCooperative(thiswnd);
+ foreach_reverse(recursList)
+ // FG> we need to prevent windows from excessively activating our windows or focus is gonna blow up
+ // thiswnd->bringToFront();
+#ifdef WIN32
+ SetWindowPos(recursList.getfor()->gethWnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+#else
+ recursList.getfor()->bringToFront();
+#endif
+ endfor;
+}
+
+int WindowTracker::getNumDocked()
+{
+ return recursList.getNumItems();
+}
+
+ifc_window *WindowTracker::enumDocked(int n)
+{
+ return recursList.enumItem(n);
+}
+
+void WindowTracker::addCooperative(ifc_window *thiswnd)
+{
+ int i;
+ RECT r;
+ RECT thisr;
+ bool forceall = false;
+
+ if (Std::keyModifier(STDKEY_ALT))
+ {
+ forceall = TRUE;
+ }
+
+#ifdef WASABI_COMPILE_WNDMGR
+ Layout *l = static_cast<Layout *>(thiswnd->getInterface(layoutGuid));
+ if (l)
+ {
+ for (int i = 0; i < l->getNumLockedLayouts(); i++)
+ {
+ ifc_window *wnd = l->enumLockedLayout(i);
+ addCoopWnd(wnd, 1);
+ addCooperative(wnd);
+ }
+ }
+#endif
+
+ if (recursList.searchItem(thiswnd) != -1) return ;
+
+ recursList.addItem(thiswnd);
+
+ if (Std::keyModifier(STDKEY_SHIFT)) return ;
+
+ thiswnd->getWindowRect(&thisr);
+ snapAdjustWindowRect(thiswnd, &thisr);
+
+ for (i = 0; i < desktopwnds.getNumItems(); i++)
+ {
+ ifc_window *wnd = desktopwnds.enumItem(i);
+ if (!wnd->isVisible()) continue;
+ if (hasCoopWnd(wnd)) continue;
+ if (wnd == thiswnd) continue;
+ Layout *l = (Layout*)wnd->getInterface(layoutGuid);
+ if (l && (l->getNoDock()
+#ifdef USEAPPBAR
+ || l->appbar_isDocked()
+#endif
+ )) continue;
+ wnd->getWindowRect(&r);
+ snapAdjustWindowRect(wnd, &r);
+
+#ifdef WASABI_COMPILE_WNDMGR
+ int snap = SnapPoint::match(thiswnd, NULL, wnd, KEEPSIZE, NULL, NULL, 0, 0);
+ if (forceall || snap || (touches(r, thisr) && !Wasabi::Std::rectIntersect(r, thisr)))
+ {
+#else
+ if (forceall || (touches(r, thisr) && !Std::rectIntersect(r, thisr)))
+ {
+#endif
+ addCoopWnd(wnd);
+ addCooperative(wnd);
+ }
+ }
+}
+
+bool WindowTracker::autoDock(ifc_window *thishWnd, RECT *newPosition, int mask)
+{
+ return autoDock(thishWnd, newPosition, NULL, mask);
+}
+
+bool WindowTracker::autoDock(ifc_window *thiswnd, RECT *z, RECT *_oldPosition, int mask)
+{
+ int i = 0;
+ RECT r = {0};
+#ifdef WASABI_COMPILE_CONFIG
+ extern _bool cfg_options_docking;
+ extern _int cfg_options_dockingdistance;
+
+ dockDist = cfg_options_dockingdistance;
+ dock_enabled = cfg_options_docking;
+#else
+#warning check these values
+ dockDist = 4;
+ dock_enabled = 4;
+#endif
+
+#ifdef USEAPPBAR
+ // Layout *_l = static_cast<Layout *>(thiswnd->getInterface(layoutGuid));
+ // if (_l->appbar_isDocked()) return 0;
+#endif
+
+ RECT z_snapAdjust = {0};
+ snapAdjustWindowRect(thiswnd, z, &z_snapAdjust);
+ RECT *oldPosition = _oldPosition;
+ if (oldPosition)
+ {
+ oldPosition->left += z_snapAdjust.left;
+ oldPosition->top += z_snapAdjust.top;
+ }
+
+ if (!coopWnd)
+ wascoop = 0;
+
+ disabledock = 0;
+
+ if (Std::keyModifier(STDKEY_SHIFT))
+ {
+ for (int i = 0;i < coopList.getNumItems();i++)
+ {
+ coopEntry *e = coopList.enumItem(i);
+ if (!e->locked)
+ {
+ delete e;
+ coopList.removeByPos(i);
+ coopcachewnd = NULL;
+ i--;
+ }
+ }
+ disabledock = 1;
+ }
+
+ int f = 0, s = 0;
+ int w = z->right - z->left;
+ int h = z->bottom - z->top;
+
+ POINT done = {0};
+
+ if (!disabledock)
+ {
+ ifc_window *wnd = NULL;
+ for (i = desktopwnds.getNumItems(); i > -1; i--)
+ {
+ if (i == desktopwnds.getNumItems())
+ {
+#ifdef USEAPPBAR
+ Layout *l = static_cast<Layout *>(thiswnd->getInterface(layoutGuid));
+ if (l->appbar_isDocked()) continue;
+#endif
+ Wasabi::Std::getViewport(&r, thiswnd->gethWnd());
+ wnd = NULL;
+ }
+ else
+ {
+ wnd = desktopwnds.enumItem(i);
+ if (coopWnd != NULL && hasCoopWnd(wnd)) continue;
+ Layout *l = (Layout*)wnd->getInterface(layoutGuid);
+ if (l && (l->getNoDock()
+#ifdef USEAPPBAR
+ || l->appbar_isDocked()
+#endif
+ )) continue;
+
+ if (wnd->isVisible())
+ {
+ wnd->getWindowRect(&r);
+ snapAdjustWindowRect(wnd, &r);
+ }
+ else continue;
+ }
+
+ if (coopWnd != NULL && coopWnd == wnd || (i >= 0 && hasCoopWnd(desktopwnds.enumItem(i)))) continue;
+
+ if (thiswnd == wnd) continue;
+
+ RECT oz = *z;
+ POINT thisdone = {0};
+
+#ifdef WASABI_COMPILE_WNDMGR
+ if (SnapPoint::match(thiswnd, z, wnd, mask, (int *)&thisdone.x, (int *)&thisdone.y, w, h)) s++;
+#endif
+ if (z->left > r.left - getDockDistance() && z->left < r.left + getDockDistance() && (mask & LEFT) && !thisdone.x)
+ {
+ z->left = r.left;
+ thisdone.x = 1;
+ if (mask & KEEPSIZE) z->right = r.left + w;
+ f++;
+ }
+ if (i != desktopwnds.getNumItems() && z->right > r.left - getDockDistance() && z->right < r.left + getDockDistance() && (mask & RIGHT) && !thisdone.x)
+ {
+ z->right = r.left;
+ thisdone.x = 1;
+ if (mask & KEEPSIZE) z->left = r.left - w;
+ f++;
+ }
+ if (z->top > r.top - getDockDistance() && z->top < r.top + getDockDistance() && (mask & TOP) && !thisdone.y)
+ {
+ z->top = r.top;
+ thisdone.y = 1;
+ if (mask & KEEPSIZE) z->bottom = r.top + h;
+ f++;
+ }
+ if (i != desktopwnds.getNumItems() && z->bottom > r.top - getDockDistance() && z->bottom < r.top + getDockDistance() && (mask & BOTTOM) && !thisdone.y)
+ {
+ z->bottom = r.top;
+ thisdone.y = 1;
+ if (mask & KEEPSIZE) z->top = r.top - h;
+ f++;
+ }
+ if (z->right > r.right - getDockDistance() && z->right < r.right + getDockDistance() && (mask & RIGHT) && !thisdone.x)
+ {
+ z->right = r.right;
+ thisdone.x = 1;
+ if (mask & KEEPSIZE) z->left = r.right - w;
+ f++;
+ }
+ if (i != desktopwnds.getNumItems() && z->left > r.right - getDockDistance() && z->left < r.right + getDockDistance() && (mask & LEFT) && !thisdone.x)
+ {
+ z->left = r.right;
+ thisdone.x = 1;
+ if (mask & KEEPSIZE) z->right = r.right + w;
+ f++;
+ }
+
+ if (z->bottom > r.bottom - getDockDistance() && z->bottom < r.bottom + getDockDistance() && (mask & BOTTOM) && !thisdone.y)
+ {
+ z->bottom = r.bottom;
+ thisdone.y = 1;
+ if (mask & KEEPSIZE) z->top = r.bottom - h;
+ f++;
+ }
+
+ if (i != desktopwnds.getNumItems() && z->top > r.bottom - getDockDistance() && z->top < r.bottom + getDockDistance() && (mask & TOP) && !thisdone.y)
+ {
+ z->top = r.bottom;
+ thisdone.y = 1;
+ if (mask & KEEPSIZE) z->bottom = r.bottom + h;
+ f++;
+ }
+
+ if (((wnd != NULL && (mask & NOINTERSECT) && Wasabi::Std::rectIntersect(*z, r)) || !touches(*z, r)) && !s)
+ {
+ *z = oz;
+ thisdone.x = 0;
+ thisdone.y = 0;
+ }
+
+ done.x |= thisdone.x;
+ done.y |= thisdone.y;
+ }
+ }
+
+ if (coopWnd == thiswnd && oldPosition)
+ {
+ POINT s = {0}, redock = {0};
+ TList<RECT> rlist;
+ s.x = z->left - oldPosition->left;
+ s.y = z->top - oldPosition->top;
+ for (i = 0;i < coopList.getNumItems();i++)
+ {
+ RECT r = {0};
+ ifc_window *W = coopList.enumItem(i)->wnd;
+ if (!checkWindow(W)) { coopEntry *e = coopList.enumItem(i); delete e; coopList.removeByPos(i); i--; continue; }
+ if (W != (BaseWnd*) - 1)
+ {
+ W->getWindowRect(&r);
+ //snapAdjustWindowRect(W, &r);
+ }
+#ifdef WIN32
+ else
+ GetWindowRect(WASABI_API_WND->main_getRootWnd()->gethWnd(), &r);
+#endif
+ int w = r.right - r.left, h = r.bottom - r.top;
+ r.left += s.x;
+ r.top += s.y;
+ r.right = r.left + w;
+ r.bottom = r.top + h;
+ RECT cr = r;
+ if (autoDock(W, &cr, LEFT | RIGHT | TOP | BOTTOM | NOINTERSECT | KEEPSIZE))
+ {
+ if (redock.x == 0) redock.x = cr.left - r.left;
+ if (redock.y == 0) redock.y = cr.top - r.top;
+ }
+ rlist.addItem(r);
+ }
+
+ if (redock.x || redock.y)
+ {
+ Wasabi::Std::offsetRect(z, redock.x, redock.y);
+ f++;
+ }
+#ifdef WIN32
+ HDWP hd = NULL;
+ if (coopList.getNumItems() > 0) hd = BeginDeferWindowPos(coopList.getNumItems());
+#endif
+ for (i = 0;i < coopList.getNumItems();i++)
+ {
+ RECT r = rlist.enumItem(i);
+ ifc_window *W = coopList.enumItem(i)->wnd;
+ r.left += redock.x;
+ r.top += redock.y;
+ //unsnapAdjustWindowRect(W, &r);
+#ifdef WIN32
+ W->notifyDeferredMove(r.left, r.top);
+ //if (GetWindow(W->gethWnd(), GW_OWNER))
+// SetWindowPos(W->gethWnd(), NULL, r.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
+// else
+ hd = DeferWindowPos(hd, W->gethWnd(), NULL, r.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
+#else
+ W->move( r.left, r.top );
+#endif
+ }
+ foreach(coopList)
+ ifc_window *w = coopList.getfor()->wnd;
+ if (w != coopWnd)
+ {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ l->beginMove();
+ }
+ }
+ endfor;
+#ifdef WIN32
+ if (coopList.getNumItems() > 0) EndDeferWindowPos(hd);
+#endif
+ foreach(coopList)
+ ifc_window *w = coopList.getfor()->wnd;
+ if (w != coopWnd)
+ {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ l->onMove();
+ l->endMove();
+ }
+ }
+ endfor;
+ rlist.removeAll();
+ }
+
+ z->left -= z_snapAdjust.left;
+ z->top -= z_snapAdjust.top;
+ z->right += z_snapAdjust.right;
+ z->bottom += z_snapAdjust.bottom;
+
+ return ((f + s) != 0);
+}
+
+int WindowTracker::hasCoopWnd(ifc_window *w)
+{
+ if (coopcachewnd == w) return coopcache;
+ coopcachewnd = w;
+ coopcache = 0;
+ for (int i = 0;i < coopList.getNumItems();i++)
+ if (coopList.enumItem(i)->wnd == w)
+ {
+ coopcache = 1;
+ break;
+ }
+ return coopcache;
+}
+
+void WindowTracker::addCoopWnd(ifc_window *w, int forced)
+{
+ coopList.addItem(new coopEntry(w, forced));
+ coopcachewnd = NULL;
+}
+
+void WindowTracker::flushCoopWnds()
+{
+ coopList.deleteAll();
+ coopcachewnd = NULL;
+}
+
+void WindowTracker::addRootWnd(ifc_window *wnd)
+{
+ ASSERT(!allWnd.haveItem(wnd));
+ allWnd.addItem(wnd);
+ if (!wnd->isVirtual())
+ {
+ ASSERT(!nonvirtuals.haveItem(wnd));
+ nonvirtuals.addItem(wnd);
+ }
+}
+
+void WindowTracker::removeRootWnd(ifc_window *wnd)
+{
+ allWnd.delItem(wnd);
+ if (allWnd.getNumItems() == 0) allWnd.deleteAll(); // avoid fortify fals alarm on static
+ int n = nonvirtuals.searchItem(wnd);
+ if (n > -1) nonvirtuals.removeByPos(n);
+}
+
+ifc_window *WindowTracker::rootWndFromPoint(POINT *pt)
+{
+ /* api_window *last = NULL;
+ api_window *last_parent = NULL;
+ for (int i=0;i<allWnd.getNumItems();i++) {
+ api_window *w = allWnd[i];
+ if (last && w->getRootWndParent() != last_parent)
+ return checkGhost(last, (signed short)pt->x, (signed short)pt->y);
+ if (w->pointInWnd(pt)) {
+ if (!w->getRootWndParent() || w->gethWnd() != w->getRootWndParent()->gethWnd()) return checkGhost(w, (signed short)pt->x, (signed short)pt->y);
+ last = w;
+ last_parent = w->getRootWndParent();
+ }
+ }
+ return NULL;*/
+
+ // Get window's top level window for pt
+#ifdef _WIN32
+ OSWINDOWHANDLE t = WindowFromPoint(*pt);
+ if (!t) return NULL;
+
+ //CHECK IF SAFE ! if (!rootWndFromHwnd(t)) return NULL;
+
+ // Find its rootWnd
+ for (int i = nonvirtuals.getNumItems() - 1;i >= 0;i--)
+ {
+ ifc_window *r = nonvirtuals[i];
+ if (r->gethWnd() == t)
+ {
+ POINT p = *pt;
+ r->screenToClient((int*)&p.x, (int *)&p.y);
+ return r->findRootWndChild(p.x, p.y);
+ }
+ }
+#else
+#warning port me!
+#endif
+ return NULL;
+}
+
+ifc_window *WindowTracker::rootWndFromHwnd(OSWINDOWHANDLE h)
+{
+ if (!h) return NULL;
+ // Find its rootWnd
+ for (int i = 0;i < allWnd.getNumItems();i++)
+ {
+ ifc_window *r = allWnd[i];
+ if (r->gethWnd() == h) return r;
+ }
+ return NULL;
+}
+
+int WindowTracker::wasCooperativeMove()
+{
+ return wascoop;
+}
+
+// TODO: can be moved to a static function - doesn't seem to use any class data
+void WindowTracker::snapAdjustWindowRect(ifc_window *w, RECT *r, RECT *adjustvals)
+{
+#ifdef WASABI_COMPILE_WNDMGR
+ if (w->getInterface(layoutGuid))
+ {
+ RECT snapAdjust = {0};
+ static_cast<Layout *>(w)->getSnapAdjust(&snapAdjust);
+ double rr = w->getRenderRatio();
+ if (rr != 1.0)
+ {
+ snapAdjust.left = (int)((double)(snapAdjust.left) * rr);
+ snapAdjust.top = (int)((double)(snapAdjust.top) * rr);
+ snapAdjust.right = (int)((double)(snapAdjust.right) * rr);
+ snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr);
+ }
+ r->left += snapAdjust.left;
+ r->top += snapAdjust.top;
+ r->right -= snapAdjust.right;
+ r->bottom -= snapAdjust.bottom;
+ if (adjustvals) *adjustvals = snapAdjust;
+ }
+ else { adjustvals = NULL; }
+#else
+ if (adjustvals) MEMSET(adjustvals, 0, sizeof(RECT));
+#endif
+}
+
+void WindowTracker::unsnapAdjustWindowRect(ifc_window *w, RECT *r, RECT *adjustvals)
+{
+#ifdef WASABI_COMPILE_WNDMGR
+ if (w->getInterface(layoutGuid))
+ {
+ RECT snapAdjust = {0};
+ static_cast<Layout *>(w)->getSnapAdjust(&snapAdjust);
+ if (w->getRenderRatio() != 1.0)
+ {
+ double rr = w->getRenderRatio();
+ snapAdjust.left = (int)((double)(snapAdjust.left) * rr);
+ snapAdjust.top = (int)((double)(snapAdjust.top) * rr);
+ snapAdjust.right = (int)((double)(snapAdjust.right) * rr);
+ snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr);
+ }
+ r->left -= snapAdjust.left;
+ r->top -= snapAdjust.top;
+ r->right += snapAdjust.right;
+ r->bottom += snapAdjust.bottom;
+ if (adjustvals) *adjustvals = snapAdjust;
+ }
+ else { adjustvals = NULL; }
+#else
+ if (adjustvals) MEMSET(adjustvals, 0, sizeof(RECT));
+#endif
+}
+
+void WindowTracker::recursAddToMoveWindows(ifc_window *wnd, redock_struct *rs, int v)
+{
+ if (!rs) return ;
+ RECT r1;
+ if (wnd != NULL)
+ {
+ wnd->getWindowRect(&r1);
+ snapAdjustWindowRect(wnd, &r1);
+ }
+ else
+ {
+ wnd = rs->l;
+ r1 = rs->original_rect;
+ if (!WASABI_API_WND->rootwndIsValid(wnd)) return ;
+ }
+
+ {
+ Layout *l = (Layout*)wnd->getInterface(layoutGuid);
+ if (l && (l->getNoDock()
+#ifdef USEAPPBAR
+ || l->appbar_isDocked()
+#endif
+ )) return ;
+ }
+
+ // add all touching windows
+ for (int i = 0; i < desktopwnds.getNumItems(); i++)
+ {
+ ifc_window *w = desktopwnds[i];
+ if (!w->isVisible()) continue;
+ if (w == wnd) continue;
+ Layout *l = (Layout*)w->getInterface(layoutGuid);
+ if (l && (l->getNoDock()
+#ifdef USEAPPBAR
+ || l->appbar_isDocked()
+#endif
+ )) continue;
+ RECT r2;
+ w->getWindowRect(&r2);
+ snapAdjustWindowRect(w, &r2);
+ // check for bottom touch
+ if ((v == 1 || v == -1) && r2.top == r1.bottom && !tomoveWindows_bottom.haveItem(w))
+ {
+ if (r2.right >= r1.left && r2.left <= r1.right)
+ {
+ tomoveWindows_bottom.addItem(w);
+ recursAddToMoveWindows(w, rs, 1);
+ }
+ }
+ // check for right touch
+ if ((v == 0 || v == -1) && r2.left == r1.right && !tomoveWindows_right.haveItem(w))
+ {
+ if (r2.bottom >= r1.top && r2.top <= r1.bottom)
+ {
+ tomoveWindows_right.addItem(w);
+ recursAddToMoveWindows(w, rs, 0);
+ }
+ }
+ // check for left touch
+ if ((v == 0 || v == -1) && r2.right == r1.left && !tomoveWindows_left.haveItem(w))
+ {
+ if (r2.bottom >= r1.top && r2.top <= r1.bottom)
+ {
+ tomoveWindows_left.addItem(w);
+ recursAddToMoveWindows(w, rs, 0);
+ }
+ }
+ // check for top touch
+ if ((v == 1 || v == -1) && r2.bottom == r1.top && !tomoveWindows_top.haveItem(w))
+ {
+ if (r2.right >= r1.left && r2.left <= r1.right)
+ {
+ tomoveWindows_top.addItem(w);
+ recursAddToMoveWindows(w, rs, 1);
+ }
+ }
+ }
+}
+
+void WindowTracker::beforeRedock(Layout *l, redock_struct *rs)
+{
+ if (!l) return ;
+ rs->l = l;
+ l->getWindowRect(&rs->original_rect);
+ snapAdjustWindowRect(rs->l, &rs->original_rect);
+}
+
+void WindowTracker::afterRedock(Layout *l, redock_struct *rs)
+{
+ RECT nr;
+ if (!rs) return ;
+
+ if (!WASABI_API_WND->rootwndIsValid(l)) return ;
+ if (!WASABI_API_WND->rootwndIsValid(rs->l)) return ;
+ recursAddToMoveWindows(NULL, rs);
+
+ l->getWindowRect(&nr);
+ snapAdjustWindowRect(l, &nr);
+
+ if (l->isUnlinked() || rs->l->isUnlinked()) return ;
+
+#ifdef WIN32
+ HDWP hdwp = BeginDeferWindowPos(desktopwnds.getNumItems());
+#endif
+
+ PtrList<Layout> toendmove;
+
+ int diff = rs->original_rect.bottom - nr.bottom;
+ if (diff)
+ { // check for bottom side dock changes
+ for (int i = 0;i < tomoveWindows_bottom.getNumItems();i++)
+ {
+ ifc_window *w = tomoveWindows_bottom[i];
+ if (w == l) continue;
+ if (w == rs->l) continue;
+ if (!allWnd.haveItem(w)) continue;
+ RECT r;
+ w->getWindowRect(&r);
+ r.top -= diff;
+ r.bottom -= diff;
+#ifdef WIN32
+ w->notifyDeferredMove(r.left, r.top);
+ DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
+#else
+ w->move( r.left, r.top );
+#endif
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l) toendmove.addItem(l);
+ }
+ }
+
+ diff = rs->original_rect.top - nr.top;
+ if (diff)
+ { // check for top side dock changes
+ for (int i = 0;i < tomoveWindows_top.getNumItems();i++)
+ {
+ ifc_window *w = tomoveWindows_top[i];
+ if (w == l) continue;
+ if (w == rs->l) continue;
+ if (!allWnd.haveItem(w)) continue;
+ RECT r;
+ w->getWindowRect(&r);
+ r.top -= diff;
+ r.bottom -= diff;
+#ifdef WIN32
+ w->notifyDeferredMove(r.left, r.top);
+ DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
+#else
+ w->move( r.left, r.top );
+#endif
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l) toendmove.addItem(l);
+ }
+ }
+
+ diff = rs->original_rect.right - nr.right;
+ if (diff)
+ { // check for right side dock changes
+ for (int i = 0;i < tomoveWindows_right.getNumItems();i++)
+ {
+ ifc_window *w = tomoveWindows_right[i];
+ if (w == l) continue;
+ if (w == rs->l) continue;
+ if (!allWnd.haveItem(w)) continue;
+ RECT r;
+ w->getWindowRect(&r);
+ r.left -= diff;
+ r.right -= diff;
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l) l->beginMove();
+#ifdef WIN32
+ w->notifyDeferredMove(r.left, r.top);
+ DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
+#else
+ w->move( r.left, r.top );
+#endif
+ if (l) toendmove.addItem(l);
+ }
+ }
+
+ diff = rs->original_rect.left - nr.left;
+ if (diff)
+ { // check for left side dock changes
+ for (int i = 0;i < tomoveWindows_left.getNumItems();i++)
+ {
+ ifc_window *w = tomoveWindows_left[i];
+ if (w == l) continue;
+ if (w == rs->l) continue;
+ if (!allWnd.haveItem(w)) continue;
+ RECT r;
+ w->getWindowRect(&r);
+ r.left -= diff;
+ r.right -= diff;
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l) l->beginMove();
+#ifdef WIN32
+ w->notifyDeferredMove(r.left, r.top);
+ DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
+#else
+ w->move( r.left, r.top );
+#endif
+ if (l) toendmove.addItem(l);
+ }
+ }
+
+#ifdef WIN32
+ EndDeferWindowPos(hdwp);
+#endif
+ tomoveWindows_left.removeAll();
+ tomoveWindows_top.removeAll();
+ tomoveWindows_right.removeAll();
+ tomoveWindows_bottom.removeAll();
+ rs->l = NULL;
+ foreach(toendmove)
+ toendmove.getfor()->onMove();
+ toendmove.getfor()->endMove();
+ endfor;
+}
+
+void WindowTracker::layoutChanged(Layout *previouswnd, Layout *newwnd)
+{
+ redock_struct rs;
+ beforeRedock(previouswnd, &rs);
+ afterRedock(newwnd, &rs);
+}
+
+ifc_window *WindowTracker::coopWnd = NULL;
+PtrList<ifc_window> WindowTracker::desktopwnds;
+PtrList<ifc_window> WindowTracker::nonvirtuals;
+PtrList<coopEntry> WindowTracker::coopList;
+PtrList<ifc_window> WindowTracker::recursList;
+PtrList<ifc_window> WindowTracker::tomoveWindows_left;
+PtrList<ifc_window> WindowTracker::tomoveWindows_top;
+PtrList<ifc_window> WindowTracker::tomoveWindows_right;
+PtrList<ifc_window> WindowTracker::tomoveWindows_bottom;
+PtrList<ifc_window> WindowTracker::allWnd;
+int WindowTracker::dockDist = DEFAULT_DOCK_DIST;
+int WindowTracker::dock_enabled = 1;
diff --git a/Src/Wasabi/api/wnd/wndtrack.h b/Src/Wasabi/api/wnd/wndtrack.h
new file mode 100644
index 00000000..f4f33d80
--- /dev/null
+++ b/Src/Wasabi/api/wnd/wndtrack.h
@@ -0,0 +1,104 @@
+#ifndef __WNDTRACK_H
+#define __WNDTRACK_H
+
+#include "cwndtrack.h"
+#include <bfc/tlist.h>
+#include <bfc/ptrlist.h>
+#include <api/wndmgr/layout.h>
+
+class ifc_window;
+
+#define WNDTRACKCB_POPUPEXIT 0x8797
+#define WNDTRACKCB_POPUPEXITALL 0x8798
+
+const int DEFAULT_DOCK_DIST=10;
+const int MIN_DOCK_DIST=1;
+const int MAX_DOCK_DIST=64;
+
+class coopEntry {
+ public:
+ coopEntry(ifc_window *w, int lock=0) : wnd(w), locked(lock) {}
+ ~coopEntry() {}
+
+ ifc_window *wnd;
+ int locked;
+};
+
+#ifndef _REDOCK_STRUCT_DEFINED
+#define _REDOCK_STRUCT_DEFINED
+typedef struct {
+ Layout *l;
+ RECT original_rect;
+} redock_struct;
+#endif
+
+class WindowTracker {
+public:
+ WindowTracker();
+ ~WindowTracker();
+
+ void addWindow(ifc_window *wnd);
+ void removeWindow(ifc_window *wnd);
+ int checkWindow(ifc_window *wnd);
+ ifc_window *enumWindows(int n);
+ int getNumWindows();
+ ifc_window *enumAllWindows(int n);
+ int getNumAllWindows();
+ bool autoDock(ifc_window *thiswnd, RECT *newPosition, int mask);
+ bool autoDock(ifc_window *thiswnd, RECT *newPosition, RECT *oldPosition, int mask);
+ static bool touches(const RECT &z, const RECT &r);
+
+ RECT findOpenRect(const RECT &prev, ifc_window *exclude=NULL);
+
+ static void setDockDistance(int dd);
+ static int getDockDistance();
+ static void setEnableDocking(int ed);
+
+ void startCooperativeMove(ifc_window *wnd);
+ void endCooperativeMove();
+ int wasCooperativeMove();
+ void invalidateAllWindows();
+ int getNumDocked();
+ ifc_window *enumDocked(int n);
+
+ static void addRootWnd(ifc_window *wnd);
+ static void removeRootWnd(ifc_window *wnd);
+ static ifc_window *rootWndFromPoint(POINT *pt);
+ static ifc_window *rootWndFromHwnd(OSWINDOWHANDLE h);
+ static void layoutChanged(Layout *previouswnd, Layout *newwnd); // re-dock windows when changing layout
+
+ static void beforeRedock(Layout *l, redock_struct *rs);
+ static void afterRedock(Layout *l, redock_struct *rs);
+ static ifc_window *getNextDesktopWindow(ifc_window *w, int next);
+ static void snapAdjustWindowRect(ifc_window *w, RECT *r, RECT *adjustvals=NULL);
+ static void unsnapAdjustWindowRect(ifc_window *w, RECT *r, RECT *adjustvals=NULL);
+
+private:
+ void addCooperative(ifc_window *thiswnd);
+ void addCoopWnd(ifc_window *w, int forced=0);
+ int hasCoopWnd(ifc_window *w);
+ void flushCoopWnds();
+ static void recursAddToMoveWindows(ifc_window *wnd, redock_struct *rs, int v=-1); // used by layoutChanged()
+
+ static PtrList<ifc_window> desktopwnds;
+ static PtrList<ifc_window> nonvirtuals;
+ static PtrList<coopEntry> coopList;
+ static PtrList<ifc_window> recursList;
+ static ifc_window *coopWnd;
+ static PtrList<ifc_window> allWnd;
+ static PtrList<ifc_window> tomoveWindows_top;
+ static PtrList<ifc_window> tomoveWindows_left;
+ static PtrList<ifc_window> tomoveWindows_bottom;
+ static PtrList<ifc_window> tomoveWindows_right;
+
+ static int dockDist;
+ static int dock_enabled;
+ int wascoop;
+ int disabledock;
+ ifc_window *coopcachewnd;
+ int coopcache;
+};
+
+extern WindowTracker *windowTracker;
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/alphamgr.cpp b/Src/Wasabi/api/wndmgr/alphamgr.cpp
new file mode 100644
index 00000000..0bcf7fe0
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/alphamgr.cpp
@@ -0,0 +1,661 @@
+#include <precomp.h>
+#include "alphamgr.h"
+#include <api/wndmgr/layout.h>
+#include <api/skin/skinparse.h>
+#ifdef _WIN32
+#include <tataki/blending/blending.h>
+#endif
+#include <bfc/util/profiler.h>
+#include <bfc/wasabi_std_wnd.h>
+
+#ifndef PI
+#define PI 3.1415926536
+#endif
+
+#define ALPHAMGR_HOVERCHECK 100
+#define ALPHAMGR_UPDATEALPHA 200
+
+AlphaMgr::AlphaMgr() {
+ overlayout = NULL;
+ timerclient_setTimer(ALPHAMGR_HOVERCHECK, 200);
+ alllinked = 0;
+ autoopacify = 0;
+ fast_timer_on = 0;
+ big_curtransparency = 0;
+ big_status = STATUS_UNKNOWN;
+ big_startalpha = 0;
+ big_lasttimein = 0;
+ extend_px = 0;
+ global_alpha = 0;
+ big_enterleave_time = 0;
+ fadein_ms = 1;
+ fadeout_ms = 1;
+ holdtime_ms = 1;
+}
+
+AlphaMgr::~AlphaMgr()
+{
+ timerclient_killTimer(ALPHAMGR_HOVERCHECK);
+}
+
+void AlphaMgr::addLayout(Layout *l)
+{
+ checkTimer();
+
+ if (layouts.findItem((const wchar_t *)l))
+ return;
+
+ layouts.addItem(new AlphaMgrEntry(l));
+}
+
+void AlphaMgr::removeLayout(Layout *l) {
+ int p=-1;
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l, &p);
+ if (p != -1) {
+ if (e->getStatus() == STATUS_IN_FADINGON || e->getStatus() == STATUS_IN_ON) {
+ updateInList(e, 0);
+ checkTimer();
+ }
+ layouts.removeByPos(p);
+ in_layouts.removeItem(e);
+ delete e;
+ checkTimer();
+ }
+}
+
+// gets the currently needed transparency, according to layout overrides and global link, and then applies this
+// transparency to the layout, it does not change anything in any data structure, this is only a visual update function
+void AlphaMgr::updateTransparency(Layout *l) {
+ if (!l) return;
+ if (l->isInited()) {
+ if (l->isTransparencySafe()) {
+ int a = l->getTransparencyOverride();
+ if (a == -1) {
+ if (l->getNoParent()!=1) {
+ if (a == -1 && hasAutoOpacity(l))
+ a = getTransparency(l);
+ else if (a == -1 && getAllLinked())
+ a = getGlobalAlpha();
+ }
+ if (a == -1) {
+ /* why the hell would it care if it's alllinked if it's an independent window ?? (noparent=1)
+ if (getAllLinked())
+ a = getGlobalAlpha();
+ else
+ */
+ a = l->getPaintingAlpha();
+ }
+ }
+ l->setTransparency(a);
+ } else {
+ l->setTransparency(255);
+ }
+ }
+}
+
+// returns the alpha value for this slot, that's not necessarily the transparency that should be applied to the layout
+// since overrides & calculations in updateTransparency and getTransparency should apply.
+int AlphaMgr::getAlpha(AlphaMgrEntry *e) {
+ if (alllinked && e->getLayout()->getNoParent() != 1) return getGlobalAlpha();
+ return e->getLayout()->getAlpha();
+}
+
+int AlphaMgr::getAlpha(Layout *l) {
+ int p=-1;
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l, &p);
+ if (p != -1) return getAlpha(e);
+ return l->getAlpha();
+}
+
+int AlphaMgr::getGlobalAlpha() {
+ return global_alpha;
+}
+
+void AlphaMgr::updateAllTransparency() {
+ foreach(layouts)
+ updateTransparency(layouts.getfor()->getLayout());
+ endfor;
+}
+
+void AlphaMgr::setGlobalAlpha(int a) {
+ global_alpha = a;
+ updateAllTransparency();
+}
+
+int AlphaMgr::getCurve(AlphaMgrEntry *e) {
+ int n;
+ int status = e ? e->getStatus() : getBigStatus();
+ if (e == NULL) {
+ n = MulDiv(Wasabi::Std::getTickCount()-getBigEnterLeaveTime(),256,status == STATUS_IN_FADINGON ? fadein_ms : fadeout_ms);
+ if (n > 255) n = 255; if (n < 0) n = 0;
+ } else {
+ if (e->getEnterLeaveTime() == -1) return -1;
+ n = MulDiv(Wasabi::Std::getTickCount()-e->getEnterLeaveTime(),256,status == STATUS_IN_FADINGON ? fadein_ms : fadeout_ms);
+ if (n > 255) n = 255; if (n < 0) n = 0;
+ }
+ return n;
+}
+
+// returns the value of the transparency if no override applies, you still need to check overrides (see updatetransparency)
+int AlphaMgr::getTransparency(Layout *l) {
+ if (getAutoOpacify())
+ l = NULL;
+ if (l == NULL) {
+ if (getBigStatus() == STATUS_UNKNOWN) {
+ setBigStatus(STATUS_OUT_OFF);
+ Layout *main = SkinParser::getMainLayout();
+ if (main)
+ big_curtransparency = main->getTransparency();
+ else
+ big_curtransparency = 255;
+ }
+ }
+ AlphaMgrEntry *e = NULL;
+ if (l) e = layouts.findItem((const wchar_t *)l);
+ int s = e ? e->getStatus() : getBigStatus();
+ if (e && s == STATUS_UNKNOWN) {
+ initStatus(e);
+ s = e->getStatus();
+ }
+ switch (s) {
+ case STATUS_IN_OFF: return e ? getAlpha(e) : getGlobalAlpha();
+ case STATUS_OUT_OFF: return e ? getAlpha(e) : getGlobalAlpha();
+ case STATUS_IN_ON: return 255;
+ case STATUS_OUT_FADINGOUT: {
+ int n = e ? getCurve(e) : getCurve(NULL);
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5);
+ int na;
+ if (e)
+ na = (int)(((float)(getAlpha(e) - e->getStartAlpha()) * sintrans) + e->getStartAlpha());
+ else
+ na = (int)(((float)(getGlobalAlpha() - getBigStartAlpha()) * sintrans) + getBigStartAlpha());
+ return na;
+ }
+ case STATUS_IN_FADINGON: {
+ int n = e ? getCurve(e) : getCurve(NULL);
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5);
+ int na;
+ if (e)
+ na = (int)(((float)(255 - e->getStartAlpha()) * sintrans) + e->getStartAlpha());
+ else
+ na = (int)(((float)(255 - getBigStartAlpha()) * sintrans) + getBigStartAlpha());
+ return na;
+ }
+ default: return e ? getAlpha(e) : getGlobalAlpha();
+ }
+}
+
+int AlphaMgr::hasAutoOpacityOnHover(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) return hasAutoOpacityOnHover(e);
+ return 0;
+}
+
+int AlphaMgr::hasAutoOpacity(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) return hasAutoOpacity(e);
+ return 0;
+}
+
+int AlphaMgr::hasAutoOpacityOnFocus(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) return hasAutoOpacityOnFocus(e);
+ return 0;
+}
+
+int AlphaMgr::hasAutoOpacityOnFocus(AlphaMgrEntry *e) {
+ if (alllinked) return autoopacify == 2;
+ return e->getLayout()->getAutoOpacify() == 2 && e->getLayout()->getNoParent() != 1;
+}
+
+int AlphaMgr::hasAutoOpacityOnHover(AlphaMgrEntry *e) {
+ if (alllinked) return autoopacify == 1;
+ return e->getLayout()->getAutoOpacify() == 1 && e->getLayout()->getNoParent() != 1;
+}
+
+int AlphaMgr::hasAutoOpacity(AlphaMgrEntry *e) {
+ if (alllinked) return autoopacify;
+ return e->getLayout()->getAutoOpacify() && e->getLayout()->getNoParent() != 1;
+}
+
+// we got a new layout to manage, and its status flags is not set, we should init it to something safe
+void AlphaMgr::initStatus(AlphaMgrEntry *l, int applytransparency) {
+ if (isMouseInLayout(l->getLayout())) {
+ l->setEnterLeaveTime((uint32_t)-1);
+ if (hasAutoOpacity(l)) {
+ l->setStatus(STATUS_IN_FADINGON);
+ l->onEnterLeave();
+ l->setStartAlpha(l->getLayout()->getTransparency());
+ checkTimer();
+ } else {
+ l->setStatus(STATUS_IN_OFF);
+ }
+ l->getLayout()->onMouseEnterLayout();
+ } else {
+ if (hasAutoOpacityOnHover(l)) {
+ l->setStartAlpha(l->getLayout()->getTransparency());
+ l->onEnterLeave();
+ l->setStatus(STATUS_OUT_FADINGOUT);
+ checkTimer();
+ } else {
+ l->setStatus(STATUS_OUT_OFF);
+ }
+ l->getLayout()->onMouseLeaveLayout();
+ }
+ if (applytransparency) updateTransparency(l->getLayout());
+}
+
+int AlphaMgr::isPointInLayout(Layout *l, int x, int y, api_region **rgn)
+{
+ api_region *rg = NULL;
+ if (!l) return 0;
+ if (!l->isVisible()) return 0;
+ RECT r,r2;
+ l->getClientRect(&r);
+ if (l->renderRatioActive()) l->multRatio(&r);
+ l->getWindowRect(&r2);
+ Wasabi::Std::offsetRect(&r, r2.left, r2.top);
+// OffsetRect(&r, r2.left, r2.top);
+ if (x < r.left || x > r.right || y < r.top || y > r.bottom) return 0;
+ if (rgn) {
+ if (!*rgn) {
+ rg = l->getComposedRegion();
+ *rgn = rg;
+ } else {
+ rg = *rgn;
+ }
+ } else {
+ rg = l->getComposedRegion();
+ }
+ if (!rgn) return 1;
+ x -= r.left; y -= r.top;
+ POINT pt={x,y};
+ if (l->renderRatioActive()) l->divRatio((int*)&pt.x, (int*)&pt.y);
+ if (l->getComposedRegion()->ptInRegion(&pt)) return 1;
+ return 0;
+}
+
+int AlphaMgr::isFocusInLayout(Layout *l) {
+ if (l->gotFocus()) return 1;
+ OSWINDOWHANDLE fw = Wasabi::Std::Wnd::getFocus();
+ while (fw)
+ {
+ if (fw == l->gethWnd()) return 1;
+ fw = Wasabi::Std::Wnd::getParent(fw);
+ }
+ return 0;
+}
+
+int AlphaMgr::isMouseInLayout(Layout *l) {
+ int isin = 0;
+ if (hasAutoOpacityOnFocus(l)) {
+ return isFocusInLayout(l);
+ } else {
+ int x, y;
+ api_region *r = NULL;
+ Wasabi::Std::getMousePos(&x, &y);
+ isin = isPointInLayout(l, x, y, &r);
+ int ext = getExtendAutoOpacity();
+ if (!isin && ext > 0) {
+ isin = isPointInLayout(l, x-ext, y, &r);
+ if (!isin) isin = isPointInLayout(l, x-ext, y-ext, &r);
+ if (!isin) isin = isPointInLayout(l, x, y-ext, &r);
+ if (!isin) isin = isPointInLayout(l, x+ext, y-ext, &r);
+ if (!isin) isin = isPointInLayout(l, x+ext, y, &r);
+ if (!isin) isin = isPointInLayout(l, x+ext, y+ext, &r);
+ if (!isin) isin = isPointInLayout(l, x, y+ext, &r);
+ if (!isin) isin = isPointInLayout(l, x-ext, y+ext, &r);
+ if (!isin) isin = isPointInLayout(l, x-ext, y, &r);
+ }
+ }
+ return isin;
+}
+
+int AlphaMgr::needForcedTransparencyFlag(Layout *l) {
+ if (!l->isTransparencySafe()) return 0;
+ if (l->isAlphaForced()) return 1;
+ if (l->getTransparencyOverride() > 0) return 1; // should not be testing for < 255 here
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (hasAutoOpacity(e) && getAlpha(e) < 255) return 1;
+ return 0;
+}
+
+void AlphaMgr::checkTimer() {
+ int fading = 0;
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ if (e->getStatus() == STATUS_IN_FADINGON || e->getStatus() == STATUS_OUT_FADINGOUT) { fading++; break; }
+ endfor;
+ if (getAutoOpacify() && getBigStatus() == STATUS_IN_FADINGON || getBigStatus() == STATUS_OUT_FADINGOUT)
+ fading++;
+ if (fading && !fast_timer_on) {
+ timerclient_setTimer(ALPHAMGR_UPDATEALPHA, 20);
+ fast_timer_on = 1;
+ } else if (!fading && fast_timer_on) {
+ timerclient_killTimer(ALPHAMGR_UPDATEALPHA);
+ fast_timer_on = 0;
+ }
+}
+
+void AlphaMgr::doEndCheck(AlphaMgrEntry *e) {
+ if (getCurve(e) == 255) {
+ switch (e ? e->getStatus() : getBigStatus()) {
+ case STATUS_IN_FADINGON:
+ if (e) e->setStatus(STATUS_IN_ON); else setBigStatus(STATUS_IN_ON);
+ break;
+ case STATUS_OUT_FADINGOUT:
+ if (e) e->setStatus(STATUS_OUT_OFF); else setBigStatus(STATUS_OUT_OFF);
+ break;
+ }
+ checkTimer();
+ }
+}
+
+void AlphaMgr::updateInList(AlphaMgrEntry *e, int isin) {
+ if (isin) {
+ if (in_layouts.searchItem(e) == -1)
+ in_layouts.addItem(e);
+ } else {
+ in_layouts.removeItem(e);
+ }
+
+ int big_isin = in_layouts.getNumItems() > 0;
+
+ if (getAutoOpacify()) {
+ if (big_isin) {
+ // mouse is in a layout, autoopacity is on
+ switch (getBigStatus()) {
+ case STATUS_OUT_OFF:
+ case STATUS_OUT_FADINGOUT:
+ case STATUS_IN_OFF: {
+ setBigStartAlpha(e->getLayout()->getTransparency());
+ onBigEnterLeave();
+ setBigStatus(STATUS_IN_FADINGON);
+ checkTimer();
+ break;
+ }
+ case STATUS_IN_FADINGON:
+ doEndCheck(NULL);
+ break;
+ }
+ } else {
+ // mouse out of all layouts, autoopacity is on
+ switch (getBigStatus()) {
+ case STATUS_IN_FADINGON:
+ case STATUS_IN_ON: {
+ setBigStartAlpha(getTransparency(NULL));
+ onBigEnterLeave();
+ setBigStatus(STATUS_OUT_FADINGOUT);
+ checkTimer();
+ break;
+ }
+ case STATUS_OUT_FADINGOUT:
+ doEndCheck(NULL);
+ break;
+ }
+ }
+ } else {
+ if (big_isin) {
+ // mouse is in a layout, no autoopacity
+ setBigStatus(STATUS_IN_OFF);
+ } else {
+ // mouse is out of all layouts, no autoopacity
+ setBigStatus(STATUS_OUT_OFF);
+ }
+ }
+}
+
+int AlphaMgr::isFocusingExternalWindow()
+{
+ OSWINDOWHANDLE fw = Wasabi::Std::Wnd::getFocus();
+ if (isOurExternalWindow(fw)) return 1;
+ return 0;
+}
+
+int AlphaMgr::isOverExternalWindow()
+{
+ int x, y;
+ Wasabi::Std::getMousePos(&x, &y);
+ int ext = getExtendAutoOpacity();
+
+ POINT pt;
+ pt.x = x; pt.y = y;
+ OSWINDOWHANDLE w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x-ext; pt.y = y-ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x; pt.y = y-ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x+ext; pt.y = y-ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x+ext; pt.y = y;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x+ext; pt.y = y+ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x; pt.y = y+ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x-ext; pt.y = y+ext;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ pt.x = x-ext; pt.y = y;
+ w = Wasabi::Std::Wnd::getWindowFromPoint(pt);
+ if (isOurExternalWindow(w)) return 1;
+ return 0;
+}
+
+int AlphaMgr::isWasabiWindow(OSWINDOWHANDLE w)
+{
+#ifdef _WIN32
+ wchar_t classname[256]=L"";
+ GetClassNameW(w, classname, 255);
+ return (w == WASABI_API_WND->main_getRootWnd()->gethWnd() || !wcscmp(classname, BASEWNDCLASSNAME));
+#else
+#warning port me
+ return 1;
+#endif
+}
+
+int AlphaMgr::isMenuWindow(OSWINDOWHANDLE w)
+{
+#ifdef _WIN32
+ char classname[256]="";
+ GetClassNameA(w, classname, 255);
+ return STRCASEEQL(classname, "#32768");
+#else
+ return 0;
+#warning port me
+#endif
+}
+
+int AlphaMgr::isOurExternalWindow(OSWINDOWHANDLE w)
+{
+ OSWINDOWHANDLE wnd = w;
+ if (isWasabiWindow(w))
+ return 0;
+
+ if (isMenuWindow(wnd)) {
+ wnd = Wasabi::Std::Wnd::getFocus();
+ if (isWasabiWindow(wnd) || isOurExternalWindow(wnd))
+ return 1;
+ }
+
+ while (wnd)
+ {
+ if (Wasabi::Std::Wnd::isPopup(wnd))
+ {
+ if (isWasabiWindow(wnd))
+ return 0;
+ OSWINDOWHANDLE _w = Wasabi::Std::Wnd::getParent(wnd);
+#ifdef _WIN32
+ if (!_w) _w = GetWindow(wnd, GW_OWNER);
+#else
+#warning port me
+#endif
+ if (!wnd) _w = wnd;
+ return (_w == WASABI_API_WND->main_getRootWnd()->gethWnd() || isWasabiWindow(_w) || isOurExternalWindow(_w));
+ }
+ wnd = Wasabi::Std::Wnd::getParent(wnd);
+ }
+ return 0;
+}
+
+void AlphaMgr::preHoverCheck(AlphaMgrEntry *e) {
+ int isin = isMouseInLayout(e->getLayout());
+ uint32_t last = e->getLastTimeIn();
+ uint32_t lastbig = getBigLastTimeIn();
+ if (isin) { e->onLastIn(); onBigLastIn(); }
+ if (!getAutoOpacify()) {
+ if (!isin && last != 0 && (last > Wasabi::Std::getTickCount() - holdtime_ms))
+ isin = 1;
+ } else {
+ if (!isin && lastbig != 0 && (lastbig > Wasabi::Std::getTickCount() - holdtime_ms))
+ isin = 1;
+ }
+ if (!isin) {
+ if (hasAutoOpacityOnFocus(e)) {
+ if (isFocusingExternalWindow()) isin = 1;
+ } else {
+ if (isOverExternalWindow()) isin = 1;
+ }
+ }
+ e->setNextIn(isin);
+ updateInList(e, isin);
+}
+
+void AlphaMgr::hoverCheck(Layout *l) {
+ AlphaMgrEntry *e = layouts.findItem((const wchar_t *)l);
+ if (e) hoverCheck(e);
+}
+
+void AlphaMgr::hoverCheck(AlphaMgrEntry *e, int applytransparency) {
+ if (e->getStatus() == STATUS_UNKNOWN)
+ initStatus(e);
+
+ int isin = e->getNextIn();
+
+ if (getAutoOpacify()) {
+ isin = big_status == STATUS_IN_FADINGON || big_status == STATUS_IN_ON || big_status == STATUS_IN_OFF;
+ }
+ if (hasAutoOpacity(e)) {
+ if (isin) {
+ // mouse is in, autoopacity is on
+ switch (e->getStatus()) {
+ case STATUS_OUT_OFF:
+ case STATUS_OUT_FADINGOUT:
+ case STATUS_IN_OFF:
+ e->setStartAlpha(e->getLayout()->getTransparency());
+ e->onEnterLeave();
+ e->setStatus(STATUS_IN_FADINGON);
+ checkTimer();
+ e->getLayout()->onMouseEnterLayout();
+ break;
+ case STATUS_IN_FADINGON:
+ doEndCheck(e);
+ break;
+ }
+ } else {
+ // mouse is out, autoopacity is on
+ switch (e->getStatus()) {
+ case STATUS_IN_FADINGON:
+ case STATUS_IN_ON:
+ e->setStartAlpha(e->getLayout()->getTransparency());
+ e->onEnterLeave();
+ e->setStatus(STATUS_OUT_FADINGOUT);
+ checkTimer();
+ e->getLayout()->onMouseLeaveLayout();
+ break;
+ case STATUS_OUT_FADINGOUT:
+ doEndCheck(e);
+ break;
+ }
+ }
+ } else {
+ if (isin) {
+ // mouse is in, no autoopacity
+ e->setStatus(STATUS_IN_OFF);
+ } else {
+ // mouse is out, no autoopacity
+ e->setStatus(STATUS_OUT_OFF);
+ }
+ }
+// if (applytransparency) updateTransparency(e->getLayout());
+}
+
+void AlphaMgr::timerclient_timerCallback(int id) {
+ switch(id) {
+ case ALPHAMGR_HOVERCHECK: {
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ preHoverCheck(e);
+ endfor;
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ hoverCheck(e);
+ endfor;
+ }
+ break;
+ case ALPHAMGR_UPDATEALPHA: {
+ foreach(layouts)
+ AlphaMgrEntry *e = layouts.getfor();
+ if (e->getStatus() == STATUS_IN_FADINGON || e->getStatus() == STATUS_OUT_FADINGOUT) updateTransparency(e->getLayout());
+ endfor;
+ }
+ break;
+ }
+}
+
+int AlphaMgr::getBigCurTransparency() {
+ switch (getBigStatus()) {
+ case STATUS_IN_FADINGON:
+ case STATUS_OUT_FADINGOUT:
+ return getTransparency(NULL);
+ case STATUS_IN_ON:
+ return 255;
+ case STATUS_IN_OFF:
+ case STATUS_OUT_OFF:
+ return getGlobalAlpha();
+ default: return getTransparency(NULL);
+ }
+}
+
+void AlphaMgr::setBigStartAlpha(int a) {
+ big_startalpha = a;
+}
+
+void AlphaMgr::setBigStatus(int s) {
+ big_status = s;
+}
+
+void AlphaMgr::onBigEnterLeave() {
+ big_enterleave_time = Wasabi::Std::getTickCount();
+}
+
+uint32_t AlphaMgr::getBigEnterLeaveTime() {
+ return big_enterleave_time;
+}
+
+void AlphaMgr::setAutoOpacify(int l) {
+ autoopacify = l;
+ resetTimer();
+ if (l == 0) {
+ foreach(layouts)
+ if (layouts.getfor()->getStatus() == STATUS_IN_FADINGON) layouts.getfor()->setStatus(STATUS_IN_OFF);
+ if (layouts.getfor()->getStatus() == STATUS_OUT_FADINGOUT) layouts.getfor()->setStatus(STATUS_OUT_OFF);
+ endfor;
+ }
+ updateAllTransparency();
+}
+
+void AlphaMgr::resetTimer() {
+ timerclient_killTimer(ALPHAMGR_HOVERCHECK);
+ if (autoopacify == 1 && alllinked)
+ timerclient_setTimer(ALPHAMGR_HOVERCHECK, 99);
+ else
+ timerclient_setTimer(ALPHAMGR_HOVERCHECK, 300);
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/alphamgr.h b/Src/Wasabi/api/wndmgr/alphamgr.h
new file mode 100644
index 00000000..240485dd
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/alphamgr.h
@@ -0,0 +1,136 @@
+#ifndef _ALPHAMGR_H
+#define _ALPHAMGR_H
+
+#include <api/timer/timerclient.h>
+
+class Layout;
+
+#define STATUS_UNKNOWN -1
+#define STATUS_OUT_OFF 0
+#define STATUS_IN_ON 1
+#define STATUS_OUT_FADINGOUT 2
+#define STATUS_IN_FADINGON 3
+#define STATUS_IN_OFF 4 // when no autoopacity
+
+class AlphaMgrEntry {
+ public:
+ AlphaMgrEntry(Layout *l) : layout(l), status(STATUS_UNKNOWN), fade_val(-1), startalpha(-1), lasttime_in(0), next_in(-1) {}
+ virtual ~AlphaMgrEntry() { }
+
+ Layout *getLayout() { return layout; }
+ int getStatus() { return status; }
+
+ void onEnterLeave() { enterleave_time = Wasabi::Std::getTickCount(); }
+ int getEnterLeaveTime() { return enterleave_time; }
+ void setEnterLeaveTime(uint32_t t) { enterleave_time = t; }
+ void setStatus(int s) { status = s; }
+ int getStartAlpha() { return startalpha; }
+ void setStartAlpha(int s) { startalpha = s; }
+ uint32_t getLastTimeIn() { return lasttime_in; }
+ void onLastIn() { lasttime_in = Wasabi::Std::getTickCount(); }
+ void setNextIn(int i) { next_in = i; }
+ int getNextIn() { return next_in; }
+
+ private:
+ Layout *layout;
+ int status;
+ int fade_val;
+ uint32_t enterleave_time;
+ int startalpha;
+ uint32_t lasttime_in;
+ int next_in;
+};
+
+class AlphaMgrEntryComparator {
+public:
+ static int compareItem(AlphaMgrEntry *p1, AlphaMgrEntry* p2) {
+ return CMP3((void*)p1->getLayout(), (void *)p2->getLayout());
+ }
+ static int compareAttrib(const wchar_t *attrib, AlphaMgrEntry *item) {
+ return CMP3((void *)attrib, (void *)item->getLayout());
+ }
+};
+
+class AlphaMgr : public TimerClientDI {
+ public:
+ AlphaMgr();
+ virtual ~AlphaMgr();
+
+ void addLayout(Layout *l);
+ void removeLayout(Layout *l);
+
+ virtual void timerclient_timerCallback(int id);
+
+ void updateTransparency(Layout *l);
+ int getTransparency(Layout *l);
+ int getGlobalAlpha();
+ void setGlobalAlpha(int a);
+ int isFocusInLayout(Layout *l);
+ int isMouseInLayout(Layout *l);
+ int isPointInLayout(Layout *l, int x, int y, api_region **rgn=NULL);
+ int needForcedTransparencyFlag(Layout *l);
+ int hasAutoOpacity(Layout *l);
+ int hasAutoOpacityOnHover(Layout *l);
+ int hasAutoOpacityOnFocus(Layout *l);
+
+ void setAllLinked(int l) { alllinked = l; resetTimer(); updateAllTransparency(); }
+ void setAutoOpacify(int l);
+ int getAllLinked() { return alllinked; }
+ int getAutoOpacify() { return (autoopacify && alllinked) ? autoopacify : 0; }
+ void setExtendAutoOpacity(int n) { extend_px = n; }
+ int getExtendAutoOpacity() { return extend_px; }
+ int getBigCurTransparency();
+
+ void setFadeInTime(int ms) { fadein_ms = MAX(ms, 1); }
+ void setFadeOutTime(int ms) { fadeout_ms = MAX(ms, 1); }
+ void setHoldTime(int ms) { holdtime_ms = ms; }
+ void hoverCheck(Layout *l);
+ int getAlpha(Layout *l);
+
+ private:
+ void updateAllTransparency();
+ void updateInList(AlphaMgrEntry *e, int isin);
+ void setBigStartAlpha(int a);
+ int getBigStartAlpha() { return big_startalpha; }
+ void onBigEnterLeave();
+ uint32_t getBigEnterLeaveTime();
+ void setBigStatus(int s);
+ int getBigStatus() { return big_status; }
+ void initStatus(AlphaMgrEntry *e, int applytransparency=0);
+ int getAlpha(AlphaMgrEntry *e);
+ int hasAutoOpacityOnHover(AlphaMgrEntry *e);
+ int hasAutoOpacityOnFocus(AlphaMgrEntry *e);
+ int hasAutoOpacity(AlphaMgrEntry *e);
+ void checkTimer();
+ void hoverCheck(AlphaMgrEntry *e, int applytransparency=1);
+ void preHoverCheck(AlphaMgrEntry *e);
+ int getCurve(AlphaMgrEntry *e);
+ void doEndCheck(AlphaMgrEntry *e);
+ void onBigLastIn() { big_lasttimein = Wasabi::Std::getTickCount(); }
+ uint32_t getBigLastTimeIn() { return big_lasttimein; }
+ int isFocusingExternalWindow();
+ int isOverExternalWindow();
+ int isOurExternalWindow(OSWINDOWHANDLE w);
+ int isWasabiWindow(OSWINDOWHANDLE w);
+ int isMenuWindow(OSWINDOWHANDLE w);
+ void resetTimer();
+
+ PtrListQuickSorted<AlphaMgrEntry, AlphaMgrEntryComparator> layouts;
+ PtrListQuickSortedByPtrVal<AlphaMgrEntry> in_layouts;
+ Layout *overlayout;
+ int alllinked;
+ int autoopacify;
+ int global_alpha;
+ int fast_timer_on;
+ int big_status;
+ int big_curtransparency;
+ int big_startalpha;
+ uint32_t big_enterleave_time;
+ int big_lasttimein;
+ int fadein_ms;
+ int fadeout_ms;
+ int holdtime_ms;
+ int extend_px;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/animate.cpp b/Src/Wasabi/api/wndmgr/animate.cpp
new file mode 100644
index 00000000..c5f789b7
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/animate.cpp
@@ -0,0 +1,96 @@
+#include <precomp.h>
+#include <wasabicfg.h>
+#include "animate.h"
+
+#include <api/config/items/cfgitem.h>
+
+//---------------------------------------------------------------------------
+void AnimatedRects::draw(const RECT *source, const RECT *dest, int steps)
+{
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ if (!_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid), L"Animated rects")) return;
+#else
+ if (!WASABI_WNDMGR_ANIMATEDRECTS) return;
+#endif
+
+ //FG> Not anymore, old code, old bugs
+ //BU you're so cool, Francis
+ //FG> thank you, you're not too bad either :)
+ int sizex=source->right-source->left-(dest->right-dest->left);
+ int sizey=source->bottom-source->top-(dest->bottom-dest->top);
+ int diffx=source->left-dest->left;
+ int diffy=(source->top)-dest->top;
+
+#ifdef WIN32
+ HDC dc;
+ dc=GetDC(0);
+ HBRUSH brush = CreateSolidBrush(0xFFFFFF);
+ HPEN pen = CreatePen(PS_SOLID,0,0xFFFFFF);
+ HBRUSH obrush = (HBRUSH)SelectObject(dc, brush);
+ HPEN open = (HPEN)SelectObject(dc, pen);
+ int oldrop = SetROP2(dc,R2_XORPEN);
+#endif
+#ifdef LINUX
+ HDC dc = (HDC)MALLOC( sizeof( hdc_typ ) );
+ XGCValues gcv;
+ gcv.foreground = 0xffffff;
+ gcv.function = GXxor;
+ gcv.subwindow_mode = IncludeInferiors;
+ dc->gc = XCreateGC( Linux::getDisplay(), Linux::RootWin(), GCForeground | GCFunction | GCSubwindowMode, &gcv );
+#endif
+//PORTME
+
+ for(int i=0;i<steps;i++) {
+ int x=dest->left+diffx-((diffx*i)/steps);
+ int y=dest->top+diffy-((diffy*i)/steps);
+ int maxx=(source->right-source->left)-((sizex*i)/steps);
+ int maxy=(source->bottom-source->top)-((sizey*i)/steps);
+
+#ifdef WIN32
+ int p1x=x,p1y=y;
+ int p2x=x+maxx,p2y=y;
+ int p3x=x+maxx,p3y=y+maxy;
+ int p4x=x,p4y=y+maxy;
+ MoveToEx(dc,p1x,p1y,NULL);
+ LineTo(dc,p2x,p2y);
+ LineTo(dc,p3x,p3y);
+ LineTo(dc,p4x,p4y);
+ LineTo(dc,p1x,p1y);
+#endif
+#ifdef LINUX
+ XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
+ x, y, maxx, maxy );
+#endif
+//PORTME
+ Wasabi::Std::usleep(5);
+#ifdef WIN32
+ MoveToEx(dc,p1x,p1y,NULL);
+ LineTo(dc,p2x,p2y);
+ LineTo(dc,p3x,p3y);
+ LineTo(dc,p4x,p4y);
+ LineTo(dc,p1x,p1y);
+#endif
+#ifdef LINUX
+ XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
+ x, y, maxx, maxy );
+#endif
+//PORTME
+ }
+#ifdef WIN32
+ SetROP2(dc, oldrop);
+ SelectObject(dc, open);
+ SelectObject(dc, obrush);
+ DeleteObject(brush);
+ DeleteObject(pen);
+ ReleaseDC(0,dc);
+#endif
+#ifdef LINUX
+ XFreeGC( Linux::getDisplay(), dc->gc );
+ FREE( dc );
+#endif
+//PORTME
+}
+
diff --git a/Src/Wasabi/api/wndmgr/animate.h b/Src/Wasabi/api/wndmgr/animate.h
new file mode 100644
index 00000000..23a98318
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/animate.h
@@ -0,0 +1,11 @@
+#ifndef _ANIMATE_H
+#define _ANIMATE_H
+
+#include <bfc/wasabi_std.h>
+
+class AnimatedRects {
+public:
+ static void draw(const RECT *src, const RECT *dst, int nsteps=5);
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/api_wndmgr.cpp b/Src/Wasabi/api/wndmgr/api_wndmgr.cpp
new file mode 100644
index 00000000..c2206aeb
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/api_wndmgr.cpp
@@ -0,0 +1,47 @@
+#include <precomp.h>
+#include "api_wndmgr.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+#define CBCLASS wndmgr_apiI
+START_DISPATCH;
+ VCB(WNDMGR_API_WNDTRACKADD, wndTrackAdd);
+ VCB(WNDMGR_API_WNDTRACKREMOVE, wndTrackRemove);
+ CB(WNDMGR_API_WNDTRACKDOCK, wndTrackDock);
+ CB(WNDMGR_API_WNDTRACKDOCK2, wndTrackDock2);
+ VCB(WNDMGR_API_WNDTRACKSTARTCOOPERATIVE, wndTrackStartCooperative);
+ VCB(WNDMGR_API_WNDTRACKENDCOOPERATIVE, wndTrackEndCooperative);
+ CB(WNDMGR_API_WNDTRACKWASCOOPERATIVE, wndTrackWasCooperative);
+ VCB(WNDMGR_API_WNDTRACKINVALIDATEALL, wndTrackInvalidateAll);
+ CB(WNDMGR_API_SKINWND_TOGGLEBYGUID, skinwnd_toggleByGuid);
+ CB(WNDMGR_API_SKINWND_TOGGLEBYGROUPID, skinwnd_toggleByGroupId);
+ CB(WNDMGR_API_SKINWND_CREATEBYGUID, skinwnd_createByGuid);
+ CB(WNDMGR_API_SKINWND_CREATEBYGROUPID, skinwnd_createByGroupId);
+ VCB(WNDMGR_API_SKINWND_DESTROY, skinwnd_destroy);
+ CB(WNDMGR_API_SKINWND_GETNUMBYGUID, skinwnd_getNumByGuid);
+ CB(WNDMGR_API_SKINWND_ENUMBYGUID, skinwnd_enumByGuid);
+ CB(WNDMGR_API_SKINWND_GETNUMBYGROUPID, skinwnd_getNumByGroupId);
+ CB(WNDMGR_API_SKINWND_ENUMBYGROUPID, skinwnd_enumByGroupId);
+ VCB(WNDMGR_API_SKINWND_ATTACHTOSKIN, skinwnd_attachToSkin);
+ //CB(WNDMGR_API_SKIN_GETCONTAINER, skin_getContainer);
+ //CB(WNDMGR_API_SKIN_GETLAYOUT, skin_getLayout);
+ VCB(WNDMGR_API_WNDHOLDER_REGISTER, wndholder_register);
+ VCB(WNDMGR_API_WNDHOLDER_UNREGISTER, wndholder_unregister);
+ CB(WNDMGR_API_MESSAGEBOX, messageBox);
+ CB(WNDMGR_API_GETMODALWND, getModalWnd);
+ VCB(WNDMGR_API_PUSHMODALWND, pushModalWnd);
+ VCB(WNDMGR_API_POPMODALWND, popModalWnd);
+ VCB(WNDMGR_API_DRAWANIMATEDRECTS, drawAnimatedRects);
+ CB(WNDMGR_API_AUTOPOPUP_REGISTERGUID, autopopup_registerGuid);
+ CB(WNDMGR_API_AUTOPOPUP_REGISTERGROUPID, autopopup_registerGroupId);
+ VCB(WNDMGR_API_AUTOPOPUP_UNREGISTER, autopopup_unregister);
+ CB(WNDMGR_API_AUTOPOPUP_GETNUMGUIDS, autopopup_getNumGuids);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGUID, autopopup_enumGuid);
+ CB(WNDMGR_API_AUTOPOPUP_GETNUMGROUPS, autopopup_getNumGroups);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGROUPS, autopopup_enumGroup);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGUIDDESC, autopopup_enumGuidDescription);
+ CB(WNDMGR_API_AUTOPOPUP_ENUMGROUPDESC, autopopup_enumGroupDescription);
+ CB(WNDMGR_API_VARMGR_TRANSLATE, varmgr_translate);
+ CB(WNDMGR_API_NEWDYNAMICCONTAINER, newDynamicContainer);
+END_DISPATCH;
diff --git a/Src/Wasabi/api/wndmgr/api_wndmgr.h b/Src/Wasabi/api/wndmgr/api_wndmgr.h
new file mode 100644
index 00000000..667ddd38
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/api_wndmgr.h
@@ -0,0 +1,305 @@
+#ifndef __WNDMGR_API_H
+#define __WNDMGR_API_H
+
+#include <bfc/dispatch.h>
+#include <bfc/nsguid.h>
+
+class ifc_window;
+class WindowHolder;
+class Container;
+class ScriptObject;
+
+#ifndef MODALWND_DEF
+#define MODALWND_DEF
+ifc_window *const MODALWND_NOWND = reinterpret_cast<ifc_window*>(-1);
+#endif
+
+class wndmgr_api : public Dispatchable {
+ public:
+ void wndTrackAdd(ifc_window *wnd);
+ void wndTrackRemove(ifc_window *wnd);
+ bool wndTrackDock(ifc_window *wnd, RECT *r, int mask);
+ bool wndTrackDock(ifc_window *wnd, RECT *r, RECT *orig_r, int mask);
+ void wndTrackStartCooperative(ifc_window *wnd);
+ void wndTrackEndCooperative();
+ int wndTrackWasCooperative();
+ void wndTrackInvalidateAll();
+ int skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ int skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ ifc_window *skinwnd_createByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew = NULL);
+ ifc_window *skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew = NULL);
+ void skinwnd_destroy(ifc_window *w, RECT *destanimrect = NULL);
+ int skinwnd_getNumByGuid(GUID g);
+ ifc_window *skinwnd_enumByGuid(GUID g, int n);
+ int skinwnd_getNumByGroupId(const wchar_t *groupid);
+ ifc_window *skinwnd_enumByGroupId(const wchar_t *groupid, int n);
+ void skinwnd_attachToSkin(ifc_window *w, int side, int size);
+ //ScriptObject *skin_getContainer(const wchar_t *container_name);
+ //ScriptObject *skin_getLayout(ScriptObject *container, const wchar_t *layout_name);
+ void wndholder_register(WindowHolder *wh);
+ void wndholder_unregister(WindowHolder *wh);
+ int messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt);
+ ifc_window *getModalWnd();
+ void pushModalWnd(ifc_window *w = MODALWND_NOWND);
+ void popModalWnd(ifc_window *w = MODALWND_NOWND);
+ void drawAnimatedRects(const RECT *r1, const RECT *r2);
+ int autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ int autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ void autopopup_unregister(int id);
+ int autopopup_getNumGuids();
+ GUID autopopup_enumGuid(int n);
+ int autopopup_getNumGroups();
+ const wchar_t *autopopup_enumGroup(int n);
+ const wchar_t *autopopup_enumGuidDescription(int n);
+ const wchar_t *autopopup_enumGroupDescription(int n);
+ const wchar_t *varmgr_translate(const wchar_t *str);
+ //Container *newDynamicContainer(const wchar_t *containername, int transcient = 1);
+
+ enum {
+ WNDMGR_API_WNDTRACKADD = 0,
+ WNDMGR_API_WNDTRACKREMOVE = 10,
+ WNDMGR_API_WNDTRACKDOCK = 20,
+ WNDMGR_API_WNDTRACKDOCK2 = 30,
+ WNDMGR_API_WNDTRACKSTARTCOOPERATIVE = 40,
+ WNDMGR_API_WNDTRACKENDCOOPERATIVE = 50,
+ WNDMGR_API_WNDTRACKWASCOOPERATIVE = 60,
+ WNDMGR_API_WNDTRACKINVALIDATEALL = 70,
+ WNDMGR_API_SKINWND_TOGGLEBYGUID = 80,
+ WNDMGR_API_SKINWND_TOGGLEBYGROUPID = 90,
+ WNDMGR_API_SKINWND_CREATEBYGUID = 100,
+ WNDMGR_API_SKINWND_CREATEBYGROUPID = 110,
+ WNDMGR_API_SKINWND_DESTROY = 120,
+ WNDMGR_API_SKINWND_GETNUMBYGUID = 130,
+ WNDMGR_API_SKINWND_ENUMBYGUID = 140,
+ WNDMGR_API_SKINWND_GETNUMBYGROUPID = 150,
+ WNDMGR_API_SKINWND_ENUMBYGROUPID = 160,
+ WNDMGR_API_SKINWND_ATTACHTOSKIN = 170,
+ //WNDMGR_API_SKIN_GETCONTAINER = 180,
+ WNDMGR_API_SKIN_GETLAYOUT = 190,
+ WNDMGR_API_WNDHOLDER_REGISTER = 200,
+ WNDMGR_API_WNDHOLDER_UNREGISTER = 210,
+ WNDMGR_API_MESSAGEBOX = 220,
+ WNDMGR_API_GETMODALWND = 230,
+ WNDMGR_API_PUSHMODALWND = 240,
+ WNDMGR_API_POPMODALWND = 250,
+ WNDMGR_API_DRAWANIMATEDRECTS = 260,
+ WNDMGR_API_AUTOPOPUP_REGISTERGUID = 270,
+ WNDMGR_API_AUTOPOPUP_REGISTERGROUPID = 280,
+ WNDMGR_API_AUTOPOPUP_UNREGISTER = 290,
+ WNDMGR_API_VARMGR_TRANSLATE = 300,
+ WNDMGR_API_NEWDYNAMICCONTAINER = 310,
+ WNDMGR_API_AUTOPOPUP_GETNUMGUIDS = 320,
+ WNDMGR_API_AUTOPOPUP_ENUMGUID = 330,
+ WNDMGR_API_AUTOPOPUP_GETNUMGROUPS = 340,
+ WNDMGR_API_AUTOPOPUP_ENUMGROUPS = 350,
+ WNDMGR_API_AUTOPOPUP_ENUMGUIDDESC = 360,
+ WNDMGR_API_AUTOPOPUP_ENUMGROUPDESC = 370,
+ };
+};
+
+inline void wndmgr_api::wndTrackAdd(ifc_window *wnd) {
+ _voidcall(WNDMGR_API_WNDTRACKADD, wnd);
+}
+
+inline void wndmgr_api::wndTrackRemove(ifc_window *wnd) {
+ _voidcall(WNDMGR_API_WNDTRACKREMOVE, wnd);
+}
+
+inline bool wndmgr_api::wndTrackDock(ifc_window *wnd, RECT *r, int mask) {
+ return _call(WNDMGR_API_WNDTRACKDOCK, (bool)FALSE, wnd, r, mask);
+}
+
+inline bool wndmgr_api::wndTrackDock(ifc_window *wnd, RECT *r, RECT *orig_r, int mask) {
+ return _call(WNDMGR_API_WNDTRACKDOCK2, (bool)FALSE, wnd, r, orig_r, mask);
+}
+
+inline void wndmgr_api::wndTrackStartCooperative(ifc_window *wnd) {
+ _voidcall(WNDMGR_API_WNDTRACKSTARTCOOPERATIVE, wnd);
+}
+
+inline void wndmgr_api::wndTrackEndCooperative() {
+ _voidcall(WNDMGR_API_WNDTRACKENDCOOPERATIVE);
+}
+
+inline int wndmgr_api::wndTrackWasCooperative() {
+ return _call(WNDMGR_API_WNDTRACKWASCOOPERATIVE, (int)0);
+}
+
+inline void wndmgr_api::wndTrackInvalidateAll() {
+ _voidcall(WNDMGR_API_WNDTRACKINVALIDATEALL);
+}
+
+inline int wndmgr_api::skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient) {
+ return _call(WNDMGR_API_SKINWND_TOGGLEBYGUID, (int)0, g, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+inline int wndmgr_api::skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient) {
+ return _call(WNDMGR_API_SKINWND_TOGGLEBYGROUPID, (int)0, groupid, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_createByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew) {
+ return _call(WNDMGR_API_SKINWND_CREATEBYGUID, (ifc_window *)NULL, g, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew) {
+ return _call(WNDMGR_API_SKINWND_CREATEBYGROUPID, (ifc_window *)NULL, groupid, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+inline void wndmgr_api::skinwnd_destroy(ifc_window *w, RECT *destanimrect) {
+ _voidcall(WNDMGR_API_SKINWND_DESTROY, w, destanimrect);
+}
+
+inline int wndmgr_api::skinwnd_getNumByGuid(GUID g) {
+ return _call(WNDMGR_API_SKINWND_GETNUMBYGUID, (int)0, g);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_enumByGuid(GUID g, int n) {
+ return _call(WNDMGR_API_SKINWND_ENUMBYGUID, (ifc_window *)NULL, g, n);
+}
+
+inline int wndmgr_api::skinwnd_getNumByGroupId(const wchar_t *groupid) {
+ return _call(WNDMGR_API_SKINWND_GETNUMBYGROUPID, (int)0, groupid);
+}
+
+inline ifc_window *wndmgr_api::skinwnd_enumByGroupId(const wchar_t *groupid, int n) {
+ return _call(WNDMGR_API_SKINWND_ENUMBYGROUPID, (ifc_window *)NULL, groupid, n);
+}
+
+inline void wndmgr_api::skinwnd_attachToSkin(ifc_window *w, int side, int size) {
+ _voidcall(WNDMGR_API_SKINWND_ATTACHTOSKIN, w, side, size);
+}
+/*
+inline ScriptObject *wndmgr_api::skin_getContainer(const wchar_t *container_name) {
+ return _call(WNDMGR_API_SKIN_GETCONTAINER, (ScriptObject *)NULL, container_name);
+}
+*/
+/*
+inline ScriptObject *wndmgr_api::skin_getLayout(ScriptObject *container, const wchar_t *layout_name) {
+ return _call(WNDMGR_API_SKIN_GETLAYOUT, (ScriptObject *)NULL, container, layout_name);
+}
+*/
+inline void wndmgr_api::wndholder_register(WindowHolder *wh) {
+ _voidcall(WNDMGR_API_WNDHOLDER_REGISTER, wh);
+}
+
+inline void wndmgr_api::wndholder_unregister(WindowHolder *wh) {
+ _voidcall(WNDMGR_API_WNDHOLDER_UNREGISTER, wh);
+}
+
+inline int wndmgr_api::messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt) {
+ return _call(WNDMGR_API_MESSAGEBOX, (int)0, txt, title, flags, not_anymore_identifier, parenwnt);
+}
+
+inline ifc_window *wndmgr_api::getModalWnd() {
+ return _call(WNDMGR_API_GETMODALWND, (ifc_window *)NULL);
+}
+
+inline void wndmgr_api::pushModalWnd(ifc_window *w) {
+ _voidcall(WNDMGR_API_PUSHMODALWND, w);
+}
+
+inline void wndmgr_api::popModalWnd(ifc_window *w) {
+ _voidcall(WNDMGR_API_POPMODALWND, w);
+}
+
+inline void wndmgr_api::drawAnimatedRects(const RECT *r1, const RECT *r2) {
+ _voidcall(WNDMGR_API_DRAWANIMATEDRECTS, r1, r2);
+}
+
+inline int wndmgr_api::autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container, int container_flag) {
+ return _call(WNDMGR_API_AUTOPOPUP_REGISTERGUID, (int)0, g, desc, prefered_container, container_flag);
+}
+
+inline int wndmgr_api::autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container, int container_flag) {
+ return _call(WNDMGR_API_AUTOPOPUP_REGISTERGROUPID, (int)0, groupid, desc, prefered_container, container_flag);
+}
+
+inline void wndmgr_api::autopopup_unregister(int id) {
+ _voidcall(WNDMGR_API_AUTOPOPUP_UNREGISTER, id);
+}
+
+inline const wchar_t *wndmgr_api::varmgr_translate(const wchar_t *str) {
+ return _call(WNDMGR_API_VARMGR_TRANSLATE, (const wchar_t *)0, str);
+}
+/*
+inline Container *wndmgr_api::newDynamicContainer(const wchar_t *containername, int transcient) {
+ return _call(WNDMGR_API_NEWDYNAMICCONTAINER, (Container *)NULL, containername, transcient);
+}
+*/
+inline int wndmgr_api::autopopup_getNumGuids() {
+ return _call(WNDMGR_API_AUTOPOPUP_GETNUMGUIDS, 0);
+}
+
+inline GUID wndmgr_api::autopopup_enumGuid(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGUID, INVALID_GUID, n);
+}
+
+
+inline int wndmgr_api::autopopup_getNumGroups() {
+ return _call(WNDMGR_API_AUTOPOPUP_GETNUMGROUPS, 0);
+}
+
+inline const wchar_t *wndmgr_api::autopopup_enumGroup(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGROUPS, (const wchar_t*)NULL, n);
+}
+
+inline const wchar_t *wndmgr_api::autopopup_enumGuidDescription(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGUIDDESC, (const wchar_t *)NULL, n);
+}
+
+inline const wchar_t *wndmgr_api::autopopup_enumGroupDescription(int n) {
+ return _call(WNDMGR_API_AUTOPOPUP_ENUMGROUPDESC, (const wchar_t *)NULL, n);
+}
+
+class wndmgr_apiI : public wndmgr_api {
+ public:
+ virtual void wndTrackAdd(ifc_window *wnd)=0;
+ virtual void wndTrackRemove(ifc_window *wnd)=0;
+ virtual bool wndTrackDock(ifc_window *wnd, RECT *r, int mask)=0;
+ virtual bool wndTrackDock2(ifc_window *wnd, RECT *r, RECT *orig_r, int mask)=0;
+ virtual void wndTrackStartCooperative(ifc_window *wnd)=0;
+ virtual void wndTrackEndCooperative()=0;
+ virtual int wndTrackWasCooperative()=0;
+ virtual void wndTrackInvalidateAll()=0;
+ virtual int skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0)=0;
+ virtual int skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0)=0;
+ virtual ifc_window *skinwnd_createByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL)=0;
+ virtual ifc_window *skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL)=0;
+ virtual void skinwnd_destroy(ifc_window *w, RECT *destanimrect = NULL)=0;
+ virtual int skinwnd_getNumByGuid(GUID g)=0;
+ virtual ifc_window *skinwnd_enumByGuid(GUID g, int n)=0;
+ virtual int skinwnd_getNumByGroupId(const wchar_t *groupid)=0;
+ virtual ifc_window *skinwnd_enumByGroupId(const wchar_t *groupid, int n)=0;
+ virtual void skinwnd_attachToSkin(ifc_window *w, int side, int size)=0;
+ virtual ScriptObject *skin_getContainer(const wchar_t *container_name)=0;
+ virtual ScriptObject *skin_getLayout(ScriptObject *container, const wchar_t *layout_name)=0;
+ virtual void wndholder_register(WindowHolder *wh)=0;
+ virtual void wndholder_unregister(WindowHolder *wh)=0;
+ virtual int messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt)=0;
+ virtual ifc_window *getModalWnd()=0;
+ virtual void pushModalWnd(ifc_window *w = MODALWND_NOWND)=0;
+ virtual void popModalWnd(ifc_window *w = MODALWND_NOWND)=0;
+ virtual void drawAnimatedRects(const RECT *r1, const RECT *r2)=0;
+ virtual int autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0)=0;
+ virtual int autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0)=0;
+ virtual void autopopup_unregister(int id)=0;
+ virtual int autopopup_getNumGuids()=0;
+ virtual GUID autopopup_enumGuid(int n)=0;
+ virtual int autopopup_getNumGroups()=0;
+ virtual const wchar_t *autopopup_enumGroup(int n)=0;
+ virtual const wchar_t *varmgr_translate(const wchar_t *str)=0;
+ virtual Container *newDynamicContainer(const wchar_t *containername, int transcient = 1)=0;
+ virtual const wchar_t *autopopup_enumGuidDescription(int n)=0;
+ virtual const wchar_t *autopopup_enumGroupDescription(int n)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+// {038A3567-1530-4062-BA87-CCB4F01DA3E9}
+static const GUID wndMgrApiServiceGuid =
+{ 0x38a3567, 0x1530, 0x4062, { 0xba, 0x87, 0xcc, 0xb4, 0xf0, 0x1d, 0xa3, 0xe9 } };
+
+extern wndmgr_api *wndManagerApi;
+
+#endif //wndmgr_api_h
diff --git a/Src/Wasabi/api/wndmgr/appcmds.cpp b/Src/Wasabi/api/wndmgr/appcmds.cpp
new file mode 100644
index 00000000..93b6ab6d
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/appcmds.cpp
@@ -0,0 +1,61 @@
+#include <precomp.h>
+#include "appcmds.h"
+
+#define CBCLASS AppCmdsI
+START_DISPATCH;
+CB(APPCMDS_GETNUMCMDS, appcmds_getNumCmds);
+CB(APPCMDS_ENUMCMD, appcmds_enumCmd);
+VCB(APPCMDS_ONCOMMAND, appcmds_onCommand);
+END_DISPATCH;
+#undef CBCLASS
+
+AppCmdsI::~AppCmdsI()
+{
+ foreach(cmds)
+ if (cmds.getfor()->autodelete)
+ delete cmds.getfor();
+ endfor
+}
+
+void AppCmdsI::appcmds_addCmd(CmdRec *cmdrec)
+{
+ cmds.addItem(cmdrec);
+}
+
+void AppCmdsI::appcmds_addCmd(const wchar_t *name, int id, int side)
+{
+ cmds.addItem(new CmdRec(name, id, side, TRUE));
+}
+
+void AppCmdsI::appcmds_deleteAll()
+{
+ foreach(cmds)
+ if (cmds.getfor()->autodelete) delete cmds.getfor();
+ endfor
+ cmds.removeAll();
+}
+
+int AppCmdsI::appcmds_getNumCmds()
+{
+ return cmds.getNumItems();
+}
+
+const wchar_t *AppCmdsI::appcmds_enumCmd(int n, int *side, int *id)
+{
+ CmdRec *cr = cmds[n];
+ if (cr == NULL) return NULL;
+ if (side != NULL) *side = cr->side;
+ if (id != NULL) *id = cr->id;
+ return cr->cmdname;
+}
+
+void AppCmdsI::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ foreach(cmds)
+ if (cmds.getfor()->id == id)
+ {
+ cmds.getfor()->onCommand(buttonRect, which_button);
+ break;
+ }
+ endfor
+}
diff --git a/Src/Wasabi/api/wndmgr/appcmds.h b/Src/Wasabi/api/wndmgr/appcmds.h
new file mode 100644
index 00000000..fc3f3ec5
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/appcmds.h
@@ -0,0 +1,89 @@
+#ifndef _APPCMDS_H
+#define _APPCMDS_H
+
+#include <bfc/dispatch.h>
+#include <bfc/depend.h>
+#include <bfc/common.h>
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+
+class DragItem;
+
+// this will be fully dispatched later on
+class AppCmds : public Dispatchable
+{
+public:
+
+ int appcmds_getNumCmds();
+
+ const wchar_t *appcmds_enumCmd(int n, int *side, int *id);
+
+ enum {
+ SIDE_LEFT = 0, SIDE_RIGHT = 1
+ };
+
+ enum {
+ LEFT_CLICK = 0,
+ RIGHT_CLICK = 1,
+ };
+
+ void appcmds_onCommand(int id, const RECT *buttonRect, int which_button); //onscreen coords
+
+ enum {
+ APPCMDS_GETNUMCMDS = 100,
+ APPCMDS_ENUMCMD = 200,
+ APPCMDS_ONCOMMAND = 300,
+ };
+};
+
+inline int AppCmds::appcmds_getNumCmds()
+{
+ return _call(APPCMDS_GETNUMCMDS, 0);
+}
+
+inline const wchar_t *AppCmds::appcmds_enumCmd(int n, int *side, int *id)
+{
+ return _call(APPCMDS_ENUMCMD, (const wchar_t *)NULL, n, side, id);
+}
+
+inline void AppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ _voidcall(APPCMDS_ONCOMMAND, id, buttonRect, which_button);
+}
+
+class CmdRec
+{
+public:
+ CmdRec(const wchar_t *name, int _id, int _side, int _autodelete = 0) : cmdname(name), id(_id), side(_side), autodelete(_autodelete) {}
+ virtual ~CmdRec() {}
+ StringW cmdname;
+ int id, side;
+ int autodelete;
+
+ virtual void onCommand(const RECT *buttonRect, int which_button) {}}
+;
+
+class AppCmdsI : public AppCmds
+{
+public:
+ AppCmdsI() { }
+ virtual ~AppCmdsI();
+
+protected:
+ void appcmds_addCmd(CmdRec *cmdrec);
+ void appcmds_addCmd(const wchar_t *name, int id, int side = SIDE_LEFT);
+ void appcmds_deleteAll(); //calls delete on each one
+
+public:
+ virtual int appcmds_getNumCmds();
+ virtual const wchar_t *appcmds_enumCmd(int n, int *side, int *id);
+
+ // override this and catch your commands, otherwise it'll call the CmdRec
+ virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_button);
+
+protected:
+ RECVS_DISPATCH;
+ PtrList<CmdRec> cmds;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/autopopup.cpp b/Src/Wasabi/api/wndmgr/autopopup.cpp
new file mode 100644
index 00000000..58212998
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/autopopup.cpp
@@ -0,0 +1,157 @@
+#include <precomp.h>
+#include "autopopup.h"
+
+static PtrListQuickSorted<AutoPopupEntry, AutoPopupEntrySort> entries;
+static int nid=0;
+
+int AutoPopup::registerGuid(int skinpartid, GUID g, const wchar_t *desc, const wchar_t *prefered_container, int required)
+{
+ if (desc == NULL || !*desc) desc = L"[????]";
+ AutoPopupEntry *ape = new AutoPopupEntry(skinpartid, g, NULL, desc, prefered_container, required);
+ entries.addItem(ape);
+ return ape->getNid();
+}
+
+int AutoPopup::registerGroupId(int skinpartid, const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container, int required) {
+ if (desc == NULL || !*desc) desc = L"[????]";
+ AutoPopupEntry *ape = new AutoPopupEntry(skinpartid, INVALID_GUID, groupid, desc, prefered_container, required);
+ entries.addItem(ape);
+ return ape->getNid();
+}
+
+int AutoPopup::getNumItems() { return entries.getNumItems(); }
+AutoPopupEntry *AutoPopup::enumItem(int n) { return entries.enumItem(n); }
+
+int AutoPopup::getNumGroups() {
+ int n = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() != NULL && e->getGuid() == INVALID_GUID) n++;
+ endfor;
+ return n;
+}
+
+int AutoPopup::getNumGuids() {
+ int n = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() == NULL && e->getGuid() != INVALID_GUID) n++;
+ endfor;
+ return n;
+}
+
+const wchar_t *AutoPopup::enumGroup(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() != NULL && e->getGuid() == INVALID_GUID) {
+ if (c == n) return e->getGroupId();
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+GUID AutoPopup::enumGuid(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() == NULL && e->getGuid() != INVALID_GUID) {
+ if (c == n) return e->getGuid();
+ c++;
+ }
+ endfor;
+ return INVALID_GUID;
+}
+
+const wchar_t *AutoPopup::enumGroupDescription(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() != NULL && e->getGuid() == INVALID_GUID) {
+ if (c == n) return e->getDescription();
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+const wchar_t *AutoPopup::enumGuidDescription(int n) {
+ int c = 0;
+ foreach(entries)
+ AutoPopupEntry *e = entries.getfor();
+ if (e->getGroupId() == NULL && e->getGuid() != INVALID_GUID) {
+ if (c == n) return e->getDescription();
+ c++;
+ }
+ endfor;
+ return NULL;
+}
+
+
+AutoPopupEntry *AutoPopup::getByDesc(const wchar_t *desc) {
+ foreach(entries)
+ if (!WCSICMP(desc, entries.getfor()->getDescription()))
+ return entries.getfor();
+ endfor;
+ return NULL;
+}
+
+void AutoPopup::reset() { entries.deleteAll(); nid = 0; }
+
+const wchar_t *AutoPopup::getDefaultContainerParams(const wchar_t *groupid, GUID g, int *flag) {
+ if (groupid == NULL) { // guid
+ for (int i=entries.getNumItems()-1;i>=0;i--) {
+ if (entries.enumItem(i)->getGuid() == g) {
+ if (flag != NULL) *flag = entries.enumItem(i)->getContainerHow();
+ return entries.enumItem(i)->getPreferedContainer();
+ }
+ }
+ } else { // groupid
+ for (int i=entries.getNumItems()-1;i>=0;i--)
+ {
+ if (WCSCASEEQLSAFE(entries.enumItem(i)->getGroupId(), groupid))
+ {
+ if (flag != NULL) *flag = entries.enumItem(i)->getContainerHow();
+ return entries.enumItem(i)->getPreferedContainer();
+ }
+ }
+ }
+ return NULL;
+}
+
+void AutoPopup::unregister(int id) {
+ for (int i=0;i<entries.getNumItems();i++) {
+ AutoPopupEntry *ape = entries.enumItem(i);
+ if (ape->getNid() == id) {
+ delete ape;
+ entries.removeByPos(i);
+ i--;
+ continue;
+ }
+ }
+}
+
+void AutoPopup::removeSkinPart(int id) {
+ for (int i=0;i<entries.getNumItems();i++) {
+ AutoPopupEntry *ape = entries.enumItem(i);
+ if (ape->getSkinpart() == id) {
+ delete ape;
+ entries.removeByPos(i);
+ i--;
+ }
+ }
+}
+
+int AutoPopup::allocNid() { return nid++; }
+
+void AutoPopup::removeAllAddons() {
+ for (int i=0;i<entries.getNumItems();i++) {
+ AutoPopupEntry *ape = entries.enumItem(i);
+ if (ape->getSkinpart() != SKINPARTID_NONE) {
+ delete ape;
+ entries.removeByPos(i);
+ i--;
+ }
+ }
+}
diff --git a/Src/Wasabi/api/wndmgr/autopopup.h b/Src/Wasabi/api/wndmgr/autopopup.h
new file mode 100644
index 00000000..c37bd122
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/autopopup.h
@@ -0,0 +1,76 @@
+#ifndef __AUTOPOPUP_H
+#define __AUTOPOPUP_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+class AutoPopupEntry;
+class AutoPopupEntrySort;
+
+#define SKINPARTID_NONE -1
+
+class AutoPopup {
+
+ public:
+
+ static int registerGuid(int skinpartid/*SKINPARTID_NONE*/, GUID g, const wchar_t *desc, const wchar_t *prefered_container=NULL, int required=FALSE);
+ static int registerGroupId(int skinpartid/*SKINPARTID_NONE*/, const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container=NULL, int required=FALSE);
+ static void unregister(int id);
+
+ static int getNumItems();
+ static AutoPopupEntry *enumItem(int n);
+ static AutoPopupEntry *getByDesc(const wchar_t *desc);
+
+ static void reset();
+ static void removeSkinPart(int id);
+
+ static int allocNid();
+ static void removeAllAddons();
+
+ static int getNumGuids();
+ static GUID enumGuid(int n);
+ static int getNumGroups();
+ static const wchar_t *enumGroup(int n);
+ static const wchar_t *enumGuidDescription(int n);
+ static const wchar_t *enumGroupDescription(int n);
+
+ static const wchar_t *getDefaultContainerParams(const wchar_t *groupid, GUID g, int *flag);
+};
+
+class AutoPopupEntry {
+
+ public:
+
+ AutoPopupEntry(int skinpartid, GUID g, const wchar_t *grpid, const wchar_t *description, const wchar_t *prefered_container=NULL, int required=TRUE) : guid(g), groupid(grpid), desc(description), container(prefered_container), container_how(required), skinpart(skinpartid) { nid = AutoPopup::allocNid(); }
+ virtual ~AutoPopupEntry() { }
+
+ GUID getGuid() { return guid; }
+ const wchar_t *getGroupId() { return groupid; }
+ const wchar_t *getDescription() { return desc; }
+ int getNid() { return nid; }
+ const wchar_t *getPreferedContainer() { return container; }
+ int getContainerHow() { return container_how; }
+ int getSkinpart() { return skinpart; }
+
+ private:
+
+ GUID guid;
+ StringW groupid;
+ StringW desc;
+ int nid;
+ StringW container;
+ int container_how;
+ int skinpart;
+};
+
+class AutoPopupEntrySort {
+public:
+ static int compareItem(AutoPopupEntry *p1, AutoPopupEntry *p2) {
+ return WCSICMP(p1->getDescription(), p2->getDescription());
+ }
+ static int compareAttrib(const wchar_t *attrib, AutoPopupEntry *item) {
+ return WCSICMP(attrib, item->getDescription());
+ }
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/container.cpp b/Src/Wasabi/api/wndmgr/container.cpp
new file mode 100644
index 00000000..cfa7485e
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/container.cpp
@@ -0,0 +1,919 @@
+#include <precomp.h>
+#include "wasabicfg.h"
+#include <api/wndmgr/container.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <api/config/items/attrbool.h>
+#include <api/config/items/cfgitem.h>
+#include <api/skin/skinparse.h>
+#include <api/wac/compon.h>
+#include <api/wnd/wndtrack.h>
+#include <api/skin/skin.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include <bfc/string/stringdict.h>
+#include <api/skin/widgets/xuiwndholder.h> // TODO: cut, but we need XuiWindowHolder::parseGUID for now
+#include <bfc/platform/guid.h>
+
+#ifdef WIN32
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+#endif
+
+BEGIN_STRINGDICTIONARY(_containerparams)
+SDI(L"name", CONTAINERPARAM_NAME);
+SDI(L"id", CONTAINERPARAM_ID);
+SDI(L"dynamic", CONTAINERPARAM_DYNAMIC);
+SDI(L"default_x", CONTAINERPARAM_DEFAULTX);
+SDI(L"default_y", CONTAINERPARAM_DEFAULTY);
+SDI(L"default_visible", CONTAINERPARAM_DEFAULTVISIBLE);
+SDI(L"canclose", CONTAINERPARAM_CANCLOSE);
+SDI(L"nomenu", CONTAINERPARAM_NOMENU);
+SDI(L"nofocusapponclose", CONTAINERPARAM_NOFOCUSAPPONCLOSE);
+SDI(L"primarycomponent", CONTAINERPARAM_CONTENT);
+END_STRINGDICTIONARY(_containerparams, containerparams);
+
+Container::Container(int script_id)
+{
+ getScriptObject()->vcpu_setInterface(containerGuid, (void *)static_cast<Container *>(this));
+ getScriptObject()->vcpu_setClassName(L"Container");
+ getScriptObject()->vcpu_setController(containerController);
+ scriptid = script_id;
+ currentLayout = -1;
+ default_visible = TRUE;
+ loaded_default_visible = TRUE;
+ dynamic = 0;
+ MEMCPY(&myGUID, &INVALID_GUID, sizeof(GUID));
+ lastLayout = -1;
+ refocusapponclose = 1;
+ canclose = 1;
+ inited = 0;
+ deleting = 0;
+ transcient = 0;
+ switching_layout = 0;
+ nomenu = 0;
+ prevent_save_visibility = 0;
+ contentGuid = INVALID_GUID;
+ hasContentGuid=false;
+}
+
+
+void Container::setName(const wchar_t *name)
+{
+#ifdef ON_TWEAK_CONTAINER_NAMEW
+ ON_TWEAK_CONTAINER_NAMEW(name);
+#endif
+ containerName = name ? name : CONTAINER_UNDEFINED_NAME;
+ foreach(layouts)
+ Layout *l = layouts.getfor();
+ if (l->getRootWndName() == NULL)
+ {
+ l->setOSWndName(name);
+ }
+ endfor;
+ updateDefaultVisible();
+
+ dependent_sendEvent(Container::depend_getClassGuid(), Event_NAMECHANGE, 0, this);
+}
+
+void Container::resetLayouts()
+{
+ updateDefaultVisible();
+
+ foreach(layouts)
+ layouts.getfor()->loadSavedState();
+ endfor;
+}
+
+void Container::setId(const wchar_t *id)
+{
+ containerId = id ? id : L"undefined";
+ ismain = !WCSICMP(id, L"main");
+}
+
+int Container::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ switch (containerparams.getId(paramname))
+ {
+ case CONTAINERPARAM_NAME:
+ setName(strvalue);
+ return 1;
+ case CONTAINERPARAM_ID:
+ setId(strvalue);
+ return 1;
+ case CONTAINERPARAM_DYNAMIC:
+ setDynamic(WTOI(strvalue));
+ return 1;
+ case CONTAINERPARAM_DEFAULTX:
+ default_x = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_DEFAULTY:
+ default_y = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_DEFAULTVISIBLE:
+ default_visible = WTOI(strvalue);
+ updateDefaultVisible();
+ return 1;
+ case CONTAINERPARAM_CANCLOSE:
+ canclose = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_NOMENU:
+ nomenu = WTOI(strvalue);
+ return 1;
+ case CONTAINERPARAM_NOFOCUSAPPONCLOSE:
+ refocusapponclose = !WTOI(strvalue);
+ break;
+ case CONTAINERPARAM_CONTENT:
+ {
+ // TODO: move this out of XuiWindowHolder
+ GUID *g = XuiWindowHolder::parseGUID(strvalue);
+ contentGuid = *g;
+ hasContentGuid=true;
+
+ break;
+ }
+
+ }
+ return 0;
+}
+
+Container::~Container()
+{
+ containerCallback(CONT_CB_HIDDEN);
+ layouts.deleteAll();
+ contents.deleteAll();
+ SkinParser::containers.removeItem(this);
+}
+
+void Container::getWindowRect(RECT *r)
+{
+ Layout *l = getCurrentLayout();
+ if (l)
+ l->getWindowRect(r);
+}
+
+void Container::addLayout(Layout *layout)
+{
+ layouts.addItem(layout);
+}
+
+const wchar_t *Container::getName()
+{
+ return containerName;
+}
+
+const wchar_t *Container::getId()
+{
+ return containerId;
+}
+
+int Container::getDefaultPositionX(void)
+{
+ return default_x;
+}
+
+int Container::getDefaultPositionY(void)
+{
+ return default_y;
+}
+
+void Container::onInit(int noshow)
+{
+ if (inited) return ;
+ inited++;
+ loadFromDefaults(noshow);
+}
+
+void Container::loadFromDefaults(int noshow)
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (last_layout.isempty())
+ {
+ StringPrintfW tmp(L"container_%s|active", getName());
+ wchar_t c[512] = {0};
+ WASABI_API_CONFIG->getStringPrivate(tmp, c, 511, L"");
+ c[510] = 0;
+ last_layout = c;
+ }
+#endif
+
+ if (loaded_default_visible)
+ {
+ showDefaultLayout(noshow);
+ }
+}
+
+void Container::setDefaultLayout(const wchar_t *name)
+{
+ last_layout = name;
+}
+
+void Container::showDefaultLayout(int noshow)
+{
+ Layout *l = getLayout(last_layout);
+
+ if (!l)
+ l = layouts.enumItem(0);
+
+ if (l)
+ {
+ currentLayout = layouts.searchItem(l);
+
+ if (!noshow)
+ l->setVisible(1);
+
+ containerCallback(CONT_CB_VISIBLE); // since we set currentLayout prior to showing the layout, the callback will not be processed in onChildSetLayoutVisible
+ }
+}
+
+void Container::setVisible(int sh)
+{
+ if (!sh && !canclose)
+ return ;
+
+ int is = isVisible();
+
+ if (!!sh == !!is)
+ return ;
+
+ Layout *l = getCurrentLayout();
+
+ if (!l && lastLayout != -1)
+ l = layouts[lastLayout];
+
+ if (sh)
+ {
+ if (!l)
+ showDefaultLayout();
+ else
+ {
+ l->setVisible(1);
+ }
+ }
+ else
+ {
+ if (l)
+ l->setVisible(0);
+ }
+}
+
+int Container::isVisible()
+{
+ if (switching_layout) return 1;
+ Layout *l = getCurrentLayout();
+ if (!l) return 0;
+ return l->isVisible();
+}
+
+void Container::onChildSetLayoutVisible(Layout *l, int v)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ {
+ if (layouts[i] == l)
+ {
+ if (v)
+ {
+ if (currentLayout != i)
+ {
+ Layout *l = NULL;
+ if (currentLayout >= 0)
+ l = layouts[currentLayout];
+ if (l) l->setVisible(0);
+ containerCallback(CONT_CB_VISIBLE);
+ currentLayout = i;
+ l = layouts[currentLayout];
+#ifdef WASABI_COMPILE_CONFIG
+ if (!isTranscient() && !prevent_save_visibility)
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"container_%s|active", getName()), l->getGuiObject()->guiobject_getId());
+#endif
+#ifdef WA3COMPATIBILITY
+ l->setForwardMsgWnd(WASABI_API_WND->main_getRootWnd()->gethWnd());
+#endif
+ if (l->wantActivation())
+ {
+ l->bringToFront();
+ l->setFocus();
+ }
+ l->invalidate();
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ if (!isTranscient() && !isDynamic() && !prevent_save_visibility)
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"activated/%s", getName()), v);
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"everloaded/%s", getName()), 1);
+#endif
+
+ }
+ else
+ {
+ if (i == currentLayout)
+ {
+ if (!isDeleting() && !isTranscient() && !isDynamic())
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"activated/%s", getName()), v);
+#endif
+ lastLayout = currentLayout;
+ currentLayout = -1;
+ }
+ containerCallback(CONT_CB_HIDDEN);
+ }
+ }
+ return ;
+ }
+ }
+}
+
+void Container::containerCallback(int msg)
+{
+ switch (msg)
+ {
+ case CONT_CB_VISIBLE:
+ {
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ WndInfo i;
+ i.groupid = e->groupid;
+ i.guid = e->guid;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::SHOWWINDOW, reinterpret_cast<intptr_t>(&i));
+ endfor
+ WndInfo i;
+ i.groupid = getId();
+ i.guid = INVALID_GUID;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::SHOWWINDOW, reinterpret_cast<intptr_t>(&i));
+ }
+ break;
+ case CONT_CB_HIDDEN:
+ {
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ WndInfo i;
+ i.groupid = e->groupid;
+ i.guid = e->guid;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::HIDEWINDOW, reinterpret_cast<intptr_t>(&i));
+ endfor
+ WndInfo i;
+ i.groupid = getId();
+ i.guid = INVALID_GUID;
+ i.c = this;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::WINDOW, WndCallback::HIDEWINDOW, reinterpret_cast<intptr_t>(&i));
+ }
+ break;
+ }
+}
+
+void Container::close()
+{
+ int norefocs = !wantRefocusApp();
+ if (norefocs) WASABI_API_WND->appdeactivation_push_disallow(NULL);
+ if (!canclose) return ;
+ if (isDynamic())
+ {
+ setVisible(0);
+ skinEmbedder->destroyContainer(this); // deferred
+ }
+ else
+ setVisible(0);
+ if (norefocs) WASABI_API_WND->appdeactivation_pop_disallow(NULL);
+}
+
+void Container::toggle()
+{
+ if (isVisible()) close(); else setVisible(1); // close has special function hide/destroy depending on dynamic status
+}
+
+void Container::switchToLayout(const wchar_t *name, int moveit)
+{
+ int l = -1;
+ getLayout(name, &l);
+
+ if (l == -1)
+ {
+ // Layout not found, reverting to first in the list
+ if (layouts.getNumItems() > 0) l = 0;
+ else
+ return ; // none found, abort
+ }
+
+ switching_layout = 1;
+ if (l != currentLayout)
+ {
+ int old = currentLayout;
+ RECT r = {0};
+ Layout *oldlayout = old >= 0 ? layouts[old] : NULL;
+ Layout *newlayout = layouts[l];
+ onBeforeSwitchToLayout(oldlayout, newlayout);
+ if (oldlayout)
+ {
+ oldlayout->getWindowRect(&r);
+ oldlayout->endCapture();
+ }
+ int unlinked = layouts[l]->isUnlinked();
+ unlinked |= oldlayout ? oldlayout->isUnlinked() : 0;
+ if (moveit && !unlinked && oldlayout)
+ layouts[l]->move(r.left, r.top);
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ if (_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Link layouts scale"))
+ {
+#else
+ if (WASABI_WNDMGR_LINKLAYOUTSCALES)
+ {
+#endif
+ if (oldlayout)
+ {
+ double _r = oldlayout->getRenderRatio();
+ newlayout->setRenderRatio(_r);
+ }
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ if (_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Link layouts alpha"))
+ {
+#else
+ if (WASABI_WNDMGR_LINKLAYOUTSALPHA)
+ {
+#endif
+ if (oldlayout)
+ {
+ int a = layouts[old]->getAlpha();
+ newlayout->setAlpha(a);
+ int autoopacify = layouts[old]->getAutoOpacify();
+ newlayout->setAutoOpacify(autoopacify);
+ }
+ }
+
+ WindowTracker::layoutChanged(oldlayout, newlayout);
+#ifdef ON_LAYOUT_CHANGED
+ ON_LAYOUT_CHANGED;
+#endif
+ layouts[l]->setVisible(1);
+ foreach(SkinParser::containers)
+ SkinParser::containers.getfor()->savePositions();
+ endfor
+ onSwitchToLayout(newlayout);
+ }
+ switching_layout = 0;
+}
+
+void Container::savePositions()
+{
+ foreach (layouts)
+ layouts.getfor()->savePosition();
+ endfor
+}
+
+Layout *Container::getLayout(const wchar_t *name, int *pos)
+{
+ for ( int i = 0; i < getNumLayouts(); i++ )
+ {
+ if ( WCSCASEEQLSAFE( enumLayout( i )->getGuiObject()->guiobject_getId(), name ) )
+ {
+ if (pos)
+ {
+ *pos = i;
+ }
+
+ return enumLayout( i );
+
+ }
+ }
+
+ return NULL;
+}
+
+Layout *Container::getCurrentLayout()
+{
+ if (currentLayout < 0)
+ return NULL;
+
+ return layouts.enumItem(currentLayout);
+}
+
+void Container::otherContainerToggled(const wchar_t *id, int visible)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ layouts[i]->containerToggled(id, visible);
+}
+
+void Container::componentToggled(GUID *g, int visible)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ layouts[i]->componentToggled(g, visible);
+}
+
+void Container::sendNotifyToAllLayouts(int notifymsg, int param1, int param2)
+{
+ for (int i = 0;i < layouts.getNumItems();i++)
+ layouts[i]->sendNotifyToAllChildren(notifymsg, param1, param2);
+}
+
+int Container::isMainContainer()
+{
+ return ismain;
+}
+
+void Container::sysMenu()
+{
+ POINT p;
+ Wasabi::Std::getMousePos(&p);
+ layouts.enumItem(currentLayout)->onRightButtonDown(p.x, p.y);
+}
+
+void Container::setDynamic(int i)
+{
+ dynamic = i;
+ if (!containerId.isempty())
+ setId(containerId);
+}
+
+int Container::isDynamic()
+{
+ return dynamic;
+}
+
+void Container::onSwitchToLayout(Layout *l)
+{
+ ScriptObject *ls = l ? l->getGuiObject()->guiobject_getScriptObject() : NULL;
+ script_onSwitchToLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(ls));
+}
+
+void Container::onBeforeSwitchToLayout(Layout *oldl, Layout *newl)
+{
+ ScriptObject *olds = oldl ? oldl->getGuiObject()->guiobject_getScriptObject() : NULL;
+ ScriptObject *news = newl ? newl->getGuiObject()->guiobject_getScriptObject() : NULL;
+ script_onBeforeSwitchToLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(olds), MAKE_SCRIPT_OBJECT(news));
+}
+
+
+void Container::onHideLayout(Layout *l)
+{
+ script_onHideLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(l->getGuiObject()->guiobject_getScriptObject()));
+}
+
+void Container::onShowLayout(Layout *l)
+{
+ script_onShowLayout(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(l->getGuiObject()->guiobject_getScriptObject()));
+}
+
+int Container::getNumLayouts()
+{
+ return layouts.getNumItems();
+}
+
+Layout *Container::enumLayout(int n)
+{
+ return layouts.enumItem(n);
+}
+
+const wchar_t *Container::getDescriptor()
+{
+ static wchar_t d[256];
+ // if we've tweaked the container names then when saving out we can see and attempt to 'untweak'
+ // so that things like Winamp Modern's ML will be correctly positioned irrespective of language
+ int untweak = 0;
+ wchar_t tweaked[96] = {0};
+ // Martin> We need to check the containerName against null - dunno why some skins cause this string to be null
+ if(containerName.v() != NULL && !_wcsicmp(containerName.v(), WASABI_API_LNGSTRINGW_BUF(IDS_MEDIA_LIBRARY,tweaked,96))){
+ untweak = 1;
+ }
+ WCSNPRINTF(d, 256,L"%s/%s", getId(), (!untweak ? containerName.v() : L"Media Library"));
+ return d;
+}
+
+void Container::updateDefaultVisible()
+{
+ if (!canclose)
+ {
+ loaded_default_visible = 1;
+ return ;
+ }
+#ifdef WASABI_COMPILE_CONFIG
+ loaded_default_visible = WASABI_API_CONFIG->getIntPrivate(StringPrintfW(L"activated/%s", getName()), default_visible);
+#else
+ loaded_default_visible = default_visible;
+#endif
+}
+
+int Container::getScriptId()
+{
+ return scriptid;
+}
+
+void Container::notifyAddContent(ifc_window *w, const wchar_t *id, GUID g)
+{
+ contents.addItem(new ContentEntry(id, g, w));
+ ScriptObject *_w = w ? w->getGuiObject()->guiobject_getScriptObject() : NULL;
+ wchar_t guidstr[256] = {0};
+ nsGUID::toCharW(g, guidstr);
+ script_onAddContent(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_OBJECT(_w), MAKE_SCRIPT_STRING(id), MAKE_SCRIPT_STRING(guidstr));
+}
+
+void Container::notifyRemoveContent(ifc_window *w)
+{
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ if (e->wnd == w)
+ {
+ contents.removeItem(e);
+ delete e;
+ return ;
+ }
+ endfor;
+}
+
+int Container::hasContent(GUID g)
+{
+ foreach(contents)
+ ContentEntry *e = contents.getfor();
+ if (e->guid == g)
+ {
+ return 1;
+ }
+ endfor;
+ return 0;
+}
+
+GUID Container::getDefaultContent()
+{
+ if (hasContentGuid)
+ return contentGuid;
+ if (contents.getNumItems() > 0) return contents.enumItem(0)->guid;
+ return INVALID_GUID;
+}
+
+ContainerScriptController _containerController;
+ContainerScriptController *containerController = &_containerController;
+
+
+// -- Functions table -------------------------------------
+function_descriptor_struct ContainerScriptController::exportedFunction[] = {
+ {L"onSwitchToLayout", 1, (void*)Container::script_onSwitchToLayout },
+ {L"onBeforeSwitchToLayout", 2, (void*)Container::script_onBeforeSwitchToLayout },
+ {L"onHideLayout", 1, (void*)Container::script_onHideLayout },
+ {L"onShowLayout", 1, (void*)Container::script_onShowLayout },
+ {L"getLayout", 1, (void*)Container::script_getLayout },
+ {L"getNumLayouts", 0, (void*)Container::script_getNumLayouts },
+ {L"enumLayout", 1, (void*)Container::script_enumLayout },
+ {L"getCurLayout", 0, (void*)Container::script_getCurrentLayout},
+ {L"switchToLayout", 1, (void*)Container::script_switchToLayout },
+ {L"isDynamic", 0, (void*)Container::script_isDynamic },
+ {L"show", 0, (void*)Container::script_show },
+ {L"hide", 0, (void*)Container::script_hide },
+ {L"close", 0, (void*)Container::script_close},
+ {L"toggle", 0, (void*)Container::script_toggle },
+ {L"setName", 1, (void*)Container::script_setName },
+ {L"getName", 0, (void*)Container::script_getName },
+ {L"getGuid", 0, (void*)Container::script_getGuid },
+ {L"setXmlParam", 2, (void*)Container::script_setXmlParam},
+ {L"onAddContent", 3, (void*)Container::script_onAddContent},
+ };
+// --------------------------------------------------------
+
+/*SET_HIERARCHY(Container, SCRIPT_CONTAINER);
+SET_HIERARCHY2(Container, SCRIPT_CONTAINER, CONTAINER_SCRIPTPARENT);*/
+
+const wchar_t *ContainerScriptController::getClassName()
+{
+ return L"Container";
+}
+
+const wchar_t *ContainerScriptController::getAncestorClassName()
+{
+ return L"Object";
+}
+
+ScriptObjectController *ContainerScriptController::getAncestorController()
+{
+ return rootScriptObjectController;
+}
+
+int ContainerScriptController::getInstantiable()
+{
+ return 1;
+}
+
+ScriptObject *ContainerScriptController::instantiate()
+{
+ Container *c = new Container;
+ return c->getScriptObject();
+}
+
+void ContainerScriptController::destroy(ScriptObject *o)
+{
+ //ASSERTALWAYS("be nice, don't do that");
+ Container *c = (Container *)o->vcpu_getInterface(containerGuid);
+ delete c;
+}
+
+void *ContainerScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void ContainerScriptController::deencapsulate(void *o)
+{}
+
+
+int ContainerScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *ContainerScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID ContainerScriptController::getClassGuid()
+{
+ return containerGuid;
+}
+
+//-----------------------------------------------------------------------
+
+scriptVar Container::script_onSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, containerController, l);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, l);
+}
+
+scriptVar Container::script_onBeforeSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar oldl, scriptVar newl)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS2(o, containerController, oldl, newl);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT2(o, oldl, newl);
+}
+
+scriptVar Container::script_onHideLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, containerController, l);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, l);
+}
+
+scriptVar Container::script_onShowLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, containerController, l);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, l);
+}
+
+// Get an layout from its ID
+scriptVar Container::script_getLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(obj.type == SCRIPT_STRING); // compiler discarded
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c)
+ {
+ for (int i = 0;i < c->layouts.getNumItems();i++)
+ if (!WCSICMP(obj.data.sdata, c->layouts.enumItem(i)->getGuiObject()->guiobject_getId()))
+ {
+ return MAKE_SCRIPT_OBJECT(c->layouts.enumItem(i)->getGuiObject()->guiobject_getScriptObject());
+ }
+ }
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Container::script_show(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setVisible(1);
+ RETURN_SCRIPT_VOID;
+}
+scriptVar Container::script_hide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setVisible(0);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_close(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->close();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_toggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->toggle();
+ RETURN_SCRIPT_VOID;
+}
+
+// Switch to another layout
+scriptVar Container::script_switchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c)
+ c->switchToLayout(GET_SCRIPT_STRING(l));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_getNumLayouts(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) return MAKE_SCRIPT_INT(c->getNumLayouts());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Container::script_enumLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n)
+{
+ SCRIPT_FUNCTION_INIT
+ ASSERT(SOM::isNumeric(&n)); // compiler discarded
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ Layout *l = NULL;
+ if (c) l = c->enumLayout(SOM::makeInt(&n));
+ return MAKE_SCRIPT_OBJECT(l ? l->getScriptObject() : NULL);
+}
+
+scriptVar Container::script_getCurrentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ Layout *l = c->getCurrentLayout();
+ return MAKE_SCRIPT_OBJECT(l ? l->getScriptObject() : NULL);
+}
+
+// Switch to another layout
+scriptVar Container::script_vcpu_getId(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+
+ if (c)
+ return MAKE_SCRIPT_STRING(c->getId());
+
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Container::script_isDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) return MAKE_SCRIPT_INT(c->isDynamic());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Container::script_setName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setName(GET_SCRIPT_STRING(name));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Container::script_getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) return MAKE_SCRIPT_STRING(c->getName());
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Container::script_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c)
+ {
+ static wchar_t guidstr[256];
+ nsGUID::toCharW(c->getGUID(), guidstr);
+ return MAKE_SCRIPT_STRING(guidstr);
+ }
+ return MAKE_SCRIPT_STRING(L"");
+}
+
+scriptVar Container::script_setXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ Container *c = static_cast<Container *>(o->vcpu_getInterface(containerGuid));
+ if (c) c->setXmlParam(GET_SCRIPT_STRING(p), GET_SCRIPT_STRING(v));
+ RETURN_SCRIPT_VOID;
+}
+
+//void Container::notifyAddContent(ifc_window *w, const wchar_t *id, GUID g)
+scriptVar Container::script_onAddContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar window, scriptVar id, scriptVar g)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS3(o, containerController, window, id, g);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT3(o, window, id, g);
+}
+
diff --git a/Src/Wasabi/api/wndmgr/container.h b/Src/Wasabi/api/wndmgr/container.h
new file mode 100644
index 00000000..0078057d
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/container.h
@@ -0,0 +1,231 @@
+#ifdef WASABI_COMPILE_WNDMGR
+#ifndef __CONTAINER_H
+#define __CONTAINER_H
+
+class Container;
+class Layout;
+
+#include <bfc/ptrlist.h>
+#include <api/skin/xmlobject.h>
+
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#include <api/script/objcontroller.h>
+#include <api/script/objects/rootobj.h>
+
+
+#define CONTAINER_UNDEFINED_NAME L"undefined container name"
+
+enum {
+ CONTAINERPARAM_NAME = 0,
+ CONTAINERPARAM_ID,
+ CONTAINERPARAM_DYNAMIC,
+ CONTAINERPARAM_DEFAULTX,
+ CONTAINERPARAM_DEFAULTY,
+ CONTAINERPARAM_DEFAULTVISIBLE,
+ CONTAINERPARAM_CANCLOSE,
+ CONTAINERPARAM_NOMENU,
+ CONTAINERPARAM_NOFOCUSAPPONCLOSE,
+ CONTAINERPARAM_CONTENT,
+};
+
+class ContainerScriptController: public ScriptObjectControllerI
+{
+public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController();
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+ virtual int getInstantiable();
+
+private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+class ContentEntry
+{
+public:
+ ContentEntry(const wchar_t *gid, GUID g, ifc_window *w) : groupid(gid), guid(g), wnd(w) { }
+
+ GUID guid;
+ StringW groupid;
+ ifc_window *wnd;
+};
+
+extern ContainerScriptController *containerController;
+
+#define CONTAINER_SCRIPTPARENT RootObjectInstance
+
+class Container : public CONTAINER_SCRIPTPARENT, public XmlObjectI, public DependentI
+{
+
+public:
+ Container(int scriptid = -1);
+ virtual ~Container();
+
+ virtual void setName(const wchar_t *name);
+ virtual void setId(const wchar_t *id);
+
+ virtual const wchar_t *getName();
+ virtual const wchar_t *getId();
+
+ virtual int setXmlParam(const wchar_t *p, const wchar_t *v);
+
+ virtual void onInit(int noshow = 0);
+
+ virtual void addLayout(Layout *layout);
+ virtual void resetLayouts();
+
+ virtual void setVisible(int sh);
+ virtual int isVisible();
+
+ virtual void switchToLayout(const wchar_t *name, int moveit = 1);
+ virtual void toggle();
+ virtual void close();
+ virtual void sysMenu();
+ virtual int getNumLayouts();
+ virtual Layout *enumLayout(int n);
+ virtual Layout *getLayout(const wchar_t *name, int *pos = NULL);
+ virtual int getScriptId();
+ virtual void savePositions();
+ void setDefaultLayout(const wchar_t *name);
+ void loadFromDefaults(int noshow = 0);
+ int isTranscient() { return transcient; }
+ void setTranscient(int is) { transcient = is; }
+
+ // player callbacks to notify that container/component
+ // has been set visible/invisible
+ virtual void otherContainerToggled(const wchar_t *id, int visible);
+ virtual void componentToggled(GUID *g, int visible);
+
+ virtual int isMainContainer();
+ virtual int isDynamic();
+
+ virtual void onSwitchToLayout(Layout *l);
+ virtual void onBeforeSwitchToLayout(Layout *oldl, Layout *newl);
+ virtual void onHideLayout(Layout *l);
+ virtual void onShowLayout(Layout *l);
+ virtual Layout *getCurrentLayout();
+ virtual int getDefaultPositionX(void);
+ virtual int getDefaultPositionY(void);
+ virtual void onChildSetLayoutVisible(Layout *l, int v);
+
+ virtual void notifyAddContent(ifc_window *w, const wchar_t *groupid, GUID guid = INVALID_GUID);
+ virtual void notifyRemoveContent(ifc_window *w);
+ virtual int hasContent(GUID g);
+ virtual GUID getDefaultContent();
+
+ const wchar_t *getDescriptor(void);
+
+ virtual void getWindowRect(RECT *r);
+
+ virtual void sendNotifyToAllLayouts(int notifymsg, int param1, int param2);
+ void setDynamic(int i);
+
+ void updateDefaultVisible();
+ void setDeleting() { deleting = 1; }
+ int isDeleting() { return deleting; }
+ int isInited() { return inited; }
+
+ int canClose() { return canclose; }
+ void setCanClose(int c) { canclose = c; }
+ GUID getGUID() { return myGUID; }
+
+ int getNoMenu() { return nomenu; }
+
+ void setPreventSaveVisibility(int p) { prevent_save_visibility = p; }
+ int wantRefocusApp() { return refocusapponclose; }
+ void setWantRefocusApp(int rf) { refocusapponclose = rf; }
+
+ public:
+ // ifc_dependent stuff
+
+ static const GUID *depend_getClassGuid() {
+ // {C439D9F4-34F5-453c-B947-448ED20203FC}
+ static const GUID ret =
+ { 0xc439d9f4, 0x34f5, 0x453c, { 0xb9, 0x47, 0x44, 0x8e, 0xd2, 0x2, 0x3, 0xfc } };
+
+ return &ret;
+ }
+ enum
+ {
+ Event_NAMECHANGE = 0,
+ };
+
+
+private:
+ void containerCallback(int msg);
+ StringW containerName;
+ StringW containerId;
+ PtrList<Layout> layouts;
+ int currentLayout;
+ StringW last_layout;
+ int canclose;
+ int lastLayout;
+ int default_visible, loaded_default_visible;
+ int ismain;
+ int dynamic;
+ int default_x = -1;
+ int default_y = -1;
+ int default_w = -1;
+ int default_h = -1;
+ int scriptid;
+ int inited;
+ int deleting;
+ int transcient;
+ PtrList<ContentEntry> contents;
+ int switching_layout;
+ int nomenu;
+ int prevent_save_visibility;
+ int refocusapponclose;
+ GUID contentGuid;
+ bool hasContentGuid;
+
+private:
+ GUID myGUID;
+ void showDefaultLayout(int noshow = 0);
+
+public:
+ static scriptVar script_vcpu_getId(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_onSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar script_onBeforeSwitchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar oldl, scriptVar newl);
+ static scriptVar script_onHideLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar script_onShowLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar l);
+ static scriptVar script_getLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar obj);
+ static scriptVar script_switchToLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_getCurrentLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_show(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_hide(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_close(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_toggle(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getNumLayouts(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_enumLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar n);
+ static scriptVar script_isDynamic(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name);
+ static scriptVar script_getName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_setXmlParam(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar p, scriptVar v);
+ static scriptVar script_onAddContent(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar window, scriptVar id, scriptVar g);
+
+};
+
+enum {
+ CONT_CB_NONE,
+ CONT_CB_VISIBLE,
+ CONT_CB_HIDDEN
+};
+
+#endif
+#endif
diff --git a/Src/Wasabi/api/wndmgr/gc.cpp b/Src/Wasabi/api/wndmgr/gc.cpp
new file mode 100644
index 00000000..c312b9ea
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/gc.cpp
@@ -0,0 +1,24 @@
+#include <precomp.h>
+#include "gc.h"
+
+GarbageCollector *garbageCollector=NULL;
+
+GarbageCollector::GarbageCollector() {
+ last = 0;
+ WASABI_API_SYSCB->syscb_registerCallback(this);
+}
+
+GarbageCollector::~GarbageCollector() {
+ WASABI_API_SYSCB->syscb_deregisterCallback(this);
+}
+
+int GarbageCollector::gccb_onGarbageCollect() {
+ uint32_t tc = Wasabi::Std::getTickCount();
+ if (tc < last + 10000) return 0;
+
+ last = tc;
+#ifdef WIN32
+ //SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
+#endif
+ return 0;
+}
diff --git a/Src/Wasabi/api/wndmgr/gc.h b/Src/Wasabi/api/wndmgr/gc.h
new file mode 100644
index 00000000..a57d24b4
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/gc.h
@@ -0,0 +1,19 @@
+#ifndef __GARBAGECOLLECT_H
+#define __GARBAGECOLLECT_H
+
+#include <api/syscb/callbacks/gccb.h>
+
+class GarbageCollector : public GarbageCollectCallbackI {
+ public:
+ GarbageCollector();
+ virtual ~GarbageCollector();
+
+ virtual int gccb_onGarbageCollect();
+
+ private:
+ uint32_t last;
+};
+
+extern GarbageCollector *garbageCollector;
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/guistatuscb.cpp b/Src/Wasabi/api/wndmgr/guistatuscb.cpp
new file mode 100644
index 00000000..761a18a1
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/guistatuscb.cpp
@@ -0,0 +1,15 @@
+#include <precomp.h>
+#include "guistatuscb.h"
+
+#define CBCLASS GuiStatusCallbackI
+START_DISPATCH;
+ CB(STATUS_GETDEP, status_getDependencyPtr);
+ VCB(STATUS_ONSETTEXT, onSetStatusText);
+ VCB(STATUS_ADDCTXTCMDS, onAddAppCmds);
+ VCB(STATUS_REMCTXTCMDS, onRemoveAppCmds);
+ VCB(STATUS_PUSHCOMPLETED, pushCompleted);
+ VCB(STATUS_INCCOMPLETED, incCompleted);
+ VCB(STATUS_SETCOMPLETED, setCompleted);
+ VCB(STATUS_POPCOMPLETED, popCompleted);
+END_DISPATCH;
+#undef CBCLASS
diff --git a/Src/Wasabi/api/wndmgr/guistatuscb.h b/Src/Wasabi/api/wndmgr/guistatuscb.h
new file mode 100644
index 00000000..f35a4d9f
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/guistatuscb.h
@@ -0,0 +1,83 @@
+#ifndef _GUISTATUSCB_H
+#define _GUISTATUSCB_H
+
+#include <bfc/dispatch.h>
+
+class AppCmds;
+class ifc_dependent;
+
+class GuiStatusCallback : public Dispatchable {
+ public:
+ void onSetStatusText(const wchar_t *text, int overlay);
+ void onAddAppCmds(AppCmds *commands);
+ void onRemoveAppCmds(AppCmds *commands);
+ void pushCompleted(int max=100);
+ void incCompleted(int add=1);
+ void setCompleted(int pos);
+ void popCompleted();
+
+ api_dependent *status_getDependencyPtr();
+ enum {
+ STATUS_ONSETTEXT = 101,
+ STATUS_GETDEP = 200,
+ STATUS_ADDCTXTCMDS = 300,
+ STATUS_REMCTXTCMDS = 400,
+ STATUS_PUSHCOMPLETED = 500,
+ STATUS_INCCOMPLETED = 600,
+ STATUS_SETCOMPLETED = 700,
+ STATUS_POPCOMPLETED = 800,
+ };
+};
+
+inline void GuiStatusCallback ::onSetStatusText(const wchar_t *text, int overlay) {
+ _voidcall(STATUS_ONSETTEXT, text, overlay);
+}
+
+inline api_dependent *GuiStatusCallback ::status_getDependencyPtr() {
+ return _call(STATUS_GETDEP, (api_dependent *)NULL);
+}
+
+inline void GuiStatusCallback ::onAddAppCmds(AppCmds *commands) {
+ _voidcall(STATUS_ADDCTXTCMDS, commands);
+}
+
+inline void GuiStatusCallback ::onRemoveAppCmds(AppCmds *commands) {
+ _voidcall(STATUS_REMCTXTCMDS, commands);
+}
+
+inline
+void GuiStatusCallback::pushCompleted(int max) {
+ _voidcall(STATUS_PUSHCOMPLETED, max);
+}
+
+inline
+void GuiStatusCallback::incCompleted(int add) {
+ _voidcall(STATUS_INCCOMPLETED, add);
+}
+
+inline
+void GuiStatusCallback::setCompleted(int pos) {
+ _voidcall(STATUS_SETCOMPLETED, pos);
+}
+
+inline
+void GuiStatusCallback::popCompleted() {
+ _voidcall(STATUS_POPCOMPLETED);
+}
+
+class GuiStatusCallbackI : public GuiStatusCallback {
+ public:
+ virtual void onSetStatusText(const wchar_t *text, int overlay)=0;
+ virtual api_dependent *status_getDependencyPtr()=0;
+ virtual void onAddAppCmds(AppCmds *commands)=0;
+ virtual void onRemoveAppCmds(AppCmds *commands)=0;
+ virtual void pushCompleted(int max=100)=0;
+ virtual void incCompleted(int add=1)=0;
+ virtual void setCompleted(int pos)=0;
+ virtual void popCompleted()=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/layout.cpp b/Src/Wasabi/api/wndmgr/layout.cpp
new file mode 100644
index 00000000..006a953d
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/layout.cpp
@@ -0,0 +1,2586 @@
+#include <precomp.h>
+#include <api/skin/widgets/mb/scriptbrowser.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/popup.h>
+#include <api/wndmgr/msgbox.h>
+#include <api/skin/widgets/group.h>
+#include "layout.h"
+#include <api/skin/skinparse.h>
+#include <api/skin/widgets/button.h>
+#include <api/core/buttons.h>
+#include <api/wnd/wndtrack.h>
+//#include <api/wac/main.h> //CUT!
+#include <api/skin/widgets/compbuck2.h>
+#include <api/wac/compon.h>
+#include <api/skin/skin.h>
+#include <api/wnd/notifmsg.h>
+#include <api/config/items/intarray.h>
+#include <api/config/items/cfgitem.h>
+#include <api/config/options.h>
+#include <api/script/script.h>
+#include <api/script/scriptmgr.h>
+#include <bfc/parse/pathparse.h>
+#include <api/skin/groupmgr.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/skin/skinparse.h>
+#include <api/service/svcs/svc_action.h>
+#include <api/config/items/attrbool.h>
+#include <api/config/items/attrint.h>
+#include <api/wndmgr/alphamgr.h>
+#include <bfc/wasabi_std_wnd.h>
+#include <api/wnd/PaintCanvas.h>
+#ifdef _WIN32
+#include <windowsx.h> // for SetWindowRedraw
+#endif
+
+#ifdef WASABINOMAINAPI
+#include <api/wndmgr/gc.h>
+#include <api/syscb/callbacks/gccb.h>
+#endif
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x20A
+#endif
+
+#define TIMER_SETTINGCHANGED 0x8791
+#define TIMER_AUTOOPACIFY 0x8792
+#define TIMER_AUTOOPACIFY2 0x8793
+#define TIMER_OFFSCREENCHECK 0x8794
+#define TIMER_TRANSPARENCY_AUTOON 0x8795
+#define TIMER_SAVE_POSITION 0x8796
+#define TIMER_SAVE_ALL_POSITIONS 0x8797
+
+#ifdef WASABI_COMPILE_CONFIG
+extern _bool cfg_uioptions_linkallalpha;
+extern _bool cfg_uioptions_linkallratio;
+extern _int cfg_uioptions_autoopacitylinked;
+extern _int cfg_uioptions_autoopacitytime;
+extern _int cfg_uioptions_extendautoopacity;
+extern _int cfg_uioptions_autoopacityfadein;
+extern _int cfg_uioptions_autoopacityfadeout;
+extern _int cfg_uioptions_linkedalpha;
+extern _bool cfg_options_appbarondrag;
+#endif
+
+AlphaMgr *alphaMgr = NULL;
+XMLParamPair Layout::params[] =
+ {
+ {LAYOUT_SETALPHA, L"ALPHA"},
+ {LAYOUT_SETALPHABACKGROUND, L"ALPHABACKGROUND"},
+ {LAYOUT_SETDESKTOPALPHA, L"DESKTOPALPHA"},
+ {LAYOUT_FORCEALPHA, L"FORCEALPHA"},
+ {LAYOUT_SETINDESKTOP, L"INDESKTOP"},
+ {LAYOUT_SETLINKHEIGHT, L"LINKHEIGHT"},
+ {LAYOUT_SETLINKWIDTH, L"LINKWIDTH"},
+ {LAYOUT_SETLOCKTO, L"LOCKTO"},
+ {LAYOUT_SETNOACTIVATION, L"NOACTIVATION"},
+ {LAYOUT_NODOCK, L"NODOCK"},
+ {LAYOUT_NOOFFSCREENCHECK, L"NOOFFSCREENCHECK"},
+ {LAYOUT_NOPARENT, L"NOPARENT"},
+ {LAYOUT_SETONTOP, L"ONTOP"},
+ {LAYOUT_SETOSFRAME, L"OSFRAME"},
+ {LAYOUT_SETOWNER, L"OWNER"},
+ {LAYOUT_SNAPADJUSTBOTTOM, L"SNAPADJUSTBOTTOM"},
+ {LAYOUT_SNAPADJUSTLEFT, L"SNAPADJUSTLEFT"},
+ {LAYOUT_SNAPADJUSTRIGHT, L"SNAPADJUSTRIGHT"},
+ {LAYOUT_SNAPADJUSTTOP, L"SNAPADJUSTTOP"},
+ {LAYOUT_UNLINKED, L"UNLINKED"},
+ {LAYOUT_RESIZABLE, L"RESIZABLE"},
+ {LAYOUT_SCALABLE, L"SCALABLE"},
+ };
+
+Layout::Layout()
+{
+ getScriptObject()->vcpu_setInterface(layoutGuid, (void *)static_cast<Layout *>(this));
+ getScriptObject()->vcpu_setInterface(guiResizableGuid, (void *)static_cast<GuiResizable *>(this));
+ getScriptObject()->vcpu_setClassName(L"Layout");
+ getScriptObject()->vcpu_setController(layoutController);
+#ifdef _WIN32
+ forwardMsgWnd = INVALIDOSWINDOWHANDLE;
+#endif
+ transparency_reenabled_at = 0;
+ transparency_autooff = 0;
+ captured = 0; resizing = 0;
+ m_forceunlink = 0;
+ inresize = 0;
+ autoopacify = 0;
+ x = 0; y = 0;
+#ifdef USEAPPBAR
+ appbar_want_autohide = 1;
+ appbar_want_alwaysontop = 1;
+ m_allowsavedock = 0;
+#endif
+ size_w = 0; size_h = 0;
+ reg = NULL;
+ //subregionlayers = new PtrList<Layer>;
+ setStartHidden(TRUE);
+ moving = 0;
+ setVirtual(0);
+ indesktop = 0;
+ p_container = NULL;
+ alpha = 255;
+ linkedheight = NULL;
+ linkedwidth = NULL;
+ inlinkwidth = 0;
+ inlinkheight = 0;
+ wantactiv = 1;
+ wantdesktopalpha = 0;
+ alllayouts.addItem(this);
+ galphadisabled = 0;
+ lockedto = NULL;
+ osframe = 0;
+ scalelocked = 0;
+ initontop = 0;
+ wantredrawonresize = 1;
+ getGuiObject()->guiobject_setMover(1);
+ snap_adjust_left = snap_adjust_right = snap_adjust_top = snap_adjust_bottom = 0;
+ disable_auto_alpha = 0;
+ unlinked = 0;
+ scaling = 0;
+ transparencyoverride = -1;
+ noparent = 0;
+ forcealpha = 0;
+ nodock = 0;
+ resizable = 1;
+ scalable = 1;
+ nooffscreencheck = 0;
+ m_w = m_h = m_endmovesize = 0;
+
+ xuihandle = newXuiHandle();
+ CreateXMLParameters(xuihandle);
+
+ if (!alphaMgr)
+ {
+ alphaMgr = new AlphaMgr();
+ #ifdef WASABI_COMPILE_CONFIG
+ alphaMgr->setAllLinked(cfg_uioptions_linkallalpha.getValueAsInt());
+ alphaMgr->setAutoOpacify(cfg_uioptions_autoopacitylinked.getValueAsInt());
+ alphaMgr->setGlobalAlpha(cfg_uioptions_linkedalpha.getValueAsInt());
+ alphaMgr->setHoldTime(cfg_uioptions_autoopacitytime.getValueAsInt());
+ alphaMgr->setFadeInTime(cfg_uioptions_autoopacityfadein.getValueAsInt());
+ alphaMgr->setFadeOutTime(cfg_uioptions_autoopacityfadeout.getValueAsInt());
+ alphaMgr->setExtendAutoOpacity(cfg_uioptions_extendautoopacity.getValueAsInt());
+#endif
+ }
+ alphaMgr->addLayout(this);
+}
+
+void Layout::CreateXMLParameters(int master_handle)
+{
+ //LAYOUT_SCRIPTPARENT::CreateXMLParameters(master_handle);
+ int numParams = sizeof(params) / sizeof(params[0]);
+ hintNumberOfParams(xuihandle, numParams);
+ for (int i = 0;i < numParams;i++)
+ addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
+}
+
+Layout::~Layout()
+{
+ if (transparency_reenabled_at) killTimer(TIMER_TRANSPARENCY_AUTOON);
+ alphaMgr->removeLayout(this);
+ killTimer(TIMER_OFFSCREENCHECK);
+ if (lockedto) lockedto->removeLockedLayout(this);
+ WASABI_API_WNDMGR->wndTrackRemove(this);
+ if (reg) delete reg;
+ alllayouts.removeItem(this);
+}
+
+int Layout::setXuiParam(int _xuihandle, int attrid, const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (xuihandle != _xuihandle) return LAYOUT_PARENT::setXuiParam(_xuihandle, attrid, paramname, strvalue);
+ switch (attrid)
+ {
+ case LAYOUT_SETDESKTOPALPHA:
+ setWantDesktopAlpha(WTOI(strvalue));
+ break;
+ case LAYOUT_SETINDESKTOP:
+ setInDesktop(WTOI(strvalue));
+ break;
+ case LAYOUT_SETALPHA:
+ setAlpha(WTOI(strvalue));
+ break;
+ case LAYOUT_SETLINKWIDTH:
+ setLinkWidth(strvalue);
+ if (*strvalue && isPostOnInit() && isVisible()) onResize();
+ break;
+ case LAYOUT_SETLINKHEIGHT:
+ setLinkHeight(strvalue);
+ if (*strvalue && isPostOnInit() && isVisible()) onResize();
+ break;
+ case LAYOUT_SETOWNER:
+ owner = strvalue;
+ break;
+ case LAYOUT_NOPARENT:
+ setNoParent(WTOI(strvalue));
+ break;
+ case LAYOUT_FORCEALPHA:
+ forcealpha = WTOI(strvalue);
+ break;
+ case LAYOUT_SETLOCKTO:
+ lockto = strvalue;
+ break;
+ case LAYOUT_SETOSFRAME:
+ osframe = WTOI(strvalue);
+ break;
+ case LAYOUT_SETALPHABACKGROUND:
+ setAlphaBackground(strvalue);
+ setWantDesktopAlpha(1);
+ setDrawBackground(1);
+ break;
+ case LAYOUT_SETNOACTIVATION:
+ wantactiv = WTOI(strvalue) ? 0 : 1;
+ break;
+ case LAYOUT_SETONTOP:
+ initontop = WTOI(strvalue);
+ if (isPostOnInit()) updateOnTop();
+ break;
+ case LAYOUT_SNAPADJUSTLEFT:
+ snap_adjust_left = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+#ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_SNAPADJUSTTOP:
+ snap_adjust_top = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_SNAPADJUSTRIGHT:
+ snap_adjust_right = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_SNAPADJUSTBOTTOM:
+ snap_adjust_bottom = WTOI(strvalue);
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ break;
+ case LAYOUT_UNLINKED:
+ unlinked = WTOI(strvalue);
+ if (!unlinked && isPostOnInit() && isVisible()) onResize();
+ break;
+ case LAYOUT_NODOCK:
+ setNoDock(WTOI(strvalue));
+ break;
+ case LAYOUT_NOOFFSCREENCHECK:
+ setNoOffscreenCheck(WTOI(strvalue));
+ break;
+ case LAYOUT_RESIZABLE:
+ resizable = WTOI(strvalue);
+ break;
+ case LAYOUT_SCALABLE:
+ scalable = WTOI(strvalue);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void Layout::setLinkHeight(const wchar_t *layoutid)
+{
+ linkedheight = layoutid;
+}
+
+void Layout::setLinkWidth(const wchar_t *layoutid)
+{
+ linkedwidth = layoutid;
+}
+
+int Layout::onPostedMove()
+{
+ updateLockedLayouts();
+ int r = LAYOUT_PARENT::onPostedMove();
+ Container *c = getParentContainer();
+ if (isVisible() && c && c->isMainContainer())
+ {
+#ifdef WASABI_ON_MAIN_MOVE
+ WASABI_ON_MAIN_MOVE(gethWnd());
+#endif
+
+ }
+ return r;
+}
+
+void Layout::cancelCapture()
+{
+ if (getCapture())
+ endCapture();
+ captured = 0;
+}
+
+int Layout::isOffscreen(ifc_window *w)
+{
+ if (!w->isVisible()) return 0;
+ if (nooffscreencheck) return 0;
+#ifdef USEAPPBAR
+ if (appbar_isDocked()) return 0;
+#endif
+ if (lockedto) return 0;
+ RECT wr;
+ w->getWindowRect(&wr);
+ windowTracker->snapAdjustWindowRect(w, &wr);
+ RECT r;
+
+ int isontop = 0;
+ if (w->getGuiObject())
+ {
+ isontop = WTOI(w->getGuiObject()->guiobject_getXmlParam(L"ontop"));
+#ifndef EXPERIMENTAL_INDEPENDENT_AOT
+ if (WTOI(w->getGuiObject()->guiobject_getXmlParam(L"noparent")) == 0)
+ isontop = 0;
+#endif
+
+ }
+ if (!isontop)
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ extern _bool cfg_options_alwaysontop;
+ isontop |= cfg_options_alwaysontop.getValueAsInt();
+#endif
+ }
+ Wasabi::Std::getViewport(&r, NULL, &wr, NULL, isontop);
+ if (wr.right < r.left + 10 ||
+ wr.bottom < r.top + 10 ||
+ wr.left > r.right - 10 ||
+ wr.top > r.bottom - 10)
+ {
+ return 1;
+ } //////TO CONTINUE
+ return 0;
+}
+
+void Layout::offscreenCheck()
+{
+ int disabled = 0;
+#ifdef WASABI_CHECK_OFFSCREENCHECK_DISABLE
+ WASABI_CHECK_OFFSCREENCHECK_DISABLE(disabled);
+#endif
+ if (disabled) return ;
+ if (!isVisible()) return ;
+ if (moving || scaling || resizing) return ;
+ if (isOffscreen(this))
+ {
+ windowTracker->startCooperativeMove(this);
+ for (int i = 0;i < windowTracker->getNumDocked();i++)
+ {
+ ifc_window *w = windowTracker->enumDocked(i);
+ Layout *l = static_cast<Layout*>(w->getInterface(layoutGuid));
+ if (l != NULL)
+ {
+ if (l->getParentContainer() && l->getParentContainer()->isMainContainer())
+ {
+ if (!isOffscreen(l))
+ {
+ windowTracker->endCooperativeMove();
+ return ;
+ }
+ }
+ }
+ }
+ windowTracker->endCooperativeMove();
+ RECT wr;
+ getWindowRect(&wr);
+ RECT nr = windowTracker->findOpenRect(wr);
+ move(nr.left, nr.top);
+ }
+}
+
+/**
+ * This one only prevents UI resizings from layers!
+ */
+int Layout::getResizable ()
+{
+ return this->resizable;
+}
+
+/**
+ * This one only prevents UI scalings from layers!
+ */
+int Layout::getScalable ()
+{
+ return this->scalable;
+}
+
+void Layout::setTransparencyOverride(int v)
+{
+ transparencyoverride = v;
+ if (v != -1) setTransparency(v); else updateTransparency();
+}
+
+#ifndef PI
+#define PI 3.1415926536
+#endif
+
+void Layout::timerCallback(int id)
+{
+ if (id == TIMER_TRANSPARENCY_AUTOON)
+ {
+ if (!isTransparencySafe(1))
+ {
+ transparency_reenabled_at = 0;
+ return ;
+ }
+ int n = Wasabi::Std::getTickCount() - transparency_reenabled_at;
+ if (n < 1000) return ;
+ else
+ {
+ killTimer(TIMER_TRANSPARENCY_AUTOON);
+ transparency_autooff = 0;
+ updateTransparency();
+ transparency_reenabled_at = 0;
+ }
+ return ;
+ }
+ else if (id == TIMER_OFFSCREENCHECK)
+ {
+ offscreenCheck();
+ return ;
+ }
+ else if (id == TIMER_SETTINGCHANGED)
+ {
+ killTimer(TIMER_SETTINGCHANGED);
+#ifdef _WIN32
+ HWND parent;
+ webserver = INVALIDOSWINDOWHANDLE;
+ listview = INVALIDOSWINDOWHANDLE;
+ getExplorerWindows(&parent, &listview, &webserver);
+ if (!webserver) // active desktop now off, reposition this window zorder otherwise it will be behind the icons
+#ifdef WIN32
+ SetWindowPos(gethWnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE);
+#else
+ bringToFront();
+#endif
+#endif
+ }
+ else if (id == TIMER_SAVE_ALL_POSITIONS)
+ {
+ killTimer(TIMER_SAVE_ALL_POSITIONS);
+ saveAllPositions();
+ // TODO: benski> not 100% sure we want to call into the script on the timer (maybe do it in endMove)
+ //script_vcpu_onEndMove(SCRIPT_CALL, getScriptObject());
+ return;
+ }
+ else if (id == TIMER_SAVE_POSITION)
+ {
+ killTimer(TIMER_SAVE_POSITION);
+ savePosition();
+ // TODO: benski> not 100% sure we want to call into the script on the timer (maybe do it in endMove)
+ //script_vcpu_onEndMove(SCRIPT_CALL, getScriptObject());
+ return;
+ }
+ else LAYOUT_PARENT::timerCallback(id);
+}
+
+void Layout::onMouseEnterLayout()
+{
+ script_vcpu_onMouseEnterLayout(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::onMouseLeaveLayout()
+{
+ script_vcpu_onMouseLeaveLayout(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::beginMove()
+{
+ moving = 1;
+}
+
+void Layout::beginScale()
+{
+ scaling = 1;
+}
+
+void Layout::beginResize()
+{
+ resizing = 1;
+}
+
+void Layout::endMove()
+{
+ if (m_endmovesize)
+ {
+ m_endmovesize = 0;
+ RECT r;
+ guiresizable_getRootWnd()->getWindowRect(&r);
+ r.right = r.left + m_w;
+ r.bottom = r.top + m_h;
+ guiresizable_getRootWnd()->resizeToRect(&r);
+ }
+ moving = 0;
+ // TODO: benski> do this on a resetable timer so it doesn't go so slowly
+ if (WASABI_API_WNDMGR->wndTrackWasCooperative())
+ setTimer(TIMER_SAVE_ALL_POSITIONS, 1000);
+// saveAllPositions();
+ else
+ setTimer(TIMER_SAVE_POSITION, 1000);
+ //savePosition();
+ // TODO: benski> not 100% sure we want to call into the script on the timer (maybe do it in endMove)
+ script_vcpu_onEndMove(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::endScale()
+{
+ scaling = 0;
+ savePosition();
+ fixPosition();
+}
+
+void Layout::endResize()
+{
+ resizing = 0;
+ RECT r;
+ getClientRect(&r);
+ RECT wr;
+ getWindowRect(&wr);
+ script_vcpu_onUserResize(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(wr.left), MAKE_SCRIPT_INT(wr.top), MAKE_SCRIPT_INT(r.right - r.left), MAKE_SCRIPT_INT(r.bottom - r.top));
+ savePosition();
+}
+
+void Layout::onMove()
+{
+ script_vcpu_onMove(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::setAutoOpacify(int a)
+{
+ if (autoopacify == a) return ;
+ autoopacify = a != -1 ? a : autoopacify;
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW tmp;
+ tmp.printf(L"Skin:%s/Container:%s/Layout:%s/autoopacify", WASABI_API_SKIN->getSkinName(), getParentContainer()->getDescriptor(), getGuiObject()->guiobject_getId());
+ IntArray::write(tmp, autoopacify);
+ }
+ updateTransparency();
+}
+
+void Layout::controlMenu()
+{
+ PopupMenu pop;
+ int x = 1;
+#ifdef WASABI_CHECK_CAN_EXIT
+ WASABI_CHECK_CAN_EXIT(x)
+#endif
+ if (getParentContainer() && getParentContainer()->isMainContainer())
+ {
+ if (x)
+ {
+ pop.addCommand(StringPrintfW(L"Exit %s", WASABI_API_APP->main_getAppName()), ACTION_CLOSE);
+ pop.addSeparator();
+ }
+ }
+ else
+ {
+ if (!getParentContainer() || getParentContainer()->canClose())
+ {
+ pop.addCommand(L"Close window", ACTION_CLOSE_WINDOW);
+ pop.addSeparator();
+ }
+ }
+ PopupMenu *scalemenu = new PopupMenu();
+ scalemenu->addCommand(L"50%", ACTION_SCALE_50);
+ scalemenu->addCommand(L"75%", ACTION_SCALE_75, FALSE, FALSE);
+ scalemenu->addCommand(L"100%", ACTION_SCALE_100);
+ scalemenu->addCommand(L"125%", ACTION_SCALE_125);
+ scalemenu->addCommand(L"150%", ACTION_SCALE_150);
+ scalemenu->addCommand(L"200%", ACTION_SCALE_200);
+ scalemenu->addCommand(L"400%", ACTION_SCALE_400, FALSE, FALSE);
+ pop.addSubMenu(scalemenu, L"Scale");
+
+ PopupMenu *opaqmenu = new PopupMenu();
+ opaqmenu->addCommand(L"Auto-fade", ACTION_AUTOOPACIFY, getAutoOpacify(), FALSE);
+ opaqmenu->addSeparator();
+ opaqmenu->addCommand(L"100%", ACTION_ALPHA_100, FALSE, FALSE);
+ opaqmenu->addCommand(L"90%", ACTION_ALPHA_90, FALSE, FALSE);
+ opaqmenu->addCommand(L"80%", ACTION_ALPHA_80, FALSE, FALSE);
+ opaqmenu->addCommand(L"70%", ACTION_ALPHA_70, FALSE, FALSE);
+ opaqmenu->addCommand(L"60%", ACTION_ALPHA_60, FALSE, FALSE);
+ opaqmenu->addCommand(L"50%", ACTION_ALPHA_50, FALSE, FALSE);
+ opaqmenu->addCommand(L"40%", ACTION_ALPHA_40, FALSE, FALSE);
+ opaqmenu->addCommand(L"30%", ACTION_ALPHA_30, FALSE, FALSE);
+ opaqmenu->addCommand(L"20%", ACTION_ALPHA_20, FALSE, FALSE);
+ opaqmenu->addCommand(L"10%", ACTION_ALPHA_10, FALSE, FALSE);
+
+ pop.addSubMenu(opaqmenu, L"Opacity", !isTransparencySafe());
+
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ pop.addCommand(L"Always on top", ACTION_AOT, getAlwaysOnTop());
+#endif
+
+ int r = pop.popAtMouse();
+ if (r < 0) return ;
+ onActionNotify(r, 0);
+}
+
+void Layout::fixPosition()
+{
+ RECT r;
+ getWindowRect(&r);
+ RECT orig_r = r;
+
+ RECT vr;
+ RegionI reg;
+
+ int i = 0;
+ while (Wasabi::Std::enumViewports(i, &vr))
+ {
+ reg.addRect(&vr);
+ i++;
+ }
+
+ RECT full;
+ reg.getBox(&full);
+
+
+ int dif = r.bottom - full.bottom;
+ if (dif > 0) r.top -= dif;
+ dif = r.right - full.right;
+ if (dif > 0) r.left -= dif;
+ dif = full.top - r.top;
+ if (dif > 0) r.top += dif;
+ dif = full.left - r.left;
+ if (dif > 0) r.left += dif;
+
+ if (orig_r.left != r.left || orig_r.top != r.top)
+ resize(r.left, r.top, NOCHANGE, NOCHANGE);
+}
+
+void Layout::saveAllPositions()
+{
+ // The positions are saved from the lastest to the first one
+ // The 'Player' windows and the 'Main' windows are using the same prefix
+ // In saving in decreasing order we are sure the lastest saved is the one for the Player
+
+ for (int i = 0;i < SkinParser::script_getNumContainers();i++)
+ {
+ Container *c = SkinParser::script_enumContainer(i);
+ for (int j = c->getNumLayouts() - 1;j >= 0 ;--j)
+ {
+ Layout *l = c->enumLayout(j);
+ l->savePosition();
+ }
+ }
+}
+
+int Layout::forceTransparencyFlag()
+{
+ return alphaMgr->needForcedTransparencyFlag(this);
+}
+
+void Layout::savePosition()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (!getParentContainer() || getParentContainer()->isTranscient())
+ return ;
+
+ if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle()))
+ return ;
+
+
+ StringW prefix = MakePrefix();
+ StringPrintfW tmp( L"%s/odim", prefix.v() );
+
+ SkinBitmap *baseTexture = getBaseTexture();
+
+ if ( baseTexture )
+ {
+ IntArray::write( tmp, baseTexture->getWidth(), baseTexture->getHeight() );
+ }
+ else
+ {
+ IntArray::write( tmp, -2, -2 );
+ }
+
+ RECT r, rs;
+ getClientRect(&r); // unscaled
+ //DebugStringW( L"\nLayout::savePosition() - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
+
+ if (r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0)
+ return ;
+
+ getWindowRect(&rs); // screen scaled (for x/y)
+ tmp.printf(L"%s/rect", prefix.v());
+ IntArray::write(tmp, rs.left, rs.top, r.right - r.left, r.bottom - r.top);
+ //DebugStringW( L"Layout::savePosition() rect - x = %d, y = %d, w = %d, h = %d \n", rs.left, rs.top, r.right - r.left, r.bottom - r.top );
+
+ getRestoredRect(&rs);
+ tmp.printf(L"%s/restoredrect", prefix.v());
+ IntArray::write(tmp, rs.left, rs.top, rs.right - rs.left, rs.bottom - rs.top);
+
+ //DebugStringW( L"Layout::savePosition() restoredrect - x = %d, y = %d, w = %d, h = %d \n", rs.left, rs.top, rs.right - rs.left, rs.bottom - rs.top );
+
+ tmp.printf(L"%s/maximized", prefix.v());
+ // DebugString("isMaximized = %d\n", isMaximized());
+ WASABI_API_CONFIG->setIntPrivate(tmp, isMaximized());
+
+ tmp.printf(L"%s/r", prefix.v());
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(getRenderRatio()));
+
+ tmp.printf(L"%s/sm", prefix.v());
+ TextInfoCanvas textInfoCanvas(this);
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(textInfoCanvas.getSystemFontScale()));
+
+ tmp.printf(L"%s/sl", prefix.v());
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(scalelocked));
+
+ tmp.printf(L"%s/autoopacify", prefix.v());
+ IntArray::write(tmp, autoopacify);
+
+#ifdef USEAPPBAR
+ saveAppBarPosition();
+#endif
+
+#endif
+}
+#ifdef USEAPPBAR
+void Layout::saveAppBarPosition()
+{
+ if (m_allowsavedock)
+ {
+ StringW prefix = MakePrefix();
+ StringW wtmp = StringPrintfW(L"%s/appbar", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_getSide());
+ wtmp.printf(L"%s/appbarontop", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_wantAlwaysOnTop());
+ wtmp.printf(L"%s/appbarhidden", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_isHiding());
+ wtmp.printf(L"%s/appbarisautohide", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_isAutoHiding());
+ wtmp.printf(L"%s/appbarwantautohide", prefix.v());
+ WASABI_API_CONFIG->setIntPrivate(wtmp, appbar_wantAutoHide());
+ }
+}
+#endif
+void Layout::lockScale(int locked)
+{
+ scalelocked = locked;
+ StringW tmp;
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/sl", prefix.v());
+ WASABI_API_CONFIG->setStringPrivate(tmp, StringPrintfW(scalelocked));
+}
+
+void Layout::resize(int x, int y, int w, int h, int wantcb)
+{
+ if (inresize) return ;
+ inresize = 1;
+ LAYOUT_PARENT::resize(x, y, w, h, wantcb);
+ if (!lockedto)
+ getGuiObject()->guiobject_setGuiPosition(&x, &y, &w, &h, NULL, NULL, NULL, NULL);
+ inresize = 0;
+}
+
+void Layout::move(int x, int y)
+{
+ //DebugStringW( L"Layout::move( x = %d, y = %d )\n", x, y );
+
+ LAYOUT_PARENT::move(x, y);
+ getGuiObject()->guiobject_setGuiPosition(&x, &y, NULL, NULL, NULL, NULL, NULL, NULL);
+}
+
+#define DC_CHECKLASTRESIZE 0x109
+#ifdef USEAPPBAR
+#define DC_LOADSAVEDDOCK 0x10A
+#endif
+#define DC_INVALIDATE 0x10B
+
+int Layout::onResize()
+{
+ LAYOUT_PARENT::onResize();
+ if (!abortSaving()) savePosition();
+ RECT r;
+ getClientRect(&r);
+ if (!linkedwidth.isempty())
+ {
+ if (!inlinkwidth)
+ {
+ inlinkwidth = 1;
+ RECT cr;
+ Layout *l = getParentContainer() ? getParentContainer()->getLayout(linkedwidth) : NULL;
+ if (l)
+ {
+ int _unlinked = l->isUnlinked();
+ _unlinked |= isUnlinked();
+ if (!_unlinked)
+ {
+ l->getClientRect(&cr);
+ POINT pt;
+ l->getPosition(&pt);
+ l->resize(pt.x, pt.y, r.right - r.left, cr.bottom - cr.top);
+ }
+ }
+ inlinkwidth = 0;
+ }
+ }
+ if (!linkedheight.isempty())
+ {
+ if (!inlinkheight)
+ {
+ inlinkheight = 1;
+ RECT cr;
+ Layout *l = getParentContainer() ? getParentContainer()->getLayout(linkedheight) : NULL;
+ if (l)
+ {
+ int _unlinked = l->isUnlinked();
+ _unlinked |= isUnlinked();
+ if (!_unlinked)
+ {
+ l->getClientRect(&cr);
+ POINT pt;
+ l->getPosition(&pt);
+ l->resize(pt.x, pt.y, cr.right - cr.left, r.bottom - r.top);
+ }
+ }
+ }
+ inlinkheight = 0;
+ }
+ updateLockedLayouts();
+
+ postDeferredCallback(DC_CHECKLASTRESIZE);
+
+ return 1;
+}
+
+int Layout::onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ /* if (p1 == DC_CHECKLASTRESIZE) {
+ RECT vr;
+ RECT r;
+ RECT wr;
+ Std::getViewport(&vr, NULL, NULL, gethWnd(), 1);
+ if (renderRatioActive())
+ divRatio(&vr);
+ getClientRect(&r);
+ r.bottom -= snap_adjust_bottom;
+ r.top += snap_adjust_top;
+ r.right -= snap_adjust_right;
+ r.left += snap_adjust_left;
+ getWindowRect(&wr);
+ int n = 0;
+ if (r.right-r.left > vr.right-vr.left) { r.right = r.left + vr.right-vr.left; n++; }
+ if (r.bottom-r.top > vr.bottom-vr.top) { r.bottom = r.top + vr.bottom-vr.top; n++; }
+ if (n) resize(wr.left, wr.top, r.right-r.left+snap_adjust_left+snap_adjust_right, r.bottom-r.top+snap_adjust_top+snap_adjust_bottom);
+ } else */
+#ifdef USEAPPBAR
+ if (p1 == DC_LOADSAVEDDOCK)
+ {}
+#endif
+
+ if (p1 == DC_INVALIDATE)
+ {
+ invalidate();
+ }
+ return LAYOUT_PARENT::onDeferredCallback(p1, p2);
+ // return 1;
+}
+
+void Layout::updateLockedLayouts()
+{
+ for (int i = 0;i < getNumLockedLayouts();i++)
+ {
+ Layout *l = enumLockedLayout(i);
+
+ if (l->getRenderRatio() != getRenderRatio())
+ l->setRenderRatio(getRenderRatio());
+
+ int x, y, w, h;
+ l->getGuiObject()->guiobject_getGuiPosition(&x, &y, &w, &h, NULL, NULL, NULL, NULL);
+ RECT r;
+ l->getClientRect(&r);
+ if (w == AUTOWH) w = r.right - r.left;
+ if (h == AUTOWH) h = r.bottom - r.top;
+ POINT pt;
+ l->getPosition(&pt);
+ if (x == AUTOWH) x = pt.x; else clientToScreen(&x, NULL);
+ if (y == AUTOWH) y = pt.y; else clientToScreen(NULL, &y);
+ RECT cr;
+ l->getWindowRect(&cr);
+ if (cr.left != x || cr.top != y || cr.right != cr.left + w || cr.bottom != cr.top + h)
+ l->Group::resize(x, y, w, h);
+ }
+}
+
+int Layout::isClickThrough()
+{
+ return 0;
+}
+#ifdef _WIN32
+LRESULT Layout::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+
+#ifdef ON_CUSTOM_ALTF4
+ if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)
+ if (wParam == VK_F4)
+ if (GetAsyncKeyState(VK_MENU)&0x8000) ON_CUSTOM_ALTF4;
+#endif
+
+ if (uMsg == WM_KILLFOCUS || uMsg == WM_SETFOCUS)
+ {
+ alphaMgr->hoverCheck(this);
+ }
+
+ if (forwardMsgWnd != INVALIDOSWINDOWHANDLE)
+ {
+ switch (uMsg)
+ {
+ case WM_MOUSEWHEEL:
+ return (SendMessageW(forwardMsgWnd, uMsg, wParam, 0x31337)); // 0x31337 avoid main window callback
+ //case WM_DESTROY: //FG> commented out, makes wa quit when layout is destroyed
+ case WM_CLOSE:
+ return (SendMessageW(forwardMsgWnd, uMsg, wParam, lParam));
+
+ case WM_SETTINGCHANGE:
+ {
+ if (!indesktop) break;
+ setTimer(TIMER_SETTINGCHANGED, 1000);
+ }
+ break; //BU think this should be here eh
+
+#ifdef WIN32
+ case 0x0319:
+ { // hehe --BU
+ if (lParam & 0x20000)
+ FireAction(L"NEXT", NULL, 0, 0, NULL, 0, NULL, FALSE);
+ else
+ FireAction(L"PREV", NULL, 0, 0, NULL, 0, NULL, FALSE);
+ }
+ break;
+#endif
+ /*
+ WIP: This won't work anymore. What should we do about it? -- mig
+
+ childNotify(NULL, CHILD_NOTIFY_LEFTPUSH, ACTION_NEXT);
+ break;
+ */
+ }
+ }
+ return LAYOUT_PARENT::wndProc(hWnd, uMsg, wParam, lParam);
+}
+#else
+OSStatus Layout::eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
+{
+ return LAYOUT_PARENT::eventHandler(inHandlerCallRef, inEvent, inUserData);
+}
+#warning port me
+#endif
+
+/*int Layout::onRightButtonDown(int x, int y) {
+ LAYOUT_PARENT::onRightButtonDown(x, y);
+// Main::appContextMenu(this, TRUE, isTransparencySafe());
+ return 1;
+}*/
+
+ifc_window *Layout::getCustomOwner()
+{
+ if (noparent) return NULL;
+ if (owner.isempty()) return NULL;
+ return SkinParser::getLayout(owner);
+}
+
+void Layout::addLockedLayout(Layout *l)
+{
+ locked.addItem(l);
+ updateLockedLayouts();
+}
+
+void Layout::removeLockedLayout(Layout *l)
+{
+ locked.removeItem(l);
+}
+
+int Layout::getNumLockedLayouts()
+{
+ return locked.getNumItems();
+}
+
+Layout *Layout::enumLockedLayout(int n)
+{
+ return locked.enumItem(n);
+}
+
+int Layout::isLocked()
+{
+ return (!lockto.isempty()
+ #ifdef USEAPPBAR
+ || cfg_options_appbarondrag == 0 && appbar_isDocked()
+#endif
+ );
+}
+
+void Layout::lockTo(Layout *t)
+{
+ if (t == NULL) return ;
+ if (lockedto) lockedto->removeLockedLayout(this);
+ lockedto = t;
+ t->addLockedLayout(this);
+}
+
+Layout *Layout::getLockedTo()
+{
+ return lockedto;
+}
+
+int Layout::reinit(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild)
+{
+ StringW osname = getOSWndName();
+ ASSERTPR(!indesktop, "in desktop reinit failed");
+ if (noparent)
+ parent = NULL;
+ int r = LAYOUT_PARENT::reinit(inst, parent, nochild);
+ setOSWndName(osname);
+ return r;
+}
+
+int Layout::init(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild)
+{
+ if (noparent) parent = NULL;
+ if (!indesktop) return LAYOUT_PARENT::init(inst, parent, nochild);
+
+#ifdef _WIN32
+ webserver = INVALIDOSWINDOWHANDLE;
+ listview = INVALIDOSWINDOWHANDLE;
+
+ getExplorerWindows(&parent, &listview, &webserver);
+
+ if (!parent)
+ {
+ indesktop = 0;
+ return LAYOUT_PARENT::init(inst, parent, nochild);
+ }
+#endif
+ nochild = 0;
+
+#ifdef _WIN32
+ // if active desktop is off, that's all we can do, we'll be on top of the icons
+ // if active desktop is on, but listview is not, we'll be on top of active desktop
+ if (!webserver || !listview) return LAYOUT_PARENT::init(inst, parent, nochild);
+#endif
+
+#ifdef WIN32
+ // find who we're gonna sit on top of
+ HWND behind = listview;
+ if (GetWindow(listview, GW_HWNDPREV))
+ behind = GetWindow(listview, GW_HWNDPREV);
+#else
+ DebugString( "portme -- Layout::init\n" );
+#endif
+
+ int r = LAYOUT_PARENT::init(inst, parent, nochild);
+#ifdef WIN32
+ SetWindowPos(gethWnd(), behind, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE);
+#endif
+
+ return r;
+}
+
+#ifdef WIN32
+void Layout::getExplorerWindows(OSWINDOWHANDLE *parent, OSWINDOWHANDLE *listview, OSWINDOWHANDLE *webserver)
+{
+ *parent = NULL;
+ *listview = NULL;
+ *webserver = NULL;
+
+ char classname[256] = "";
+ HWND w;
+
+ // find explorer window. todo: litestep support ?
+ *parent = FindWindowA(NULL, "Program Manager");
+ if (!*parent) return ;
+
+ // find its first child for parenting
+ *parent = GetWindow(*parent, GW_CHILD);
+ if (!*parent) return ;
+
+ // find the children
+ w = GetWindow(*parent, GW_CHILD);
+
+ while (w)
+ {
+ GetClassNameA(w, classname, 255);
+ if (!*webserver && STRCASEEQL("Internet Explorer_Server", classname))
+ *webserver = w;
+ if (!*listview && STRCASEEQL("SysListView32", classname))
+ *listview = w;
+ w = GetWindow(w, GW_HWNDNEXT);
+ }
+}
+#endif
+
+int Layout::onInit()
+{
+ LAYOUT_PARENT::onInit();
+
+ Container *c = getParentContainer();
+ if (c != NULL)
+ {
+ const wchar_t *s = c->getName();
+ if (s != NULL)
+ {
+ setOSWndName(s);
+ }
+ }
+
+ loadSavedState();
+
+#ifdef WA3COMPATIBILITY
+ setIcon(WASABI_API_APP->main_getIcon(TRUE), TRUE);
+ setIcon(WASABI_API_APP->main_getIcon(FALSE), FALSE);
+#endif
+
+ WASABI_API_WNDMGR->wndTrackAdd(this);
+
+ if (wantDesktopAlpha() && isDesktopAlphaSafe())
+ desktopAlpha_autoTurnOn();
+
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+#ifdef _WIN32
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, getDesktopAlpha() ? 1 : 255);
+ setRegion(reg);
+#else
+#warning port me
+#endif
+ }
+
+ SystemObject::onCreateLayout(this);
+
+ if (!lockto.isempty()) lockTo(SkinParser::getLayout(lockto));
+
+ updateOnTop();
+
+ setNoOffscreenCheck( -1);
+
+ return 1;
+}
+
+void Layout::updateOnTop()
+{
+ #ifdef USEAPPBAR
+ if (!appbar_isDocked())
+#endif
+ {
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ setAlwaysOnTop(initontop);
+#else
+ if (noparent)
+ {
+ int disable = 0;
+#ifdef WASABI_GET_TEMPDISABLE_AOT
+ WASABI_GET_TEMPDISABLE_AOT(disable);
+#endif
+#ifdef _WIN32
+ if (initontop && !disable) SetWindowPos(getOsWindowHandle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
+ else SetWindowPos(getOsWindowHandle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
+#else
+#warning port me
+#endif
+ }
+#endif
+
+ }
+}
+
+void Layout::loadSavedState()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ StringW tmp;
+#endif
+ wchar_t t[64] = L"";
+
+ int ow = -1;
+ int oh = -1;
+ int ra = -1;
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/odim", prefix.v());
+ IntArray::read(tmp, &ow, &oh);
+
+ tmp.printf(L"%s/alpha", prefix.v());
+ IntArray::read(tmp, &ra);
+
+ tmp.printf(L"%s/autoopacify", prefix.v());
+ IntArray::read(tmp, &autoopacify);
+
+ }
+#endif
+
+ int from_scratch = 0;
+ if (Std::keyModifier(STDKEY_SHIFT) && Std::keyModifier(STDKEY_ALT) && Std::keyModifier(STDKEY_CONTROL)) from_scratch = 1;
+#ifdef WASABI_COMPILE_CONFIG
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/sl", prefix.v());
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 63, L"0");
+ lockScale(WTOI(t));
+ }
+#endif
+
+ *t = 0;
+#ifdef WASABI_COMPILE_CONFIG
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/sm", prefix.v());
+ }
+
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 63, L"1.");
+ //double sm = (float)WTOF(t);
+#else
+ //double sm = 1.0;
+#endif
+ /*if (ABS(sm - Canvas::getSystemFontScale()) > 0.001)
+ from_scratch = 1;*/
+
+ if (Group::getBaseTexture() && alphabackground.getBitmap() != NULL)
+ {
+ if (Group::getBaseTexture()->getWidth() != alphabackground.getWidth() || Group::getBaseTexture()->getHeight() != alphabackground.getHeight())
+ {
+ ASSERTPR(0, StringPrintf("layout %S should have same size for background and alphabackground", getGuiObject()->guiobject_getParentLayout()->getGuiObject()->guiobject_getId()));
+ }
+ }
+
+ if ((ow != -2 && oh != -2) && (ow == -1 || oh == -1 || (getBaseTexture() && (ow != getBaseTexture()->getWidth() || oh != getBaseTexture()->getHeight()))))
+ from_scratch = 1;
+
+ int w = 0, h = 0;
+ int findrect = 0;
+
+ if (from_scratch || (getParentContainer() && getParentContainer()->isTranscient()))
+ {
+ if (getParentContainer())
+ {
+ int _x = getParentContainer()->getDefaultPositionX();
+ int _y = getParentContainer()->getDefaultPositionY();
+ x = _x == -1 ? x : _x;
+ y = _y == -1 ? y : _y;
+ if (x == -1 && y == -1) findrect = 1;
+ }
+ else
+ {
+ int _x, _y;
+ getGuiObject()->guiobject_getGuiPosition(&_x, &_y, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (_x != AUTOWH && _x != NOCHANGE) x = _x;
+ if (_y != AUTOWH && _y != NOCHANGE) y = _y;
+ }
+ getGuiObject()->guiobject_getGuiPosition(NULL, NULL, &w, &h, NULL, NULL, NULL, NULL);
+ if (w == AUTOWH || h == AUTOWH)
+ {
+ w = getPreferences(SUGGESTED_W);
+ h = getPreferences(SUGGESTED_H);
+ int _minx = getPreferences(MINIMUM_W);
+ int _maxx = getPreferences(MAXIMUM_W);
+ int _miny = getPreferences(MINIMUM_H);
+ int _maxy = getPreferences(MAXIMUM_H);
+ if (_minx != AUTOWH && _maxx != AUTOWH && _minx > _maxx) _minx = _maxx;
+ if (_miny != AUTOWH && _maxy != AUTOWH && _miny > _maxy) _miny = _maxy;
+ if (w == AUTOWH && _minx != AUTOWH) w = _minx;
+ if (h == AUTOWH && _miny != AUTOWH) h = _miny;
+ TextInfoCanvas textInfoCanvas(this);
+ double fontScale = textInfoCanvas.getSystemFontScale();
+ if (w != AUTOWH && getGuiObject()->guiobject_getAutoSysMetricsW())
+ w = (int)((float)w * fontScale);
+ if (h != AUTOWH && getGuiObject()->guiobject_getAutoSysMetricsH())
+ h = (int)((float)h * fontScale);
+ }
+ }
+ else
+ {
+ if (getParentContainer())
+ {
+
+ if (getParentContainer()->isMainContainer()) //FG> could be a new component installed
+ SkinParser::noCenterSkin();
+
+#ifdef WASABI_COMPILE_CONFIG
+ StringW prefix = MakePrefix();
+
+ tmp.printf(L"%s/rect", prefix.v());
+ IntArray::read(tmp, &x, &y, &w, &h);
+
+ RECT rr;
+ tmp.printf(L"%s/restoredrect", prefix.v());
+ IntArray::read(tmp, (int*)&rr.left, (int*)&rr.top, (int*)&rr.right, (int*)&rr.bottom);
+ rr.right += rr.left;
+ rr.bottom += rr.top;
+
+ tmp.printf(L"%s/maximized", prefix.v());
+ if (WASABI_API_CONFIG->getIntPrivate(tmp, 0)) setRestoredRect(&rr);
+
+#endif
+
+ }
+ }
+
+ *t = 0;
+ double ratio = 1.0;
+
+ if (!from_scratch)
+ {
+ if (getParentContainer())
+ {
+#ifdef WASABI_COMPILE_CONFIG
+ StringW prefix = MakePrefix();
+ tmp.printf(L"%s/r", prefix.v());
+
+ WASABI_API_CONFIG->getStringPrivate(tmp, t, 63, L"1.");
+ ratio = WTOF(t);
+#else
+ ratio = 1.0f;
+#endif
+
+ }
+ }
+
+#ifdef ON_TWEAK_RENDER_RATIO
+ if (!scalelocked) ON_TWEAK_RENDER_RATIO(ratio);
+#endif
+
+ if (w == 0 || h == 0 || from_scratch)
+ {
+ int _w = getPreferences(SUGGESTED_W);
+ w = _w == AUTOWH ? w : _w;
+ int _h = getPreferences(SUGGESTED_H);
+ h = _h == AUTOWH ? h : _h;
+
+ TextInfoCanvas textInfoCanvas(this);
+ double fontScale = textInfoCanvas.getSystemFontScale();
+
+ if (getGuiObject()->guiobject_getAutoSysMetricsW())
+ w = (int)((float)w * fontScale);
+ if (getGuiObject()->guiobject_getAutoSysMetricsH())
+ h = (int)((float)h * fontScale);
+ if (w == 0 || h == 0)
+ {
+ w = getBaseTexture()->getWidth();
+ h = getBaseTexture()->getHeight();
+ }
+ RECT sr = {x, y, x + w, y + h};
+ if (findrect)
+ sr = windowTracker->findOpenRect(Wasabi::Std::makeRect(0, 0, (int)((float)w * getRenderRatio()), (int)((float)h * getRenderRatio())), this);
+ sr.right = sr.left + w;
+ sr.bottom = sr.top + h;
+ BaseWnd::resize(&sr);
+ }
+ else
+ {
+ RECT cr;
+ getClientRect(&cr);
+ RECT r = {x, y, x + w, y + h};
+ BaseWnd::resize(&r);
+ }
+
+ setAlpha(from_scratch || ra == -1 ? alpha : ((ra < 254) ? ra : 255));
+
+ Layout *main = SkinParser::getMainLayout();
+ if (main != this && main
+ #ifdef WASABI_COMPILE_CONFIG
+ && cfg_uioptions_linkallratio.getValueAsInt()
+#endif
+ && !noparent)
+ {
+ setRenderRatio(main->getRenderRatio());
+ }
+ else setRenderRatio(ratio);
+
+ setAutoOpacify(autoopacify);
+
+#ifdef USEAPPBAR
+ postDeferredCallback(DC_LOADSAVEDDOCK);
+
+ if (getParentContainer() && !getParentContainer()->isTranscient())
+ {
+ StringW prefix = MakePrefix();
+ StringW tmp = StringPrintfW(L"%s/appbar", prefix.v());
+ int side = WASABI_API_CONFIG->getIntPrivate(tmp, APPBAR_NOTDOCKED);
+ tmp.printf(L"%s/appbarisautohide", prefix.v());
+ int is_autohide = WASABI_API_CONFIG->getIntPrivate(tmp, 0);
+ tmp.printf(L"%s/appbarwantautohide", prefix.v());
+ appbar_want_autohide = is_autohide || WASABI_API_CONFIG->getIntPrivate(tmp, 1);
+ tmp.printf(L"%s/appbarontop", prefix.v());
+ appbar_want_alwaysontop = WASABI_API_CONFIG->getIntPrivate(tmp, 1);
+ tmp.printf(L"%s/appbarhidden",prefix.v());
+ int curside = appbar_getSide();
+ if (side != curside)
+ {
+ if (side == APPBAR_NOTDOCKED)
+ // starting up docked ??
+ appbar_dock(side);
+ else
+ {
+ setNoParent(2);
+ BaseWnd::reinit();
+ appbar_dock(side);
+ }
+ }
+ }
+ m_allowsavedock = 1;
+
+#endif
+}
+
+void Layout::setBaseTexture(const wchar_t *b, int regis)
+{
+ LAYOUT_PARENT::setBaseTexture(b, 0); // 0, not regis!
+ if (!getDesktopAlpha() || ((wantDesktopAlpha()) && alphabackground.getBitmap() == NULL))
+ {
+ if (regis) WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+#ifdef _WIN32
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, getDesktopAlpha() ? 1 : 255);
+ setRegion(reg);
+#else
+#warning port me
+#endif
+ }
+ if (regis)
+ WASABI_API_WND->skin_registerBaseTextureWindow(this, getBackgroundStr());
+ }
+}
+
+void Layout::setWantDesktopAlpha(int want)
+{
+ if (want && !Wasabi::Std::Wnd::isDesktopAlphaAvailable())
+ {
+ // WASABI_API_WNDMGR->messageBox("Desktop Alpha Blending is only available for Win2000/WinXP and above", "Sorry", MSGBOX_OK, NULL, NULL);
+ return ;
+ }
+ wantdesktopalpha = want;
+ if (wantdesktopalpha && isInited() && isDesktopAlphaSafe())
+ desktopAlpha_autoTurnOn();
+ else if (!wantdesktopalpha && getDesktopAlpha())
+ desktopAlpha_autoTurnOff();
+}
+
+int Layout::wantDesktopAlpha()
+{
+ return wantdesktopalpha;
+}
+
+int Layout::handleDesktopAlpha()
+{
+ return 1;
+}
+
+void Layout::onGuiObjectSetVisible(GuiObject *o, int visible)
+{
+ if (disable_auto_alpha) return ;
+ if (!o || !o->guiobject_getRootWnd()) return ;
+ if (visible)
+ {
+ if (getDesktopAlpha())
+ {
+ if (!o->guiobject_getRootWnd()->handleDesktopAlpha())
+ {
+ desktopAlpha_autoTurnOff();
+ }
+ }
+ if (!transparency_autooff)
+ {
+ if (!o->guiobject_getRootWnd()->handleTransparency())
+ {
+ transparency_autoTurnOff();
+ }
+ }
+ }
+ else
+ { // !visible
+ if (!getDesktopAlpha() && wantDesktopAlpha())
+ {
+ if (isDesktopAlphaSafe())
+ desktopAlpha_autoTurnOn();
+ }
+ if (transparency_autooff)
+ {
+ if (isTransparencySafe(1))
+ transparency_autoTurnOn();
+ }
+ }
+}
+
+void Layout::desktopAlpha_autoTurnOn()
+{
+
+ setDesktopAlpha(1);
+
+ WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+#ifdef _WIN32
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, 1);
+ setRegion(reg);
+#else
+#warning port me
+#endif
+ }
+
+ WASABI_API_WND->skin_registerBaseTextureWindow(this, alphabackground.getBitmap() ? alphabackgroundstr.getValue() : getBackgroundStr());
+
+ invalidate();
+}
+
+void Layout::desktopAlpha_autoTurnOff()
+{
+#ifdef WIN32
+ SetWindowRedraw(gethWnd(), FALSE);//LockWindowUpdate(gethWnd());
+ setDesktopAlpha(0);
+
+ WASABI_API_WND->skin_unregisterBaseTextureWindow(this);
+
+ if (getBaseTexture())
+ {
+ //RECT r = {0, 0, getBaseTexture()->getWidth(), getBaseTexture()->getHeight()};
+ delete reg;
+ reg = new RegionI(getBaseTexture(), NULL, 0, 0, 0, 0, 0, 0, 255);
+ setRegion(reg);
+ }
+
+ WASABI_API_WND->skin_registerBaseTextureWindow(this, getBackgroundStr());
+ SetWindowRedraw(gethWnd(), TRUE);//LockWindowUpdate(NULL);
+
+ invalidate();
+#else
+ DebugString( "portme -- Layout::init\n" );
+#endif
+}
+
+void Layout::transparency_autoTurnOn()
+{
+ transparency_reenabled_at = Wasabi::Std::getTickCount();
+ setTimer(TIMER_TRANSPARENCY_AUTOON, 500);
+}
+
+void Layout::transparency_autoTurnOff()
+{
+ transparency_autooff = 1;
+ killTimer(TIMER_TRANSPARENCY_AUTOON);
+ updateTransparency();
+}
+
+void Layout::onGlobalEnableDesktopAlpha(int enabled)
+{
+ foreach(alllayouts)
+ alllayouts.getfor()->globalEnableDesktopAlpha(enabled);
+ endfor
+#ifdef ON_TOGGLE_DESKTOPALPHA
+ ON_TOGGLE_DESKTOPALPHA(enabled);
+#endif
+}
+
+void Layout::globalEnableDesktopAlpha(int enabled)
+{
+ if (enabled)
+ {
+ galphadisabled = 0;
+ setWantDesktopAlpha(wantdesktopalpha);
+ }
+ else
+ {
+ galphadisabled = 1;
+ if (getDesktopAlpha())
+ desktopAlpha_autoTurnOff();
+ }
+}
+
+void Layout::setWantRedrawOnResize(int v)
+{
+ if (wantredrawonresize == v) return ;
+ wantredrawonresize = v;
+}
+
+PtrList<Layout> Layout::alllayouts;
+
+int Layout::onPaint(Canvas *canvas)
+{
+ PaintCanvas paintcanvas;
+ if (canvas == NULL)
+ {
+ if (!paintcanvas.beginPaint(this)) return 0;
+ canvas = &paintcanvas;
+ }
+
+ RECT r;
+
+ if (!canvas->getClipBox(&r))
+ getClientRect(&r);
+
+ canvas->fillRect(&r, 0);
+
+ LAYOUT_PARENT::onPaint(canvas);
+
+ return 1;
+}
+
+/*WndHolder *Layout::getHolder() {
+ return this;
+}*/
+
+SkinBitmap *Layout::getBaseTexture()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ int alphaenabled = _intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Enable desktop alpha");
+#else
+ int alphaenabled = WASABI_WNDMGR_DESKTOPALPHA;
+#endif
+ if (!alphabackground.getBitmap() || !getDesktopAlpha() || !alphaenabled) return LAYOUT_PARENT::getBaseTexture();
+ return alphabackground.getBitmap();
+}
+
+int Layout::runAction(int actionid, const wchar_t *param)
+{
+ switch (actionid)
+ {
+ case ACTION_SWITCH:
+ if (getParentContainer())
+ {
+ getParentContainer()->switchToLayout(param);
+ }
+ break;
+ case ACTION_TOGGLE:
+ SkinParser::toggleContainer(param);
+ break;
+#ifdef WA3COMPATIBILITY
+ case ACTION_MENU:
+ Main::doMenu(param);
+ break;
+#endif
+ case ACTION_ENDMODAL:
+ endModal(WTOI(param));
+ break;
+ case ACTION_CLOSE:
+ onActionNotify(ACTION_CLOSE);
+ break;
+#ifdef WA3COMPATIBILITY
+ default:
+ if (actionid != 0)
+ Main::doAction(actionid);
+ break;
+#else
+ case ACTION_MINIMIZE:
+#ifdef _WIN32
+ ShowWindow(WASABI_API_WND->main_getRootWnd()->gethWnd(), SW_MINIMIZE);
+#endif
+ break;
+#endif
+
+ }
+ return 0;
+}
+
+int Layout::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2)
+{
+ if (msg == ACTION_ENFORCEMINMAX)
+ {
+ loadSavedState();
+ return 0;
+ }
+ if (child != NULL)
+ {
+ int objId = child->getNotifyId();
+ if (msg == ChildNotify::BUTTON_LEFTPUSH)
+ {
+ switch (objId)
+ {
+ case ACTION_SWITCH:
+ case ACTION_TOGGLE:
+ case ACTION_MENU:
+ runAction(objId, ((Wasabi::Button *)child)->getParam());
+ break;
+ case ACTION_ENDMODAL:
+ {
+ StringPrintfW s(L"%d", (static_cast<ButtonWnd *>(child))->getModalRetCode());
+ runAction(ACTION_ENDMODAL, s);
+ }
+ break;
+ case ACTION_CLOSE:
+ runAction(ACTION_CLOSE);
+ break;
+ /*
+ #ifdef WA3COMPATIBILITY
+ case ACTION_EJECT:
+ runAction(ACTION_EJECT, "0");
+ break;
+ #endif
+ */
+ default:
+ runAction(objId);
+ break;
+ }
+ return 0;
+ }
+ if (msg == ChildNotify::BUTTON_RIGHTPUSH)
+ {
+ //FUCKO child->abortTip();
+ // POINT pt;
+ // Std::getMousePos(&pt);
+ // screenToClient(&pt);
+ // onRightButtonDown(pt.x, pt.y);
+#pragma warning (disable: 4060)
+ switch (objId)
+ {
+ /*
+ #ifdef WA3COMPATIBILITY
+ case ACTION_EJECT: {
+ runAction(ACTION_EJECT, "1");
+ }
+ break;
+ #endif
+ */
+ }
+#pragma warning (default: 4060)
+ return 0;
+ }
+ }
+ return LAYOUT_PARENT::childNotify(child, msg, param1, param2);
+}
+
+int Layout::onActionNotify(int action, intptr_t param)
+{
+ switch (action)
+ {
+#ifdef WA3COMPATIBILITY
+ case ACTION_SYSMENU:
+ Main::appContextMenu(this, TRUE, isDesktopAlphaSafe());
+ break;
+ case ACTION_CONTROLMENU:
+ controlMenu();
+ break;
+ case ACTION_WINDOWMENU:
+ Main::thingerContextMenu(this);
+ break;
+#elif defined(WASABI_CUSTOM_CONTEXTMENUS)
+ case ACTION_SYSMENU:
+ extern void appContextMenu(ifc_window *w);
+ appContextMenu(this);
+ break;
+ case ACTION_CONTROLMENU:
+ extern void appControlMenu(ifc_window *w);
+ appControlMenu(this);
+ break;
+#endif
+ case ACTION_SCALE_50: scaleTo(50); break;
+ case ACTION_SCALE_75: scaleTo(75); break;
+ case ACTION_SCALE_100: scaleTo(100); break;
+ case ACTION_SCALE_125: scaleTo(125); break;
+ case ACTION_SCALE_150: scaleTo(150); break;
+ case ACTION_SCALE_200: scaleTo(200); break;
+ case ACTION_SCALE_400: scaleTo(400); break;
+ case ACTION_ALPHA_10: setAlpha(25); break;
+ case ACTION_ALPHA_20: setAlpha(51); break;
+ case ACTION_ALPHA_30: setAlpha(76); break;
+ case ACTION_ALPHA_40: setAlpha(102); break;
+ case ACTION_ALPHA_50: setAlpha(127); break;
+ case ACTION_ALPHA_60: setAlpha(153); break;
+ case ACTION_ALPHA_70: setAlpha(178); break;
+ case ACTION_ALPHA_80: setAlpha(204); break;
+ case ACTION_ALPHA_90: setAlpha(229); break;
+ case ACTION_ALPHA_100: setAlpha(255); break;
+ case ACTION_AUTOOPACIFY: setAutoOpacify(!getAutoOpacify()); break;
+#ifdef EXPERIMENTAL_INDEPENDENT_AOT
+ case ACTION_AOT: setAlwaysOnTop(!getAlwaysOnTop()); break;
+#endif
+ case ACTION_CLOSE_WINDOW:
+ case ACTION_CLOSE:
+ if (getParentContainer() && getParentContainer()->isMainContainer())
+ {
+ int x = 1;
+#ifdef WASABI_CHECK_CAN_EXIT
+ WASABI_CHECK_CAN_EXIT(x)
+#endif
+ if (x)
+ {
+ WASABI_API_APP->main_shutdown();
+ }
+ }
+ else if (WASABI_API_WNDMGR->getModalWnd() != this)
+ {
+ if (!getParentContainer() || !getParentContainer()->isDynamic() || !getParentContainer()->canClose())
+ if (getParentContainer()) getParentContainer()->setVisible(FALSE); else setVisible(FALSE);
+ else
+ skinEmbedder->destroyContainer(getParentContainer());
+ }
+ else
+ {
+ endModal(MSGBOX_ABORTED);
+ }
+ break;
+ default: return 0;
+ }
+ return 1;
+}
+
+void Layout::containerToggled(const wchar_t *id, int visible)
+{
+ #ifdef _WIN32
+ sendNotifyToAllChildren(WM_WA_CONTAINER_TOGGLED, (intptr_t)id, visible);
+#else
+#warning port me
+#endif
+}
+
+void Layout::componentToggled(GUID *guid, int visible)
+{
+#ifdef _WIN32
+ sendNotifyToAllChildren(WM_WA_COMPONENT_TOGGLED, (intptr_t)guid, visible);
+#else
+#warning port me
+#endif
+}
+
+void Layout::setAlphaBackground(const wchar_t *b)
+{
+ alphabackgroundstr = b;
+ alphabackground.setBitmap(b);
+#ifdef _WIN32
+ RegionI r(alphabackground.getBitmap());
+ setRegion(&r);
+#else
+#warning port me
+#endif
+}
+
+/*void Layout::setWindowRegion(api_region *reg) {
+ LAYOUT_PARENT::setWindowRegion(reg);
+ if (getDesktopAlpha()) {
+ SetWindowRgn(gethWnd(), NULL, FALSE);
+ return;
+ }
+ if (!isInited()) return;
+ api_region *_r = getRegion();
+ if (getRenderRatio() != 1.0 && reg) {
+ api_region *clone = _r->clone();
+ clone->scale(getRenderRatio());
+ SetWindowRgn(gethWnd(), clone->makeWindowRegion(), TRUE);
+ _r->disposeClone(clone);
+ } else {
+ SetWindowRgn(gethWnd(), _r ? _r->makeWindowRegion() : NULL, TRUE);
+ }
+}*/
+
+void Layout::onSetDesktopAlpha(int a)
+{
+ invalidateWindowRegion();
+}
+
+void Layout::onShow(void)
+{
+ savePosition();
+ if (!WASABI_API_MAKI->vcpu_getComplete()) SystemObject::onShowLayout(this);
+}
+
+void Layout::onHide(void)
+{
+ savePosition();
+ if (!WASABI_API_MAKI->vcpu_getComplete()) SystemObject::onHideLayout(this);
+#ifndef WASABINOMAINAPI
+ api->hintGarbageCollect();
+#else
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::GC, GarbageCollectCallback::GARBAGECOLLECT);
+#endif
+ if (getParentContainer() && getParentContainer()->wantRefocusApp()) SkinParser::focusFirst();
+}
+
+#ifdef _WIN32
+LPARAM Layout::wndHolder_getParentParam(int i)
+{
+ switch (i)
+ {
+ case 0: return (LPARAM)gethWnd();
+ case 1: return (LPARAM)static_cast<BaseWnd*>(this);
+ }
+ return 0;
+}
+#endif
+
+void Layout::onSetVisible( int show )
+{
+ disable_auto_alpha = 1;
+ LAYOUT_PARENT::onSetVisible( show );
+
+ if ( show )
+ onShow();
+ else
+ onHide();
+
+ Container *p = getParentContainer();
+
+ if ( p )
+ p->onChildSetLayoutVisible( this, show );
+
+ disable_auto_alpha = 0;
+
+ if ( wantDesktopAlpha() && isDesktopAlphaSafe() )
+ desktopAlpha_autoTurnOn();
+}
+
+void Layout::scaleTo(int s)
+{
+ beginScale();
+ setRenderRatio((double)s / 100.0);
+ endScale();
+}
+
+void Layout::setRenderRatio(double s)
+{
+ if (isPostOnInit()
+ #ifdef WASABI_COMPILE_CONFIG
+ && cfg_uioptions_linkallratio.getValueAsInt() == 1
+#endif
+ && !broadcasting)
+ {
+ broadcasting = 1;
+ SkinParser::setAllLayoutsRatio(s);
+ broadcasting = 0;
+ return ;
+ }
+ if (getRenderRatio() == s) return ;
+ LAYOUT_PARENT::setRenderRatio(s);
+ if (reg) invalidateWindowRegion();
+ invalidate();
+ foreach(locked)
+ locked.getfor()->setRenderRatio(s);
+ endfor;
+ if (lockedto && lockedto->getRenderRatio() != getRenderRatio())
+ lockedto->setRenderRatio(getRenderRatio());
+ script_vcpu_onScale(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_DOUBLE(s));
+ if (!abortSaving()) savePosition();
+}
+
+void Layout::setAlpha(int a)
+{
+ int old = alpha;
+ alpha = a;
+ updateTransparency();
+#ifdef WASABI_COMPILE_CONFIG
+ if (old != alpha && getParentContainer())
+ {
+ StringPrintfW tmp(L"Skin:%s/Container:%s/Layout:%s/alpha", WASABI_API_SKIN->getSkinName(), getParentContainer()->getDescriptor(), getGuiObject()->guiobject_getId());
+ IntArray::write(tmp, alpha);
+ }
+#endif
+}
+
+int Layout::getAlpha()
+{
+ return alpha;
+}
+
+void Layout::setPaintingAlpha(int activealpha, int inactivealpha)
+{ // from basewnd, called by gui object
+ LAYOUT_PARENT::setAlpha(activealpha, inactivealpha);
+ updateTransparency();
+}
+
+int Layout::getPaintingAlpha()
+{ // from basewnd, called by gui object
+ return getAlpha();
+}
+
+int Layout::onActivate()
+{
+ LAYOUT_PARENT::onActivate();
+ // activateChildren(1);
+ updateTransparency();
+ return 1;
+}
+
+int Layout::onKillFocus()
+{
+ alphaMgr->hoverCheck(this);
+ int r = LAYOUT_PARENT::onKillFocus();
+ return r;
+}
+
+int Layout::onGetFocus()
+{
+ alphaMgr->hoverCheck(this);
+ int r = LAYOUT_PARENT::onGetFocus();
+ return r;
+}
+
+int Layout::onDeactivate()
+{
+ LAYOUT_PARENT::onDeactivate();
+ // activateChildren(0);
+ updateTransparency();
+ return 1;
+}
+
+void Layout::updateTransparency()
+{
+ alphaMgr->updateTransparency(this);
+}
+
+/*
+void Layout::activateChildren(int act) {
+ for (int i=0;i<gui_objects.getNumItems();i++) {
+ GuiObject *o = gui_objects.enumItem(i);
+ BaseWnd *b = NULL;
+ if (o)
+ b = o->getBaseWnd();
+ else
+ ASSERT(0);
+ if (b) {
+ if (act)
+ b->onActivate();
+ else
+ b->onDeactivate();
+ }
+ }
+}*/
+
+void Layout::center()
+{
+ RECT r;
+ getNonClientRect(&r);
+ RECT vw;
+ Wasabi::Std::getViewport(&vw, NULL, NULL, gethWnd());
+ int x = ((vw.right - vw.left) - (r.right - r.left)) / 2;
+ int y = ((vw.bottom - vw.top) - (r.bottom - r.top)) / 2;
+ move(x, y);
+}
+
+void Layout::setParentContainer(Container *c)
+{
+ p_container = c;
+}
+
+Container *Layout::getParentContainer()
+{
+ return p_container;
+}
+
+int Layout::isLayout()
+{
+ return 1;
+}
+
+void Layout::setInDesktop(int a)
+{
+ ASSERTPR(!isInited(), "cannot change indesktop after init");
+ indesktop = a;
+}
+
+int Layout::getInDesktop()
+{
+ return indesktop;
+}
+
+int Layout::isDesktopAlphaSafe()
+{
+#ifdef WASABI_COMPILE_CONFIG
+ if (galphadisabled) return 0;
+ // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
+ const GUID uioptions_guid =
+ { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
+ if (!_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Enable desktop alpha")) return 0;
+#else
+ if (!WASABI_WNDMGR_DESKTOPALPHA) return 0;
+#endif
+ return LAYOUT_PARENT::isDesktopAlphaSafe();
+}
+
+void Layout::setStatusText(const wchar_t *txt, int overlay)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->onSetStatusText(txt, overlay);
+ endfor;
+}
+
+void Layout::addAppCmds(AppCmds *commands)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->onAddAppCmds(commands);
+ endfor;
+}
+
+void Layout::removeAppCmds(AppCmds *commands)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->onRemoveAppCmds(commands);
+ endfor;
+}
+
+void Layout::pushCompleted(int max)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->pushCompleted(max);
+ endfor;
+}
+void Layout::incCompleted(int add)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->incCompleted(add);
+ endfor;
+}
+void Layout::setCompleted(int pos)
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->setCompleted(pos);
+ endfor;
+}
+void Layout::popCompleted()
+{
+ foreach(statuscbs)
+ statuscbs.getfor()->popCompleted();
+ endfor;
+}
+
+void Layout::registerStatusCallback(GuiStatusCallback *lcb)
+{
+ statuscbs.addItem(lcb);
+ viewer_addViewItem(lcb->status_getDependencyPtr());
+}
+
+int Layout::viewer_onItemDeleted(api_dependent *item)
+{
+ for (int i = 0;i < statuscbs.getNumItems();i++)
+ if (statuscbs.enumItem(i)->status_getDependencyPtr() == item)
+ {
+ statuscbs.removeByPos(i--);
+ }
+ return 1;
+}
+
+void Layout::snapAdjust(int left, int right, int top, int bottom)
+{
+ snap_adjust_left = left;
+ snap_adjust_top = top;
+ snap_adjust_right = right;
+ snap_adjust_bottom = bottom;
+ script_vcpu_onSnapAdjustChanged(SCRIPT_CALL, getScriptObject());
+ #ifdef USEAPPBAR
+ if (appbar_isDocked()) appbar_posChanged();
+#endif
+ if (forceTransparencyFlag() || getAlpha() < 255) postDeferredCallback(DC_INVALIDATE);
+}
+
+void Layout::getSnapAdjust(RECT *r)
+{
+ if (!r) return ;
+ r->left = snap_adjust_left;
+ r->top = snap_adjust_top;
+ r->right = snap_adjust_right;
+ r->bottom = snap_adjust_bottom;
+}
+
+int Layout::abortSaving()
+{
+ GuiObject *o = getGuiObject();
+ if (o->guiobject_movingToTarget()) return 1;
+ return 0;
+}
+
+void Layout::setNoOffscreenCheck(int nocheck)
+{
+ killTimer(TIMER_OFFSCREENCHECK);
+
+ if (nocheck != -1) nooffscreencheck = nocheck;
+
+ setTimer(TIMER_OFFSCREENCHECK, 2500);
+}
+
+#ifdef USEAPPBAR
+
+void Layout::onDock(int side)
+{
+ script_vcpu_onDock(SCRIPT_CALL, getScriptObject(), MAKE_SCRIPT_INT(side));
+}
+
+void Layout::onUnDock()
+{
+ script_vcpu_onUndock(SCRIPT_CALL, getScriptObject());
+}
+
+void Layout::appbar_onDock(int side)
+{
+ onDock(side);
+ savePosition();
+}
+
+void Layout::appbar_onUnDock()
+{
+ onUnDock();
+ savePosition();
+}
+
+void Layout::appbar_onSlide()
+{
+ savePosition();
+}
+
+int Layout::getAppBarAutoHide()
+{
+ return appbar_want_autohide;
+}
+
+void Layout::setAppBarAutoHide(int ah)
+{
+ appbar_want_autohide = ah;
+ if (appbar_isDocked()) appbar_updateAutoHide();
+ savePosition();
+}
+
+int Layout::getAppBarAlwaysOnTop()
+{
+ return appbar_want_alwaysontop;
+}
+
+void Layout::setAppBarAlwaysOnTop(int aot)
+{
+ appbar_want_alwaysontop = aot;
+ if (appbar_isDocked()) appbar_updateAlwaysOnTop();
+ savePosition();
+}
+#endif
+
+
+// ------------------------------------------------------------------------
+
+LayoutScriptController _layoutController;
+LayoutScriptController *layoutController = &_layoutController;
+
+// -- Functions table -------------------------------------
+function_descriptor_struct LayoutScriptController::exportedFunction[] = {
+ {L"onDock", 1, (void*)Layout::script_vcpu_onDock },
+ {L"onUndock", 0, (void*)Layout::script_vcpu_onUndock },
+ {L"getScale", 0, (void*)Layout::script_vcpu_getScale },
+ {L"setScale", 1, (void*)Layout::script_vcpu_setScale },
+ {L"onScale", 1, (void*)Layout::script_vcpu_onScale },
+ {L"setDesktopAlpha", 1, (void*)Layout::script_vcpu_setDesktopAlpha },
+ {L"getDesktopAlpha", 0, (void*)Layout::script_vcpu_getDesktopAlpha },
+ {L"isTransparencySafe", 0, (void*)Layout::script_vcpu_isTransparencySafe},
+ {L"isLayoutAnimationSafe", 0, (void*)Layout::script_vcpu_isLayoutAnimationSafe},
+ {L"getContainer", 0, (void*)Layout::script_vcpu_getContainer },
+ {L"center", 0, (void*)Layout::script_vcpu_center},
+ {L"onMove", 0, (void*)Layout::script_vcpu_onMove},
+ {L"onEndMove", 0, (void*)Layout::script_vcpu_onEndMove},
+ {L"snapAdjust", 4, (void*)Layout::script_vcpu_snapAdjust},
+ {L"getSnapAdjustTop", 0, (void*)Layout::script_vcpu_getSnapAdjustTop},
+ {L"getSnapAdjustLeft", 0, (void*)Layout::script_vcpu_getSnapAdjustLeft},
+ {L"getSnapAdjustRight", 0, (void*)Layout::script_vcpu_getSnapAdjustRight},
+ {L"getSnapAdjustBottom", 0, (void*)Layout::script_vcpu_getSnapAdjustBottom},
+ {L"onUserResize", 4, (void*)Layout::script_vcpu_onUserResize},
+ {L"setRedrawOnResize", 1, (void*)Layout::script_vcpu_setRedrawOnResize},
+ {L"beforeRedock", 0, (void*)Layout::script_vcpu_beforeRedock},
+ {L"redock", 0, (void*)Layout::script_vcpu_redock},
+ {L"onMouseEnterLayout", 0, (void*)Layout::script_vcpu_onMouseEnterLayout},
+ {L"onMouseLeaveLayout", 0, (void*)Layout::script_vcpu_onMouseLeaveLayout},
+ {L"onSnapAdjustChanged", 0, (void*)Layout::script_vcpu_onSnapAdjustChanged},
+ };
+// --------------------------------------------------------
+
+
+const wchar_t *LayoutScriptController::getClassName()
+{
+ return L"Layout";
+}
+
+const wchar_t *LayoutScriptController::getAncestorClassName()
+{
+ return L"Group";
+}
+
+int LayoutScriptController::getInstantiable()
+{
+ return 1;
+}
+
+ScriptObject *LayoutScriptController::instantiate()
+{
+ Layout *l = new Layout;
+ return l->getScriptObject();
+}
+
+void LayoutScriptController::destroy(ScriptObject *o)
+{
+ Group *g = static_cast<Group *>(o->vcpu_getInterface(groupGuid));
+ if (g && GroupMgr::hasGroup(g))
+ {
+ GroupMgr::destroy(g);
+ return ;
+ }
+ ASSERTALWAYS("you cannot destroy a static layout");
+}
+
+void *LayoutScriptController::encapsulate(ScriptObject *o)
+{
+ return NULL;
+}
+
+void LayoutScriptController::deencapsulate(void *o)
+{}
+
+int LayoutScriptController::getNumFunctions()
+{
+ return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
+}
+
+const function_descriptor_struct *LayoutScriptController::getExportedFunctions()
+{
+ return exportedFunction;
+}
+
+GUID LayoutScriptController::getClassGuid()
+{
+ return layoutGuid;
+}
+
+// -------------------------------------------------------------------------
+
+scriptVar Layout::script_vcpu_onDock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar side)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, layoutController, side);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, side);
+}
+
+scriptVar Layout::script_vcpu_onUndock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_getScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ double r = 0;
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) r = l->getRenderRatio();
+ return MAKE_SCRIPT_DOUBLE(r);
+}
+
+scriptVar Layout::script_vcpu_setScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ double a = GET_SCRIPT_DOUBLE(s);
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->setRenderRatio(a);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_onScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS1(o, layoutController, s);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT1(o, s);
+}
+
+scriptVar Layout::script_vcpu_setDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s)
+{
+ SCRIPT_FUNCTION_INIT
+ bool a = GET_SCRIPT_BOOLEAN(s);
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->setWantDesktopAlpha(a);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) return MAKE_SCRIPT_BOOLEAN(l->wantDesktopAlpha() && l->isDesktopAlphaSafe());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layout::script_vcpu_isTransparencySafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) return MAKE_SCRIPT_BOOLEAN(l->isTransparencySafe());
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layout::script_vcpu_isLayoutAnimationSafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) return MAKE_SCRIPT_BOOLEAN(!l->forceTransparencyFlag() && (l->getAlphaMgr()->getAlpha(l) == 255));
+ RETURN_SCRIPT_ZERO;
+}
+
+scriptVar Layout::script_vcpu_getContainer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ return MAKE_SCRIPT_OBJECT(c ? c->getScriptObject() : NULL);
+ }
+ return MAKE_SCRIPT_OBJECT(NULL);
+}
+
+scriptVar Layout::script_vcpu_center(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->center();
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_setRedrawOnResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->setWantRedrawOnResize(GET_SCRIPT_INT(v));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_beforeRedock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) windowTracker->beforeRedock(l, &l->redock);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_redock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) windowTracker->afterRedock(l, &l->redock);
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_onEndMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onMouseEnterLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onMouseLeaveLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onSnapAdjustChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_onUserResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS4(o, layoutController, x, y, w, h);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT4(o, x, y, w, h);
+}
+
+scriptVar Layout::script_vcpu_onMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT;
+ PROCESS_HOOKS0(o, layoutController);
+ SCRIPT_FUNCTION_CHECKABORTEVENT;
+ SCRIPT_EXEC_EVENT0(o);
+}
+
+scriptVar Layout::script_vcpu_snapAdjust(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar right, scriptVar bottom)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l) l->snapAdjust(GET_SCRIPT_INT(left), GET_SCRIPT_INT(top), GET_SCRIPT_INT(right), GET_SCRIPT_INT(bottom));
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.left);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustTop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.top);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.right);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+scriptVar Layout::script_vcpu_getSnapAdjustBottom(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
+{
+ SCRIPT_FUNCTION_INIT
+ Layout *l = static_cast<Layout *>(o->vcpu_getInterface(layoutGuid));
+ if (l)
+ {
+ RECT r;
+ l->getSnapAdjust(&r);
+ return MAKE_SCRIPT_INT(r.bottom);
+ }
+ RETURN_SCRIPT_VOID;
+}
+
+int Layout::broadcasting = 0;
+
+StringW Layout::MakePrefix()
+{
+ return StringPrintfW(L"Skin:%s/Container:%s/Layout:%s", WASABI_API_SKIN->getSkinName(), getParentContainer()->getDescriptor(), getGuiObject()->guiobject_getId());
+} \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/layout.h b/Src/Wasabi/api/wndmgr/layout.h
new file mode 100644
index 00000000..20a90504
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/layout.h
@@ -0,0 +1,465 @@
+#ifndef __LAYOUT_H
+#define __LAYOUT_H
+
+class Layout;
+class Group;
+class Container;
+class Layer;
+
+#include <bfc/tlist.h>
+#include <bfc/depend.h>
+#include <tataki/bitmap/bitmap.h>
+#include <api/wnd/wndclass/buttwnd.h>
+#include <tataki/region/region.h>
+#include <api/wndmgr/container.h>
+#include <api/skin/group.h>
+#include <api/skin/widgets/layer.h>
+#include <api/wndmgr/guistatuscb.h>
+#include <api/script/script.h>
+#include <api/script/scriptobj.h>
+#ifdef WASABI_WIDGETS_GUIOBJECT
+#include <api/script/objects/guiobj.h>
+#endif
+#include <api/wnd/accessible.h>
+#include <api/wndmgr/alphamgr.h>
+#include <api/wnd/resizable.h>
+
+class XmlObject;
+class Layout;
+
+extern AlphaMgr *alphaMgr;
+
+class LayoutScriptController : public GroupScriptController {
+ public:
+
+ virtual const wchar_t *getClassName();
+ virtual const wchar_t *getAncestorClassName();
+ virtual ScriptObjectController *getAncestorController() { return groupController; }
+ virtual int getNumFunctions();
+ virtual const function_descriptor_struct *getExportedFunctions();
+ virtual GUID getClassGuid();
+ virtual ScriptObject *instantiate();
+ virtual int getInstantiable();
+ virtual void destroy(ScriptObject *o);
+ virtual void *encapsulate(ScriptObject *o);
+ virtual void deencapsulate(void *o);
+
+ private:
+
+ static function_descriptor_struct exportedFunction[];
+
+};
+
+extern LayoutScriptController *layoutController;
+
+#ifndef _NOSTUDIO
+
+class AutoOpacityLinker;
+
+#define LAYOUT_PARENT Group
+#define LAYOUT_SCRIPTPARENT Group
+
+class Layout : public LAYOUT_SCRIPTPARENT, public DependentViewerI, public GuiResizable
+{
+
+public:
+ Layout();
+ virtual ~Layout();
+
+#ifdef _WIN32
+ virtual LRESULT wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#else
+ virtual OSStatus eventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
+#endif
+
+// int onPaint(Canvas *canvas);
+ virtual int onInit();
+ virtual int init(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild);
+ virtual int reinit(OSMODULEHANDLE inst, OSWINDOWHANDLE parent, int nochild);
+
+ virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
+ virtual int onActionNotify(int action, intptr_t param=0);
+
+ virtual void resize(int x, int y, int w, int h, int wantcb=1);
+ virtual void move(int x, int y);
+
+// virtual int onRightButtonDown(int x, int y);
+// virtual int onLeftButtonDown(int x, int y);
+// virtual int onMouseMove(int x, int y);
+// virtual int onLeftButtonUp(int x, int y);
+ virtual int onResize();
+ virtual int onPostedMove();
+ virtual int onPaint(Canvas *canvas);
+ virtual void onSetDesktopAlpha(int a);
+ virtual int isLayout();
+ virtual void setAlphaBackground(const wchar_t *txture);
+ virtual SkinBitmap *getBaseTexture();
+ virtual void onGuiObjectSetVisible(GuiObject *o, int status); // called whenever a child shows/hide
+ virtual ifc_window *getCustomOwner();
+ virtual void addLockedLayout(Layout *l);
+ virtual void removeLockedLayout(Layout *l);
+ virtual int getNumLockedLayouts();
+ virtual Layout *enumLockedLayout(int n);
+ virtual int isLocked();
+ virtual void lockTo(Layout *l);
+ virtual Layout *getLockedTo();
+ void updateLockedLayouts();
+ virtual int onGetFocus();
+ virtual int onKillFocus();
+ virtual void snapAdjust(int left, int right, int top, int bottom);
+
+ virtual void onShow(void);
+ virtual void onHide(void);
+
+ virtual void center();
+
+ virtual int wantDesktopAlpha();
+ virtual void setWantDesktopAlpha(int want);
+ virtual int handleDesktopAlpha();
+
+ virtual int setXuiParam(int _xuihandle, int attribid, const wchar_t *paramname, const wchar_t *strvalue);
+
+ void setWindowRegion(api_region *reg);
+ virtual int allowResize() {
+ return !isLocked()
+#ifdef USEAPPBAR
+ && !appbar_isDocked()
+#endif
+ ;
+ }
+
+ // container/component callbacks to get notified that a container
+ // has been set visible/invisible
+ void containerToggled(const wchar_t *id,int visible);
+ void componentToggled(GUID *guid, int visible);
+
+ void setParentContainer(Container *c);
+ virtual Container *getParentContainer();
+
+ virtual int isClickThrough();
+
+ void onSetVisible(int show);
+ virtual void cancelCapture();
+
+ virtual int onActivate();
+ virtual int onDeactivate();
+
+ virtual int forceTransparencyFlag();
+
+ int x, y;
+
+#ifdef _WIN32
+ void setForwardMsgWnd(HWND wnd) { forwardMsgWnd = wnd; }
+
+ LPARAM wndHolder_getParentParam(int i=0);
+#endif
+
+ void scaleTo(int s);
+ virtual void setRenderRatio(double s);
+
+ virtual void beginMove();
+ virtual void beginScale();
+ virtual void beginResize();
+ virtual void endMove();
+ virtual void endScale();
+ virtual void endResize();
+
+ virtual void setEndMoveResize(int w, int h) {
+ m_w = w;
+ m_h = h;
+ m_endmovesize = 1;
+ };
+
+ virtual ifc_window *guiresizable_getRootWnd() { return (this); }
+
+
+ virtual void lockScale(int locked);
+ virtual int isScaleLocked() { return scalelocked; }
+
+ virtual void onMove();
+
+ virtual int isDesktopAlphaSafe();
+
+ void addSubRegionLayer(Layer *l);
+ void removeSubRegionLayer(Layer *l);
+
+ virtual void setInDesktop(int a);
+ virtual int getInDesktop();
+
+ virtual void setAlpha(int a);
+ virtual int getAlpha();
+ virtual int getPaintingAlpha();
+ virtual void timerCallback(int id);
+
+ virtual void setLinkWidth(const wchar_t *layoutid);
+ virtual void setLinkHeight(const wchar_t *layoutid);
+
+ virtual void setBaseTexture(const wchar_t *b, int regis=1);
+ virtual void setPaintingAlpha(int activealpha, int inactivealpha=-1);
+
+ static void onGlobalEnableDesktopAlpha(int enabled);
+
+ void savePosition();
+#ifdef USEAPPBAR
+ void saveAppBarPosition();
+#endif
+ virtual void setStatusText(const wchar_t *txt, int overlay=0);
+ virtual void addAppCmds(AppCmds *commands);
+ virtual void removeAppCmds(AppCmds *commands);
+
+ void pushCompleted(int max=100);
+ void incCompleted(int add=1);
+ void setCompleted(int pos);
+ void popCompleted();
+
+ virtual void registerStatusCallback(GuiStatusCallback *lcb);
+ virtual int viewer_onItemDeleted(api_dependent *item);
+ virtual int wantActivation() { return wantactiv && LAYOUT_PARENT::wantActivation(); }
+ void loadSavedState();
+ virtual void updateOnTop();
+
+ virtual int runAction(int actionid, const wchar_t *param=NULL);
+
+ virtual void getSnapAdjust(RECT *r);
+
+ virtual void updateTransparency();
+ virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
+ virtual int wantRedrawOnResize() { return wantredrawonresize; }
+ virtual void setWantRedrawOnResize(int v);
+
+#ifdef USEAPPBAR
+ virtual int appbar_wantAutoHide() { return getAppBarAutoHide(); }
+ virtual int appbar_wantAlwaysOnTop() { return getAppBarAlwaysOnTop(); }
+
+ virtual int getAppBarAutoHide();
+ virtual void setAppBarAutoHide(int ah);
+
+ virtual int getAppBarAlwaysOnTop();
+ virtual void setAppBarAlwaysOnTop(int aot);
+#endif
+
+ virtual void pushForceUnlink() { m_forceunlink++; }
+ virtual void popForceUnlink() { m_forceunlink--; }
+
+ virtual int isUnlinked() {
+#ifdef USEAPPBAR
+ return unlinked || appbar_isDocked() || m_forceunlink;
+#else
+ return unlinked || m_forceunlink;
+#endif
+ }
+
+ void setAutoOpacify(int a);
+ int getAutoOpacify() { return autoopacify; }
+
+ void offscreenCheck();
+ int isOffscreen(ifc_window *w);
+
+ int getResizable();
+ int getScalable();
+
+ void setTransparencyOverride(int v);
+ int getTransparencyOverride() { return transparencyoverride; }
+
+ enum {
+ LAYOUT_SETDESKTOPALPHA=0,
+ LAYOUT_SETINDESKTOP,
+ LAYOUT_SETALPHA,
+ LAYOUT_SETLINKWIDTH,
+ LAYOUT_SETLINKHEIGHT,
+ LAYOUT_SETOWNER,
+ LAYOUT_SETLOCKTO,
+ LAYOUT_SETOSFRAME,
+ LAYOUT_SETALPHABACKGROUND,
+ LAYOUT_SETNOACTIVATION,
+ LAYOUT_SETONTOP,
+ LAYOUT_SNAPADJUSTLEFT,
+ LAYOUT_SNAPADJUSTTOP,
+ LAYOUT_SNAPADJUSTRIGHT,
+ LAYOUT_SNAPADJUSTBOTTOM,
+ LAYOUT_UNLINKED,
+ LAYOUT_NOPARENT,
+ LAYOUT_FORCEALPHA,
+ LAYOUT_NODOCK,
+ LAYOUT_NOOFFSCREENCHECK,
+ LAYOUT_RESIZABLE,
+ LAYOUT_SCALABLE,
+ };
+
+
+ void onMouseEnterLayout();
+ void onMouseLeaveLayout();
+
+ int getNoParent() { return noparent; }
+ void setNoParent(int np) { noparent = np; }
+ int isAlphaForced() { return forcealpha; }
+
+ AlphaMgr *getAlphaMgr() { return alphaMgr; }
+
+ int getNoDock() { return nodock; }
+ void setNoDock(int nd) { nodock = nd; }
+ int isTransparencyForcedOff() { return transparency_autooff; }
+
+ void controlMenu();
+
+ void setNoOffscreenCheck(int nocheck);
+
+#ifdef USEAPPBAR
+ void onDock(int side);
+ void onUnDock();
+
+ virtual void appbar_onDock(int side);
+ virtual void appbar_onUnDock();
+ virtual void appbar_onSlide();
+#endif
+
+protected:
+ /*static */void CreateXMLParameters(int master_handle);
+/* virtual int dragEnter(ifc_window *sourceWnd);
+ virtual int dragOver(int x, int y, ifc_window *sourceWnd);
+ virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
+ virtual int acceptExternalDrops() { return 1; }*/
+ virtual int wantClickWndAutoInvalidate() { return 0; }
+
+
+private:
+ StringW MakePrefix();
+ static XMLParamPair params[];
+ void fixPosition();
+ void saveAllPositions();
+ void activateChildren(int act);
+#ifdef _WIN32
+ void getExplorerWindows(HWND *parent, HWND *listview, HWND *webserver);
+#endif
+ void desktopAlpha_autoTurnOn();
+ void desktopAlpha_autoTurnOff();
+ void transparency_autoTurnOn();
+ void transparency_autoTurnOff();
+ void globalEnableDesktopAlpha(int enabled);
+
+#ifdef _WIN32
+ HWND forwardMsgWnd;
+#endif
+ int resizing;
+ int wantactiv;
+ int size_w,size_h;
+ int cX,cY;
+ int captured;
+ POINT mousepos;
+#ifdef _WIN32
+ HWND webserver;
+ HWND listview;
+#endif
+ int alphagoingon;
+ int alphagoingoff;
+ int scalelocked;
+ int wantredrawonresize;
+
+ int xuihandle;
+
+ RegionI *reg;
+ //PtrList<Layer> *subregionlayers;
+ Container *p_container;
+ StringW alphabackgroundstr;
+ ifc_window *wndholders;
+ int abortSaving();
+ int transparencyoverride;
+
+ int default_x;
+ int default_y;
+ int moving;
+ int scaling;
+ int mover;
+ int indesktop;
+ int alpha;
+ StringW linkedheight, linkedwidth;
+ int inlinkwidth, inlinkheight;
+ AutoSkinBitmap alphabackground;
+ int wantdesktopalpha;
+ int galphadisabled;
+ static PtrList<Layout> alllayouts;
+ StringW owner;
+ PtrList<Layout> locked;
+ StringW lockto;
+ Layout *lockedto;
+ int inpostedmove;
+ int osframe;
+ PtrList<GuiStatusCallback> statuscbs;
+ int initontop;
+// GarbageCollector gc;
+ PtrList<AppCmds> appcmds;
+ int inresize;
+ int unlinked;
+
+ int snap_adjust_left;
+ int snap_adjust_top;
+ int snap_adjust_right;
+ int snap_adjust_bottom;
+
+ int disable_auto_alpha;
+ int autoopacify;
+ int noparent;
+ int forcealpha;
+ redock_struct redock;
+ static int broadcasting;
+ int nodock;
+ uint32_t transparency_reenabled_at;
+ int transparency_autooff;
+ int nooffscreencheck;
+ int resizable;
+ int scalable;
+
+ int m_w, m_h;
+ int m_endmovesize;
+ int m_allowsavedock;
+ int m_forceunlink;
+#ifdef USEAPPBAR
+ int appbar_want_autohide;
+ int appbar_want_alwaysontop;
+#endif
+
+// FG>
+// -- SCRIPT -----------------------------------------------------
+public:
+
+ static scriptVar script_vcpu_onDock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar side);
+ static scriptVar script_vcpu_onUndock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_setScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_onScale(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_setDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar s);
+ static scriptVar script_vcpu_getDesktopAlpha(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_isTransparencySafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_isLayoutAnimationSafe(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getContainer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_center(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onEndMove(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onUserResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar x, scriptVar y, scriptVar w, scriptVar h);
+ static scriptVar script_vcpu_snapAdjust(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar left, scriptVar top, scriptVar right, scriptVar bottom);
+ static scriptVar script_vcpu_setRedrawOnResize(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v);
+ static scriptVar script_vcpu_beforeRedock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_redock(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustTop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustLeft(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustRight(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_getSnapAdjustBottom(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onMouseEnterLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onMouseLeaveLayout(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+ static scriptVar script_vcpu_onSnapAdjustChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
+
+#else
+class Layout : public LAYOUT_SCRIPTPARENT {
+
+public:
+
+#endif
+
+// INSERT_SCRIPT_OBJECT_CONTROL
+
+
+};
+
+// END SCRIPT
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/msgbox.cpp b/Src/Wasabi/api/wndmgr/msgbox.cpp
new file mode 100644
index 00000000..4a32cf66
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/msgbox.cpp
@@ -0,0 +1,251 @@
+#include <precomp.h>
+#include "msgbox.h"
+#include <api/wndmgr/skinwnd.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_container.h>
+#include <api/script/objects/c_script/c_text.h>
+#include <api/script/objects/c_script/c_button.h>
+
+_btnstruct msgboxbtns[] =
+ {
+ { L"<<", MSGBOX_PREVIOUS },
+ { L"OK", MSGBOX_OK },
+ { L"Yes", MSGBOX_YES },
+ { L"All", MSGBOX_ALL },
+ { L"No", MSGBOX_NO },
+ { L">>", MSGBOX_NEXT },
+ { L"Cancel", MSGBOX_CANCEL },
+ };
+
+MsgBox::MsgBox(const wchar_t *_text, const wchar_t *_title, int _flags, const wchar_t *notanymore)
+{
+ text = _text;
+ title = _title;
+ flags = _flags;
+#ifdef WIN32
+#ifdef _DEBUG
+ DebugStringW(L"msgbox: %s: %s", title, text.getValue());
+#endif
+#endif
+ notanymore_id = notanymore;
+ sw = NULL;
+ if (flags == 0) flags = MSGBOX_OK;
+}
+
+MsgBox::~MsgBox()
+{
+ foreach(buttons)
+ WASABI_API_SKIN->xui_delete(buttons.getfor());
+ endfor
+}
+
+int MsgBox::run()
+{
+ int _r = -1;
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (!notanymore_id.isempty())
+ {
+ StringPrintfW txt(L"msgbox_defaultvalue_%s", notanymore_id);
+ if ((GetKeyState(VK_SHIFT) & 0x8000))
+ WASABI_API_CONFIG->setIntPublic(txt, -1);
+ _r = WASABI_API_CONFIG->getIntPublic(txt, -1);
+ }
+#endif
+
+ if (_r == -1)
+ {
+ sw = new SkinWnd(L"msgbox.custom.group", L"modal", FALSE, NULL, 1, 1);
+ if (!sw->getWindow()) return -1;
+ ifc_window *grp = sw->getWindow();
+ ifc_window *l = grp->getDesktopParent();
+
+ GuiObject *_p = sw->findObject(L"msgbox.custom.group");
+ //CUT: api_window *p = _p->guiobject_getRootWnd();
+
+ C_Container cont(sw->getContainer());
+ cont.setName(title);
+
+ createButtons();
+ int min_w = reposButtons();
+
+ GuiObject *go_txt = sw->findObject(L"msgbox.text");
+ if (go_txt != NULL)
+ {
+ GuiObject *to = go_txt->guiobject_findObject(L"wasabi.text");
+ GuiObject *gto = sw->findObject(L"text");
+ if (to != NULL && gto != NULL)
+ {
+ go_txt->guiobject_setXmlParam(L"text", text);
+ C_GuiObject t(*go_txt);
+ int _w = t.getAutoWidth();
+ int _h = t.getAutoHeight();
+
+ to->guiobject_setXmlParam(L"w", StringPrintfW(_w));
+ to->guiobject_setXmlParam(L"h", StringPrintfW(_h));
+ to->guiobject_setXmlParam(L"relatw", L"0");
+ to->guiobject_setXmlParam(L"relath", L"0");
+
+ int x, rx, w, rw;
+ int y, ry, h, rh;
+ int gtow, gtoh;
+
+ go_txt->guiobject_getGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh);
+ if (rw == 1)
+ _w += -w;
+ else
+ _w += x * 2;
+ if (rh == 1)
+ _h += -h;
+ else
+ _h += y * 2;
+
+ gtow = _w;
+ gtoh = _h;
+
+ GuiObject *grpo = grp->getGuiObject();
+ ASSERT(grpo != NULL);
+ gto->guiobject_getGuiPosition(&x, &y, &w, &h, &rx, &ry, &rw, &rh);
+ if (rw == 1)
+ _w += -w;
+ else
+ _w += x * 2;
+ if (rh == 1)
+ _h += -h;
+ else
+ _h += y * 2;
+
+ gto->guiobject_setXmlParam(L"w", StringPrintfW(gtow));
+ gto->guiobject_setXmlParam(L"h", StringPrintfW(gtoh));
+
+ grpo->guiobject_setXmlParam(L"w", StringPrintfW(_w));
+ grpo->guiobject_setXmlParam(L"h", StringPrintfW(_h));
+ grpo->guiobject_setXmlParam(L"lockminmax", L"1");
+ grpo->guiobject_setXmlParam(L"propagatesize", L"1");
+ XmlObject *xl = static_cast<XmlObject *>(l->getInterface(xmlObjectGuid));
+ xl->setXmlParam(L"minimum_h", StringPrintfW(L"%d", _h));
+ xl->setXmlParam(L"minimum_w", StringPrintfW(L"%d", (_w < min_w) ? min_w : _w));
+ }
+ }
+
+ if (!notanymore_id.isempty())
+ {
+ GuiObject *o = WASABI_API_SKIN->xui_new(L"Wasabi:CheckBox"); // that'll be deleted automatically when our parent group destroys
+ if (o != NULL)
+ {
+ ifc_window *w = o->guiobject_getRootWnd();
+ C_GuiObject go(*o);
+ go.init(_p->guiobject_getScriptObject());
+ o->guiobject_setXmlParam(L"text", L"Do not show this message anymore");
+ o->guiobject_setXmlParam(L"y", L"-50");
+ o->guiobject_setXmlParam(L"relaty", L"1");
+ o->guiobject_setXmlParam(L"x", L"12");
+ o->guiobject_setXmlParam(L"relatx", L"0");
+ o->guiobject_setXmlParam(L"w", L"-24");
+ o->guiobject_setXmlParam(L"relatw", L"1");
+ min_w = MAX(w->getPreferences(SUGGESTED_W), min_w);
+ }
+ }
+
+ sw->notifyMinMaxChanged();
+ reposButtons();
+ _r = sw->runModal(1);
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ if (!notanymore_id.isempty() && _r != -1 && sw != NULL)
+ {
+ GuiObject *o = sw->findObject(L"checkbox.toggle");
+ if (o != NULL)
+ {
+ C_Button b(*o);
+ if (b.getActivated())
+ {
+ StringPrintfW txt(L"msgbox_defaultvalue_%s", notanymore_id);
+ WASABI_API_CONFIG->setIntPublic(txt, _r);
+ }
+ }
+ }
+#endif
+
+ if (sw) sw->destroy(); sw = NULL;
+
+ return _r;
+}
+
+void MsgBox::addButton(const wchar_t *text, int retcode)
+{
+ GuiObject *o = WASABI_API_SKIN->xui_new(L"Wasabi:Button"); // that wil NOT be deleted automatically when our parent group destroys because we did not init with guiobject
+ if (o != NULL)
+ {
+ o->guiobject_setXmlParam(L"action", L"endmodal");
+ o->guiobject_setXmlParam(L"retcode", StringPrintfW(retcode));
+ o->guiobject_setXmlParam(L"text", text);
+ buttons.addItem(o);
+ }
+}
+
+void MsgBox::createButtons()
+{
+ GuiObject *_p = sw->findObject(L"msgbox.custom.group");
+ if (!_p) return ;
+
+ ASSERT(buttons.getNumItems() == 0);
+ buttons.deleteAll();
+
+ for (int i = 0;i < sizeof(msgboxbtns) / sizeof(_btnstruct);i++)
+ {
+ if (flags & msgboxbtns[i].id)
+ {
+ addButton(msgboxbtns[i].txt, msgboxbtns[i].id);
+ }
+ }
+
+ ifc_window *p = _p->guiobject_getRootWnd();
+
+ foreach(buttons)
+ ifc_window *wnd = buttons.getfor()->guiobject_getRootWnd();
+ if (wnd != NULL)
+ {
+ wnd->setStartHidden(1);
+ wnd->setParent(p);
+ wnd->init(p);
+ }
+ endfor;
+}
+
+int MsgBox::reposButtons()
+{
+ RECT r;
+ GuiObject *_p = sw->findObject(L"msgbox.custom.group");
+ ifc_window *p = _p->guiobject_getRootWnd();
+ p->getClientRect(&r);
+
+ int shift = 0;
+
+ //CUT: int _w = 0;
+ //CUT: int _h = 0;
+ for (int i = buttons.getNumItems() - 1;i >= 0;i--)
+ {
+ ifc_window *wnd = buttons.enumItem(i)->guiobject_getRootWnd();
+ if (wnd != NULL)
+ {
+ int _w = wnd->getPreferences(SUGGESTED_W);
+ int _h = wnd->getPreferences(SUGGESTED_H);
+ if (_w == AUTOWH) _w = -1;
+ int w = MAX(_w, 64);
+ wnd->resize(r.right - w - 16 - shift, r.bottom - 8 - _h, w, _h);
+ _w = MAX(w, _w);
+ _h = MAX(_h, _h);
+ shift += w + 4;
+ }
+ }
+
+ foreach(buttons)
+ ifc_window *wnd = buttons.getfor()->guiobject_getRootWnd();
+ if (wnd != NULL)
+ wnd->setVisible(1);
+ endfor;
+ return shift;
+}
diff --git a/Src/Wasabi/api/wndmgr/msgbox.h b/Src/Wasabi/api/wndmgr/msgbox.h
new file mode 100644
index 00000000..41487835
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/msgbox.h
@@ -0,0 +1,49 @@
+#ifndef __MESSAGEBOX_H
+#define __MESSAGEBOX_H
+
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+
+#define MSGBOX_ABORTED 0 // NOT a flag, only a return code
+
+#define MSGBOX_OK 1
+#define MSGBOX_CANCEL 2
+#define MSGBOX_YES 4
+#define MSGBOX_NO 8
+#define MSGBOX_ALL 16
+#define MSGBOX_NEXT 32
+#define MSGBOX_PREVIOUS 64
+
+class GuiObject;
+class SkinWnd;
+
+
+typedef struct {
+ wchar_t *txt;
+ int id;
+} _btnstruct;
+
+class MsgBox {
+ public:
+
+ MsgBox(const wchar_t *text, const wchar_t *title=L"Alert", int flags=MSGBOX_OK, const wchar_t *notanymore=NULL);
+ virtual ~MsgBox();
+ virtual int run();
+
+
+ private:
+
+ void createButtons();
+ int reposButtons();
+ void addButton(const wchar_t *text, int retcode);
+
+ StringW text, title;
+ int flags;
+ PtrList<GuiObject> buttons;
+ GuiObject *checkbox;
+ SkinWnd *sw;
+ StringW notanymore_id;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/resize.cpp b/Src/Wasabi/api/wndmgr/resize.cpp
new file mode 100644
index 00000000..959ece91
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/resize.cpp
@@ -0,0 +1,383 @@
+#include <precomp.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <bfc/assert.h>
+#include <api/wndmgr/resize.h>
+#include <api/wnd/wndtrack.h>
+#include <api/wnd/basewnd.h>
+#include <api/wndmgr/layout.h>
+
+#define tag L"wa3_resizerclass"
+
+extern HINSTANCE hInstance;
+
+
+//----------------------------------------------------------------------
+resizeClass::resizeClass(ifc_window *wnd, int minx, int miny, int maxx, int maxy, int sugx, int sugy)
+{
+ screenWidth = Wasabi::Std::getScreenWidth();
+ screenHeight = Wasabi::Std::getScreenHeight();
+
+#if defined (_WIN32) || defined(_WIN64)
+ WNDCLASSW wc;
+ if (!GetClassInfoW(hInstance, tag, &wc))
+ {
+ MEMSET(&wc, 0, sizeof(wc));
+ wc.lpfnWndProc = resizeWndProc;
+ wc.hInstance = hInstance; // hInstance of DLL
+ wc.lpszClassName = tag; // our window class name
+ wc.style = 0;
+
+ int _r = RegisterClassW(&wc);
+ ASSERTPR(_r, "cannot create resizer wndclass");
+ }
+
+ hWnd = CreateWindowExW(0, tag, L"", 0, 0, 0, 1, 1, NULL, NULL, hInstance, NULL);
+
+ ASSERT(hWnd);
+
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this);
+
+ if (minx > maxx && maxx != -1) minx = maxx;
+ if (miny > maxy && maxy != -1) miny = maxy;
+#endif
+
+ minWinWidth = minx;
+ minWinHeight = miny;
+ maxWinWidth = maxx;
+ maxWinHeight = maxy;
+ sugWinWidth = sugx;
+ sugWinHeight = sugy;
+
+ if (wnd->getInterface(layoutGuid))
+ {
+ static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
+ if (minWinWidth != -1) minWinWidth -= snapAdjust.left + snapAdjust.right;
+ if (minWinHeight != -1) minWinHeight -= snapAdjust.bottom + snapAdjust.top;
+ if (maxWinWidth != -1) maxWinWidth -= snapAdjust.left + snapAdjust.right;
+ if (maxWinHeight != -1) maxWinHeight -= snapAdjust.bottom + snapAdjust.top;
+ if (sugWinWidth != -1) sugWinWidth -= snapAdjust.left + snapAdjust.right;
+ if (sugWinHeight != -1) sugWinHeight -= snapAdjust.bottom + snapAdjust.top;
+ }
+
+ dc = NULL;
+#ifdef WIN32
+ oldB = NULL;
+ brush = NULL;
+ oldP = NULL;
+ pen = NULL;
+#endif
+}
+
+
+//----------------------------------------------------------------------
+resizeClass::~resizeClass()
+{
+#ifdef WIN32
+ if (dc)
+ {
+ SelectObject(dc, oldB);
+ SelectObject(dc, oldP);
+ SetROP2(dc, mix);
+ DeleteObject(pen);
+ DeleteObject(brush);
+ ReleaseDC(NULL, dc);
+ }
+
+ if (IsWindow(hWnd))
+ DestroyWindow(hWnd);
+ //BU win98 sucks UnregisterClass(tag, Main::gethInstance());
+#else
+ if (dc)
+ {
+ XFreeGC(Linux::getDisplay(), dc->gc);
+ FREE(dc);
+ }
+#endif
+}
+
+//----------------------------------------------------------------------
+BOOL CALLBACK invalidateChildren(HWND hwnd, LPARAM lParam)
+{
+ InvalidateRect(hwnd, NULL, FALSE);
+ return TRUE;
+}
+
+//----------------------------------------------------------------------
+BOOL CALLBACK invalidateAll(HWND hwnd, LPARAM lParam)
+{
+ EnumChildWindows(hwnd, invalidateChildren, 0);
+ InvalidateRect(hwnd, NULL, FALSE);
+ return TRUE;
+}
+
+//----------------------------------------------------------------------
+int resizeClass::resizeWindow(ifc_window *wnd, int way)
+{
+
+ // paintHookStart();
+
+ wnd->getWindowRect(&originalRect);
+
+ snapAdjust.left = 0;
+ snapAdjust.top = 0;
+ snapAdjust.right = 0;
+ snapAdjust.bottom = 0;
+
+ if (wnd->getInterface(layoutGuid))
+ {
+ static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
+ if (wnd->getRenderRatio() != 1.0)
+ {
+ double rr = wnd->getRenderRatio();
+ snapAdjust.left = (int)((double)(snapAdjust.left) * rr);
+ snapAdjust.top = (int)((double)(snapAdjust.top) * rr);
+ snapAdjust.right = (int)((double)(snapAdjust.right) * rr);
+ snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr);
+ }
+ originalRect.left += snapAdjust.left;
+ originalRect.top += snapAdjust.top;
+ originalRect.right -= snapAdjust.right;
+ originalRect.bottom -= snapAdjust.bottom;
+ }
+
+ curRect = originalRect;
+ resizeWay = way;
+ resizedWindow = wnd->gethWnd();
+ resizedWindowR = wnd;
+
+ POINT pt;
+ Wasabi::Std::getMousePos(&pt);
+ cX = pt.x;
+ cY = pt.y;
+
+#ifdef WIN32
+ SetCapture(hWnd);
+#endif
+ SetTimer(hWnd, 1, 100, NULL); // this timer will make sure that we never get interlock
+
+ drawFrame();
+
+ MSG msg;
+ cancelit = 1;
+ while (GetCapture() == hWnd && GetMessage( &msg, hWnd, 0, 0 ))
+ {
+ TranslateMessage( &msg );
+#ifdef LINUX
+ if ( msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE )
+ wndProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
+ else
+#endif
+ DispatchMessage( &msg );
+ }
+
+ drawFrame();
+
+ // paintHookStop();
+
+ if (GetCapture() == hWnd) ReleaseCapture();
+ KillTimer(hWnd, 1);
+
+ if (!cancelit)
+ {
+ curRect.left -= snapAdjust.left;
+ curRect.top -= snapAdjust.top;
+ curRect.right += snapAdjust.right;
+ curRect.bottom += snapAdjust.bottom;
+ }
+ else
+ {
+ curRect = originalRect;
+ // evil, but less evil than InvalidateRect(NULL, NULL, FALSE);
+ EnumWindows(invalidateAll, 0);
+ }
+
+ return !cancelit;
+}
+
+
+//----------------------------------------------------------------------
+RECT resizeClass::getRect(void)
+{
+ return curRect;
+}
+
+//#define nifty
+
+//----------------------------------------------------------------------
+void resizeClass::drawFrame(void)
+{
+ RECT outRect;
+
+#ifdef WIN32
+ if (!dc)
+ {
+ dc = GetDC(NULL);
+ brush = CreateSolidBrush(0xFFFFFF);
+ pen = CreatePen(PS_SOLID, 0, 0xFFFFFF);
+ oldB = (HBRUSH)SelectObject(dc, brush);
+ oldP = (HPEN)SelectObject(dc, pen);
+ mix = SetROP2(dc, R2_XORPEN);
+ }
+
+ outRect = curRect;
+
+#ifndef nifty
+
+ DrawFocusRect(dc, &outRect);
+
+#else
+
+ RECT inRect;
+
+ inRect = outRect;
+ inRect.left += 10;
+ inRect.right -= 10;
+ inRect.top += 24;
+ inRect.bottom -= 10;
+
+ MoveToEx(dc, inRect.left, inRect.top, NULL);
+ LineTo(dc, inRect.right, inRect.top);
+ LineTo(dc, inRect.right, inRect.bottom);
+ LineTo(dc, inRect.left, inRect.bottom);
+ LineTo(dc, inRect.left, inRect.top);
+ MoveToEx(dc, outRect.left, 0, NULL);
+ LineTo(dc, outRect.left, screenHeight);
+ MoveToEx(dc, outRect.right, 0, NULL);
+ LineTo(dc, outRect.right, screenHeight);
+ MoveToEx(dc, 0, outRect.top, NULL);
+ LineTo(dc, screenWidth, outRect.top);
+ MoveToEx(dc, 0, outRect.bottom, NULL);
+ LineTo(dc, screenWidth, outRect.bottom);
+
+#endif
+#endif//WIN32
+#ifdef LINUX
+ outRect = curRect;
+
+ if ( ! dc )
+ {
+ dc = (HDC)MALLOC( sizeof( hdc_typ ) );
+ XGCValues gcv;
+ gcv.function = GXxor;
+ gcv.subwindow_mode = IncludeInferiors;
+ gcv.foreground = 0xffffff;
+ gcv.line_style = LineOnOffDash;
+ gcv.dashes = 1;
+ dc->gc = XCreateGC( Linux::getDisplay(), Linux::RootWin(), GCFunction | GCForeground | GCSubwindowMode, &gcv );
+ }
+
+ XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
+ outRect.left, outRect.top, outRect.right - outRect.left,
+ outRect.bottom - outRect.top );
+#endif
+ //PORTME
+}
+
+LRESULT resizeClass::wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_LBUTTONUP:
+ cancelit = 0;
+ ReleaseCapture();
+ return 0;
+
+ case WM_MOUSEMOVE:
+ {
+ POINT pt;
+ int iX, iY;
+ Wasabi::Std::getMousePos(&pt);
+ iX = pt.x - cX;
+ iY = pt.y - cY;
+ drawFrame();
+
+ if (resizeWay & TOP)
+ curRect.top = originalRect.top + iY;
+ if (resizeWay & BOTTOM)
+ curRect.bottom = originalRect.bottom + iY;
+ if (resizeWay & LEFT)
+ curRect.left = originalRect.left + iX;
+ if (resizeWay & RIGHT)
+ curRect.right = originalRect.right + iX;
+
+ if (abs((curRect.right - curRect.left) - sugWinWidth) < 10)
+ if (resizeWay & RIGHT)
+ curRect.right = curRect.left + sugWinWidth;
+ else if (resizeWay & LEFT)
+ curRect.left = curRect.right - sugWinWidth;
+
+ if (abs((curRect.bottom - curRect.top) - sugWinHeight) < 10)
+ if (resizeWay & BOTTOM)
+ curRect.bottom = curRect.top + sugWinHeight;
+ else if (resizeWay & TOP)
+ curRect.top = curRect.bottom - sugWinHeight;
+
+ curRect.left -= snapAdjust.left;
+ curRect.top -= snapAdjust.top;
+ curRect.right += snapAdjust.right;
+ curRect.bottom += snapAdjust.bottom;
+
+ windowTracker->autoDock(resizedWindowR, &curRect, resizeWay);
+
+ curRect.left += snapAdjust.left;
+ curRect.top += snapAdjust.top;
+ curRect.right -= snapAdjust.right;
+ curRect.bottom -= snapAdjust.bottom;
+
+ if ((curRect.right - curRect.left) < minWinWidth)
+ if (resizeWay & RIGHT)
+ curRect.right = curRect.left + minWinWidth;
+ else if (resizeWay & LEFT)
+ curRect.left = curRect.right - minWinWidth;
+
+ if ((curRect.bottom - curRect.top) < minWinHeight)
+ if (resizeWay & BOTTOM)
+ curRect.bottom = curRect.top + minWinHeight;
+ else if (resizeWay & TOP)
+ curRect.top = curRect.bottom - minWinHeight;
+
+ if (maxWinWidth != -1 && (curRect.right - curRect.left) > maxWinWidth)
+ if (resizeWay & RIGHT)
+ curRect.right = curRect.left + maxWinWidth;
+ else if (resizeWay & LEFT)
+ curRect.left = curRect.right - maxWinWidth;
+
+ if (maxWinHeight != -1 && (curRect.bottom - curRect.top) > maxWinHeight)
+ if (resizeWay & BOTTOM)
+ curRect.bottom = curRect.top + maxWinHeight;
+ else if (resizeWay & TOP)
+ curRect.top = curRect.bottom - maxWinHeight;
+
+ drawFrame();
+ }
+ return 0;
+ }
+#ifdef WIN32
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+#else
+ return 0;
+#endif
+}
+
+// Window Procedure
+//
+LRESULT CALLBACK resizeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+#ifdef WIN32
+ resizeClass *gThis = (resizeClass *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
+ if (!gThis)
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+ else
+ return gThis->wndProc(hwnd, uMsg, wParam, lParam);
+#else
+ return 0;
+#endif
+}
+
+void resizeClass::setResizeCursor(int action)
+{}
+
+
diff --git a/Src/Wasabi/api/wndmgr/resize.h b/Src/Wasabi/api/wndmgr/resize.h
new file mode 100644
index 00000000..2d67e14c
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/resize.h
@@ -0,0 +1,48 @@
+#ifndef __RESIZE_H
+#define __RESIZE_H
+#ifdef _WIN32
+LRESULT CALLBACK resizeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+
+class resizeClass
+{
+#ifdef _WIN32
+ friend LRESULT CALLBACK resizeWndProc(HWND wnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // heh, i really need this one ;)
+#endif
+private:
+ void drawFrame(void);
+ void setResizeCursor(int action);
+ int orientation(int a, int action);
+ OSWINDOWHANDLE hWnd;
+ OSWINDOWHANDLE resizedWindow;
+ ifc_window *resizedWindowR;
+ int resizeWay;
+ RECT curRect;
+ RECT originalRect;
+ int cX, cY;
+ int minWinWidth, minWinHeight;
+ int maxWinWidth, maxWinHeight;
+ int sugWinWidth, sugWinHeight;
+ int screenHeight, screenWidth;
+ bool cancelit;
+ RECT snapAdjust;
+
+#ifdef WIN32
+ HBRUSH oldB, brush;
+ HPEN oldP, pen;
+#endif
+ HDC dc;
+ int mix;
+
+public:
+ resizeClass(ifc_window *wnd, int minx, int miny, int maxx, int maxy, int sugx, int sugy);
+ ~resizeClass();
+ int resizeWindow(ifc_window *wnd, int way);
+#ifdef _WIN32
+ LRESULT wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+ RECT getRect(void);
+};
+
+#endif
+
diff --git a/Src/Wasabi/api/wndmgr/skinembed.cpp b/Src/Wasabi/api/wndmgr/skinembed.cpp
new file mode 100644
index 00000000..079bc688
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinembed.cpp
@@ -0,0 +1,733 @@
+#include <precomp.h>
+#include "skinembed.h"
+#include <api/wndmgr/layout.h>
+#include <api/wnd/wndclass/wndholder.h>
+#include <api/skin/skinparse.h>
+#include <api/wnd/wndtrack.h>
+#include <api/config/items/cfgitemi.h>
+#include <api/config/items/attrint.h>
+#include <bfc/named.h>
+#include <api/wndmgr/autopopup.h>
+#include <api/syscb/callbacks/wndcb.h>
+#include <api/wndmgr/skinwnd.h>
+#include <api/script/scriptmgr.h>
+#include <bfc/critsec.h>
+
+CriticalSection skinembed_cs;
+
+SkinEmbedder *skinEmbedder = NULL;
+
+SkinEmbedder::SkinEmbedder()
+{
+ ASSERTPR(skinEmbedder == NULL, "only one skin embedder please!");
+ skinEmbedder = this;
+}
+
+SkinEmbedder::~SkinEmbedder()
+{
+ inserted.deleteAll();
+ allofthem.deleteAll();
+}
+
+int SkinEmbedder::toggle(GUID g, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient)
+{
+ ifc_window *w = enumItem(g, 0);
+ if (w != NULL)
+ {
+ destroy(w, r);
+ return 0;
+ }
+ ifc_window *wnd = create(g, NULL, prefered_container, container_flag, r, transcient);
+ if (wnd == NULL)
+ {
+#ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
+ int y;
+ ON_CREATE_EXTERNAL_WINDOW_GUID(g, y);
+#endif
+
+ }
+ return 1;
+}
+
+int SkinEmbedder::toggle(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient)
+{
+ ifc_window *w = enumItem(groupid, 0);
+ if (w != NULL)
+ {
+ destroy(w, r);
+ return 0;
+ }
+ create(INVALID_GUID, groupid, prefered_container, container_flag, r, transcient);
+ return 1;
+}
+
+ifc_window *SkinEmbedder::create(GUID g, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient, int starthidden, int *isnew)
+{
+ return create(g, NULL, prefered_container, container_flag, r, transcient, starthidden, isnew);
+}
+
+ifc_window *SkinEmbedder::create(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient, int starthidden, int *isnew)
+{
+ return create(INVALID_GUID, groupid, prefered_container, container_flag, r, transcient, starthidden, isnew);
+}
+
+WindowHolder *SkinEmbedder::getSuitableWindowHolder(GUID g, const wchar_t *group_id, Container *cont, Layout *lay, int _visible, int _dynamic, int _empty, int _hasself, int _autoavail)
+{
+ foreach(wndholders)
+ WindowHolder *h = wndholders.getfor();
+
+ ifc_window *w = h->getRootWndPtr()->getDesktopParent();
+ int dyn = 1;
+ int visible = 0;
+ int hasself = 0;
+ int empty = 0;
+ int autoavail = h->wndholder_isAutoAvailable();
+
+ Layout *l = (NULL != w) ? static_cast<Layout *>(w->getInterface(layoutGuid)) : NULL;
+ Container *c = NULL;
+
+ if (l)
+ {
+ c = l->getParentContainer();
+ if (c)
+ {
+ dyn = c->isDynamic();
+ }
+ }
+
+ if (NULL == w || !w->isInited()) visible = -1;
+ else
+ {
+ if (_visible == 1)
+ {
+ if (h->getRootWndPtr()->isVisible()) visible = 1;
+ }
+ else if (_visible == 0)
+ {
+ if (w->isVisible()) visible = 1;
+ }
+ }
+ if (!h->getCurRootWnd()) empty = 1;
+
+ if (g != INVALID_GUID)
+ {
+ if (g == h->getCurGuid())
+ hasself = 1;
+ }
+ else if (group_id && h->getCurGroupId())
+ {
+ if (!WCSICMP(group_id, h->getCurGroupId()))
+ hasself = 1;
+ }
+
+ if (_visible != -1)
+ {
+ if (visible != _visible) continue;
+ }
+ if (_dynamic != -1)
+ {
+ if (_dynamic != dyn) continue;
+ }
+ if (_empty != -1)
+ {
+ if (empty != _empty) continue;
+ }
+ if (_hasself != -1)
+ {
+ if (hasself != _hasself) continue;
+ }
+ if (_autoavail != -1)
+ {
+ if (autoavail != _autoavail) continue;
+ }
+
+ if (cont != NULL)
+ {
+ if (c != cont) continue;
+ }
+
+ if (lay != NULL)
+ {
+ if (l != lay) continue;
+ }
+
+ if (g != INVALID_GUID)
+ {
+ if (h->wantGuid(g)) return h;
+ }
+ else if (group_id)
+ {
+ if (h->wantGroup(group_id)) return h;
+ }
+ endfor;
+
+ return NULL;
+}
+
+ifc_window *SkinEmbedder::create(GUID g, const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *r, int transcient, int starthidden, int *isnew)
+{
+ // InCriticalSection in_cs(&skinembed_cs);
+
+ foreach(in_deferred_callback)
+ SkinEmbedEntry *e = in_deferred_callback.getfor();
+ if ((e->guid != INVALID_GUID && e->guid == g) || WCSCASEEQLSAFE(groupid, e->groupid))
+ {
+#ifdef _DEBUG
+ DebugStringW(L"trying to show a window that is being destroyed, hm, try again later\n");
+#endif
+ // too soon! try later dude
+ return NULL;
+ }
+ endfor;
+
+ RECT destrect = {0};
+
+ if (isnew) *isnew = 0;
+
+ WindowHolder *wh = NULL;
+ // todo: get from c++ callback
+
+ if (SOM::checkAbortShowHideWindow(g, 1))
+ return NULL;
+
+ if (g != INVALID_GUID)
+ wh = SOM::getSuitableWindowHolderFromScript(g);
+
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 1 /*visible*/, 0 /*static*/, 1 /*empty*/, -1 /*donttest*/, -1 /*donttest*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 0 /*hidden*/, 0 /*static*/, 0 /*notempty*/, 1 /*hasself*/, -1 /*donttest*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 0 /*hidden*/, 0 /*static*/, 1 /*empty*/, -1 /*donttest*/, 1 /*autoavail*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, NULL, NULL, 1 /*visible*/, 1 /*dynamic*/, 1 /*empty*/, -1 /*donttest*/, -1 /*donttest*/);
+ ifc_window *whrw = wh ? wh->getRootWndPtr() : NULL;
+ Container *cont = NULL;
+ Layout *lay = NULL;
+ ifc_window *wnd = NULL;
+ int newcont = 0;
+
+ if (!wh)
+ { // no hidden static container, so lets create a dynamic one
+ if (isnew) *isnew = 1;
+ if (container_flag == 0 && (prefered_container == NULL || !*prefered_container))
+ {
+ prefered_container = AutoPopup::getDefaultContainerParams(groupid, g, &container_flag);
+ }
+ if (container_flag == 0 && (prefered_container == NULL || !*prefered_container))
+ {
+ prefered_container = WASABI_DEFAULT_STDCONTAINER;
+ }
+ cont = SkinParser::loadContainerForWindowHolder(groupid, g, 0, transcient, prefered_container, container_flag);
+ if (cont)
+ {
+ cont->setTranscient(transcient);
+ newcont = 1;
+ lay = cont->enumLayout(0);
+ /* if (prefered_layout) { // find its target layout
+ cont->setDefaultLayout(prefered_layout);
+ lay = cont->getLayout(prefered_layout);
+ if (!lay) {
+ if (!layout_flag) // see if we can fallback
+ lay = cont->enumLayout(0);
+ else {
+ destroyContainer(cont); // deferred
+ api->console_outputString(9, StringPrintf("could not find the requested layout (%s) to host the window", prefered_container));
+ return NULL;
+ }
+ }*/
+ }
+ else
+ {
+ DebugStringW(L"no container found to hold the window... not even a default one :/\n");
+ }
+ wh = getSuitableWindowHolder(g, groupid, cont, lay, -1 /*donttest*/, -1 /*donttest*/, 0 /*notempty*/, 1 /*hasself*/, -1 /*donttest*/);
+ if (!wh) wh = getSuitableWindowHolder(g, groupid, cont, lay, -1 /*donttest*/, -1 /*donttest*/, 1 /*empty*/, -1 /*donttest*/, -1 /*donttest*/);
+ whrw = wh ? wh->getRootWndPtr() : NULL;
+ }
+
+ if (wh)
+ {
+ GuiObject *o = static_cast<GuiObject *>(whrw->getInterface(guiObjectGuid));
+ ASSERT(o != NULL);
+ if (o)
+ {
+ lay = o->guiobject_getParentLayout();
+ if (lay)
+ cont = lay->getParentContainer();
+ }
+ if ((g != INVALID_GUID && (g == wh->getCurGuid())) || (groupid && (wh->getCurGroupId() == groupid)))
+ wnd = wh->getCurRootWnd();
+ else
+ {
+ if (wh->getCurRootWnd())
+ wh->onRemoveWindow();
+ wnd = wh->onInsertWindow(g, groupid);
+ }
+ }
+
+ if (!wnd)
+ {
+ if (cont)
+ {
+ if (!WCSCASEEQLSAFE(cont->getId(), L"main"))
+ cont->close();
+ }
+ return NULL;
+ }
+
+ //int anim = 1;
+ //if (wh && !whrw->getAnimatedRects()) anim = 0; // FIXME!!
+
+ if (lay && r)
+ {
+ lay->getWindowRect(&destrect);
+ }
+
+ if (cont /*&& cont->isDynamic()*/)
+ {
+ const wchar_t *text = wnd->getRootWndName();
+ cont->setTranscient(transcient);
+ if (text != NULL)
+ if (cont->isDynamic()) cont->setName(text);
+ if (cont->isDynamic() && !transcient) cont->resetLayouts();
+ if (newcont) cont->onInit(1);
+ }
+
+#ifdef WASABI_COMPILE_CONFIG
+ // {280876CF-48C0-40bc-8E86-73CE6BB462E5}
+ const GUID options_guid =
+ { 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } };
+ CfgItem *cfgitem = WASABI_API_CONFIG->config_getCfgItemByGuid(options_guid);
+ int findopenrect = _int_getValue(cfgitem, L"Find open rect");
+#else
+ int findopenrect = WASABI_WNDMGR_FINDOPENRECT;
+#endif
+
+ if (wh && findopenrect)
+ {
+ if (lay)
+ {
+ RECT rl;
+ lay->getWindowRect(&rl);
+ RECT nr = windowTracker->findOpenRect(rl, lay);
+ destrect = nr; // rewrite destrect
+ int w = rl.right - rl.left;
+ int h = rl.bottom - rl.top;
+ lay->divRatio(&w, &h);
+ nr.right = nr.left + w;
+ nr.bottom = nr.top + h;
+ lay->resizeToRect(&nr);
+ }
+ }
+
+ if (wh)
+ {
+ if (r)
+ /*if (anim)*/ WASABI_API_WNDMGR->drawAnimatedRects(r, &destrect);
+ /*else
+ {
+ RECT r;
+ r.left = destrect.left + (destrect.right - destrect.left) / 2 - 1;
+ r.top = destrect.top + (destrect.bottom - destrect.top) / 2 + 1;
+ r.right = r.left + 2;
+ r.bottom = r.top + 2;
+ if (anim) WASABI_API_WNDMGR->drawAnimatedRects(&r, &destrect);
+ }*/
+ }
+
+ if (!starthidden)
+ {
+ if (cont && cont->isVisible())
+ { // we were already shown, duh
+ // cont->setVisible(0);
+ }
+ else
+ {
+ if (cont) cont->setVisible(1);
+ else if (lay) lay->setVisible(1);
+ }
+ }
+
+ if (wnd && newcont && !transcient)
+ {
+ inserted.addItem(new SkinEmbedEntry(wnd->getDependencyPtr(), wnd, g, groupid, prefered_container, container_flag, cont, wh));
+ viewer_addViewItem(wnd->getDependencyPtr());
+ }
+
+ if (!transcient && wnd)
+ allofthem.addItem(new SkinEmbedEntry(wnd->getDependencyPtr(), wnd, g, groupid, prefered_container, container_flag, cont, wh));
+
+ return wnd;
+}
+
+void SkinEmbedder::destroy(ifc_window *w, RECT *r)
+{
+ int donecheck = 0;
+ SkinEmbedEntry *e = NULL;
+ for (int i = 0; i < allofthem.getNumItems();i++)
+ {
+ e = allofthem.enumItem(i);
+ if (e->wnd == w)
+ {
+ donecheck = 1;
+ if (SOM::checkAbortShowHideWindow(e->guid, 0))
+ return ;
+ break;
+ }
+ }
+ if (WASABI_API_WND->rootwndIsValid(w))
+ {
+ if (!donecheck)
+ {
+ ifc_window *ww = w->findWindowByInterface(windowHolderGuid);
+ if (ww)
+ {
+ WindowHolder *wh = static_cast<WindowHolder*>(ww->getInterface(windowHolderGuid));
+ if (wh)
+ {
+ GUID g = wh->getCurGuid();
+ if (g != INVALID_GUID)
+ {
+ donecheck = 1;
+ if (SOM::checkAbortShowHideWindow(g, 0))
+ return ;
+ }
+ }
+ }
+ }
+ }
+ // checkAbort can render w invalid !!! check again
+ if (WASABI_API_WND->rootwndIsValid(w))
+ {
+ ifc_window *wnd = w->getDesktopParent();
+ GuiObject *go = static_cast<GuiObject *>(wnd->getInterface(guiObjectGuid));
+ if (go)
+ {
+ Layout *l = go->guiobject_getParentLayout();
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ if (!WCSCASEEQLSAFE(c->getId(), L"main"))
+ {
+ c->close(); // deferred if needed
+ }
+ else
+ {
+ softclose:
+ ifc_window *wnd = w->findWindowByInterface(windowHolderGuid);
+ if (wnd != NULL)
+ {
+ WindowHolder *wh = static_cast<WindowHolder *>(wnd->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow(1);
+ }
+ }
+ }
+ }
+ else goto softclose;
+ }
+ }
+ }
+}
+
+int SkinEmbedder::getNumItems(GUID g)
+{
+ int n = 0;
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ if (wndholders.enumItem(i)->getRootWndPtr()->isVisible() && wndholders.enumItem(i)->getCurGuid() == g) n++;
+ return n;
+}
+
+int SkinEmbedder::getNumItems(const wchar_t *groupid)
+{
+ int n = 0;
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ {
+ WindowHolder *wh = wndholders.enumItem(i);
+ if (wh->getRootWndPtr()->isVisible()
+ && WCSCASEEQLSAFE(wh->getCurGroupId(), groupid))
+ n++;
+ }
+ return n;
+}
+
+ifc_window *SkinEmbedder::enumItem(GUID g, int n)
+{
+ ASSERT(n >= 0);
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ {
+ WindowHolder *wh = wndholders.enumItem(i);
+ if (wh->getCurGuid() == g)
+ {
+ ifc_window *w = wh->getRootWndPtr();
+ Container *c = NULL;
+ if (w)
+ {
+ w = w->getDesktopParent();
+ if (w)
+ {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ c = l->getParentContainer();
+ }
+ }
+ }
+ if (c && c->isVisible() || (!c && wndholders.enumItem(i)->getRootWndPtr()->isVisible()))
+ {
+ if (n == 0)
+ return wndholders.enumItem(i)->getCurRootWnd();
+ n--;
+ }
+ }
+ }
+ return NULL;
+}
+
+ifc_window *SkinEmbedder::enumItem(const wchar_t *groupid, int n)
+{
+ ASSERT(n >= 0);
+ for (int i = 0;i < wndholders.getNumItems();i++)
+ {
+ WindowHolder *wh = wndholders.enumItem(i);
+ const wchar_t *curgroupid = wndholders[i]->getCurGroupId();
+ if (WCSCASEEQLSAFE(curgroupid, groupid))
+ {
+ ifc_window *w = wh->getRootWndPtr();
+ Container *c = NULL;
+ if (w)
+ {
+ w = w->getDesktopParent();
+ if (w)
+ {
+ Layout *l = static_cast<Layout *>(w->getInterface(layoutGuid));
+ if (l)
+ {
+ c = l->getParentContainer();
+ }
+ }
+ }
+ if (c && c->isVisible() || (!c && wndholders.enumItem(i)->getRootWndPtr()->isVisible()))
+ {
+ if (n == 0)
+ return wndholders.enumItem(i)->getCurRootWnd();
+ n--;
+ }
+ }
+ }
+ return NULL;
+}
+
+void SkinEmbedder::registerWindowHolder(WindowHolder *wh)
+{
+ if (wndholders.haveItem(wh)) return ;
+ wndholders.addItem(wh);
+}
+
+void SkinEmbedder::unregisterWindowHolder(WindowHolder *wh)
+{
+ if (!wndholders.haveItem(wh)) return ;
+ wndholders.removeItem(wh);
+}
+
+int SkinEmbedder::viewer_onItemDeleted(api_dependent *item)
+{
+ foreach(in_deferred_callback)
+ if (in_deferred_callback.getfor()->dep == item)
+ in_deferred_callback.removeByPos(foreach_index);
+ endfor
+ foreach(inserted)
+ SkinEmbedEntry *e = inserted.getfor();
+ if (e->dep == item)
+ {
+ inserted.removeItem(e);
+ allofthem.removeItem(e);
+ delete e;
+ break;
+ }
+ endfor;
+ foreach(allofthem)
+ SkinEmbedEntry *e = allofthem.getfor();
+ if (e->dep == item)
+ {
+ allofthem.removeItem(e);
+ delete e;
+ break;
+ }
+ endfor;
+ return 1;
+}
+
+void SkinEmbedder::cancelDestroyContainer(Container *c)
+{
+ if (!cancel_deferred_destroy.haveItem(c)) cancel_deferred_destroy.addItem(c);
+}
+
+void SkinEmbedder::destroyContainer(Container *o)
+{
+ ASSERT(o);
+ //fg>disabled as of 11/4/2003, side effect of cancelling fullscreen video (ie, notifier while playing video fullscreen)
+ //delt with the problem in basewnd directly
+ //#ifdef WIN32
+ //SetFocus(NULL); // FG> this avoids Win32 calling directly WM_KILLFOCUS into a child's wndproc (couldn't they just have posted the damn msg ?), who would then call some of his parent's virtual functions while it is being deleted
+ // perhaps it would be good to add a generic way to disable most child wnd messages while the parent is being deleted
+ //#endif
+
+ cancel_deferred_destroy.removeItem(o);
+
+ foreach(inserted)
+ SkinEmbedEntry *e = inserted.getfor();
+ if (e->container == o)
+ {
+ if (!in_deferred_callback.haveItem(e))
+ in_deferred_callback.addItem(e);
+
+ break;
+ }
+ endfor
+ deferred_destroy.addItem(o);
+ timerclient_setTimer(CB_DESTROYCONTAINER, 20);
+ //o->setVisible(0);
+ //timerclient_postDeferredCallback(CB_DESTROYCONTAINER, (intptr_t)o);
+}
+
+void SkinEmbedder::timerclient_timerCallback(int id)
+{
+ if (id == CB_DESTROYCONTAINER)
+ {
+ foreach(deferred_destroy)
+ Container *c = deferred_destroy.getfor();
+ foreach(in_deferred_callback)
+ if (in_deferred_callback.getfor()->container == c)
+ {
+ in_deferred_callback.removeByPos(foreach_index);
+ }
+ endfor;
+ if (cancel_deferred_destroy.haveItem(c))
+ {
+ continue;
+ }
+ if (SkinParser::isContainer(c)) // otherwise i'ts already gone while we were waiting for the callback, duh!
+ delete c;
+ endfor
+ cancel_deferred_destroy.removeAll();
+ deferred_destroy.removeAll();
+ timerclient_killTimer(CB_DESTROYCONTAINER);
+ return ;
+ }
+ TimerClientDI::timerclient_timerCallback(id);
+}
+
+int SkinEmbedder::timerclient_onDeferredCallback(intptr_t p1, intptr_t p2)
+{
+ return TimerClientDI::timerclient_onDeferredCallback(p1, p2);
+}
+
+#ifdef WASABI_COMPILE_CONFIG
+void SkinEmbedder::saveState()
+{
+ int i = 0;
+ wchar_t t[1024] = {0};
+ foreach(inserted)
+ SkinEmbedEntry *e = inserted.getfor();
+ if (e->guid != INVALID_GUID)
+ {
+ nsGUID::toCharW(e->guid, t);
+ }
+ else
+ {
+ WCSCPYN(t, e->groupid, 1024);
+ }
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/id/%d", i), t);
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/layout/%d", i), !e->layout.isempty() ? e->layout.getValue() : L"");
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"wndstatus/flag/%d", i), e->required);
+ i++;
+ endfor;
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/id/%d", i), L"");
+ WASABI_API_CONFIG->setStringPrivate(StringPrintfW(L"wndstatus/layout/%d", i), L"");
+ WASABI_API_CONFIG->setIntPrivate(StringPrintfW(L"wndstatus/flag/%d", i), 0);
+}
+
+void SkinEmbedder::restoreSavedState()
+{
+ int i = 0;
+ wchar_t t[1024] = {0};
+ wchar_t l[256] = {0};
+ while (1)
+ {
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"wndstatus/id/%d", i), t, 1024, L"");
+ if (!*t) break;
+ WASABI_API_CONFIG->getStringPrivate(StringPrintfW(L"wndstatus/layout/%d", i), l, 256, L"");
+ int flag = WASABI_API_CONFIG->getIntPrivate(StringPrintfW(L"wndstatus/flag/%d", i), 0);
+ GUID g = nsGUID::fromCharW(t);
+ //ifc_window *created = NULL;
+ //int tried = 0;
+ if (g != INVALID_GUID)
+ {
+ ifc_window *w = enumItem(g, 0);
+ if (w == NULL)
+ {
+ //tried = 1;
+ /*created = */create(g, l, flag);
+ }
+ }
+ else
+ {
+ ifc_window *w = enumItem(t, 0);
+ if (w == NULL)
+ {
+ //tried = 1;
+ /*created = */create(t, l, flag);
+ }
+ }
+ /* if (tried && !created) {
+ for (int j=0;j<inserted.getNumItems();j++) {
+ SkinEmbedEntry *e = inserted.enumItem(j);
+ int yes = 0;
+ if (g != INVALID_GUID) {
+ if (e->guid == g && e->required == flag && STRCASEEQLSAFE(e->layout, l))
+ yes = 1;
+ } else {
+ if (STRCASEEQLSAFE(e->groupid, t) && e->required == flag && STRCASEEQLSAFE(e->layout, l))
+ yes = 1;
+ }
+ if (yes) {
+ inserted.removeByPos(j);
+ j--;
+ delete e;
+ }
+ }
+ }*/
+ i++;
+ }
+}
+#endif
+
+void SkinEmbedder::attachToSkin(ifc_window *w, int side, int size)
+{
+ RECT r;
+ if (w == NULL) return ;
+ ifc_window *_w = w->getDesktopParent();
+ if (_w == NULL) _w = w;
+ SkinParser::getSkinRect(&r, _w);
+
+ switch (side)
+ {
+ case SKINWND_ATTACH_RIGHT:
+ _w->resize(r.right, r.top, size, r.bottom - r.top);
+ break;
+ case SKINWND_ATTACH_TOP:
+ _w->resize(r.left, r.top - size, r.right - r.left, size);
+ break;
+ case SKINWND_ATTACH_LEFT:
+ _w->resize(r.left - size, r.top, size, r.bottom - r.top);
+ break;
+ case SKINWND_ATTACH_BOTTOM:
+ _w->resize(r.left, r.bottom, r.right - r.left, size);
+ break;
+ }
+}
+
+PtrList<SkinEmbedEntry> SkinEmbedder::in_deferred_callback;
+PtrList<Container> SkinEmbedder::cancel_deferred_destroy;
+PtrList<Container> SkinEmbedder::deferred_destroy;
diff --git a/Src/Wasabi/api/wndmgr/skinembed.h b/Src/Wasabi/api/wndmgr/skinembed.h
new file mode 100644
index 00000000..e33630ab
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinembed.h
@@ -0,0 +1,76 @@
+#ifndef __SKIN_EMBEDDER_H
+#define __SKIN_EMBEDDER_H
+
+#include <bfc/nsguid.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/string/StringW.h>
+#include <bfc/ptrlist.h>
+#include <bfc/depend.h>
+#include <api/timer/timerclient.h>
+
+#define CB_DESTROYCONTAINER 0x887
+
+class ifc_window;
+class WindowHolder;
+class Container;
+class Layout;
+
+class SkinEmbedEntry {
+ public:
+ SkinEmbedEntry(api_dependent *d, ifc_window *w, GUID g, const wchar_t *gid, const wchar_t *prefered_container, int container_flag, Container *c, WindowHolder *wh) : groupid(gid), guid(g), dep(d), wnd(w), required(container_flag), layout(prefered_container), container(c), wndholder(wh) { }
+ virtual ~SkinEmbedEntry() { }
+
+ StringW groupid;
+ GUID guid;
+ api_dependent *dep;
+ ifc_window *wnd;
+ int required;
+ StringW layout;
+ Container *container;
+ WindowHolder *wndholder;
+};
+
+class SkinEmbedder : public DependentViewerI, public TimerClientDI {
+ public:
+
+ SkinEmbedder();
+ virtual ~SkinEmbedder();
+
+ int toggle(GUID g, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0);
+ int toggle(const wchar_t *groupid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0);
+ ifc_window *create(GUID g, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0, int starthidden=0, int *isnew=NULL);
+ ifc_window *create(const wchar_t *groupid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0, int starthidden=0, int *isnew=NULL);
+ void destroy(ifc_window *w, RECT *r=NULL);
+ int getNumItems(GUID g);
+ int getNumItems(const wchar_t *groupid);
+ ifc_window *enumItem(GUID g, int n);
+ ifc_window *enumItem(const wchar_t *groupid, int n);
+ WindowHolder *getSuitableWindowHolder(GUID g, const wchar_t *group_id, Container *cont, Layout *lay, int visible, int dynamic, int empty, int has_self, int autoavail);
+ void registerWindowHolder(WindowHolder *w);
+ void unregisterWindowHolder(WindowHolder *w);
+ void destroyContainer(Container *o);
+ virtual int timerclient_onDeferredCallback(intptr_t param1, intptr_t param2);
+ virtual void timerclient_timerCallback(int id);
+#ifdef WASABI_COMPILE_CONFIG
+ void restoreSavedState();
+ void saveState();
+#endif
+ void attachToSkin(ifc_window *w, int side, int size);
+
+ virtual int viewer_onItemDeleted(api_dependent *item);
+ static void cancelDestroyContainer(Container *c);
+
+ private:
+ ifc_window *create(GUID g, const wchar_t *groupid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *r=NULL, int transcient=0, int starthidden=0, int *isnew=NULL);
+
+ PtrList<WindowHolder> wndholders;
+ PtrList<SkinEmbedEntry> inserted;
+ PtrList<SkinEmbedEntry> allofthem;
+ static PtrList<SkinEmbedEntry> in_deferred_callback;
+ static PtrList<Container> cancel_deferred_destroy;
+ static PtrList<Container> deferred_destroy;
+};
+
+extern SkinEmbedder *skinEmbedder;
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/skinwnd.cpp b/Src/Wasabi/api/wndmgr/skinwnd.cpp
new file mode 100644
index 00000000..5ac895a0
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinwnd.cpp
@@ -0,0 +1,99 @@
+#include <precomp.h>
+#include "skinwnd.h"
+#include <api/wnd/api_window.h>
+#include <api/wnd/wndclass/guiobjwnd.h>
+#include <api/script/scriptguid.h>
+#include <api/script/objects/c_script/c_group.h>
+#include <api/script/objects/c_script/c_layout.h>
+#include <api/script/objects/c_script/c_container.h>
+#include <api/wnd/wndclass/wndholder.h>
+
+SkinWnd::SkinWnd(const wchar_t *group_id, const wchar_t *prefered_container, int container_flag, RECT *animated_rect_source, int transcient, int starthidden)
+{
+ isnew = 0;
+ wnd = WASABI_API_WNDMGR->skinwnd_createByGroupId(group_id, prefered_container, container_flag, animated_rect_source, transcient, starthidden, &isnew);
+ notifyMinMaxChanged();
+}
+
+SkinWnd::SkinWnd(GUID svc_or_group_guid, const wchar_t *prefered_container, int container_flag, RECT *animated_rect_source, int transcient, int starthidden)
+{
+ isnew = 0;
+ wnd = WASABI_API_WNDMGR->skinwnd_createByGuid(svc_or_group_guid, prefered_container, container_flag, animated_rect_source, transcient, starthidden, &isnew);
+ notifyMinMaxChanged();
+}
+
+SkinWnd::~SkinWnd()
+{}
+
+void SkinWnd::destroy(RECT *animated_rect_dest)
+{
+ if (wnd == NULL) return ;
+ if (!isnew)
+ {
+ ifc_window *w = wnd->findWindowByInterface(windowHolderGuid);
+ WindowHolder *wh = static_cast<WindowHolder*>(w->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow();
+ return ;
+ }
+ }
+ WASABI_API_WNDMGR->skinwnd_destroy(wnd, animated_rect_dest);
+}
+
+int SkinWnd::runModal(int center)
+{
+ if (wnd == NULL) return 0;
+ ifc_window *w = wnd->getDesktopParent();
+ if (center)
+ {
+ C_Layout l(getLayout());
+ l.center();
+ }
+ w->setVisible(1);
+ return w->runModal();
+}
+
+void SkinWnd::endModal(int retcode)
+{
+ if (wnd == NULL) return ;
+ wnd->endModal(retcode);
+}
+
+GuiObject *SkinWnd::findObject(const wchar_t *object_id)
+{
+ if (wnd == NULL) return NULL;
+ GuiObject *obj = NULL;
+ obj = static_cast<GuiObject *>(wnd->getInterface(guiObjectGuid));
+ return obj->guiobject_findObject(object_id);
+}
+
+ScriptObject *SkinWnd::getContainer()
+{
+ if (wnd == NULL) return NULL;
+ ifc_window *dw = wnd->getDesktopParent();
+ if (!dw) return NULL;
+ ScriptObject *o = static_cast<ScriptObject *>(dw->getInterface(scriptObjectGuid));
+ if (o != NULL)
+ {
+ return C_Layout(o).getContainer();
+ }
+ return NULL;
+}
+
+ScriptObject *SkinWnd::getLayout()
+{
+ if (wnd == NULL) return NULL;
+ ifc_window *dw = wnd->getDesktopParent();
+ if (!dw) return NULL;
+ ScriptObject *o = static_cast<ScriptObject *>(dw->getInterface(scriptObjectGuid));
+ return o;
+}
+
+void SkinWnd::notifyMinMaxChanged()
+{
+ if (wnd != NULL)
+ {
+ wnd->signalMinMaxEnforcerChanged();
+ }
+}
diff --git a/Src/Wasabi/api/wndmgr/skinwnd.h b/Src/Wasabi/api/wndmgr/skinwnd.h
new file mode 100644
index 00000000..e372fb56
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/skinwnd.h
@@ -0,0 +1,42 @@
+#ifndef __SKINWND_H
+#define __SKINWND_H
+
+#include <bfc/common.h>
+#include "api.h"
+#include <api/script/scriptobj.h>
+
+#define WASABISTDCONTAINER_RESIZABLE_STATUS "resizable_status"
+#define WASABISTDCONTAINER_RESIZABLE_NOSTATUS "resizable_nostatus"
+#define WASABISTDCONTAINER_STATIC "static"
+#define WASABISTDCONTAINER_MODAL "modal"
+
+#define SKINWND_ATTACH_LEFT 1
+#define SKINWND_ATTACH_TOP 2
+#define SKINWND_ATTACH_RIGHT 3
+#define SKINWND_ATTACH_BOTTOM 4
+
+class ifc_window;
+class GuiObject;
+
+class SkinWnd
+{
+ public:
+ SkinWnd(GUID svc_or_group_guid, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *animated_rect_source=NULL, int transcient=0, int starthidden=0);
+ SkinWnd(const wchar_t *group_id, const wchar_t *prefered_container=NULL, int container_flag=0, RECT *animated_rect_source=NULL, int transcient=0, int starthidden=0);
+ virtual ~SkinWnd();
+ void destroy(RECT *animated_rect_dest=NULL);
+ ifc_window *getWindow() { return wnd; }
+ ScriptObject *getContainer();
+ ScriptObject *getLayout();
+ int runModal(int center=0);
+ void endModal(int retcode);
+ GuiObject *findObject(const wchar_t *object_id);
+ void notifyMinMaxChanged();
+ int isNewContainer() { return isnew; }
+
+ private:
+ ifc_window *wnd;
+ int isnew;
+};
+
+#endif
diff --git a/Src/Wasabi/api/wndmgr/snappnt.cpp b/Src/Wasabi/api/wndmgr/snappnt.cpp
new file mode 100644
index 00000000..93ad3df9
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/snappnt.cpp
@@ -0,0 +1,181 @@
+#include <precomp.h>
+#include "snappnt.h"
+#include <api/wndmgr/layout.h>
+#include <api/wnd/wndtrack.h>
+#include <api/config/items/cfgitem.h>
+
+SnapPoint::SnapPoint(Layout *l, Container *c)
+{
+ points.addItem(this);
+ setParentLayout(l);
+ setParentContainer(c);
+}
+
+SnapPoint::~SnapPoint()
+{
+ points.removeItem(this);
+}
+
+void SnapPoint::removeAll()
+{
+ points.deleteAllSafe();
+}
+
+int SnapPoint::setXmlParam(const wchar_t *paramname, const wchar_t *strvalue)
+{
+ if (!WCSICMP(paramname, L"id")) id = strvalue;
+ else if (!WCSICMP(paramname, L"x")) x = WTOI(strvalue);
+ else if (!WCSICMP(paramname, L"y")) y = WTOI(strvalue);
+ else if (!WCSICMP(paramname, L"relatx")) relatx = WTOI(strvalue);
+ else if (!WCSICMP(paramname, L"relaty")) relaty = WTOI(strvalue);
+ else return 0;
+ return 1;
+}
+
+void SnapPoint::setParentLayout(Layout *l)
+{
+ playout = l;
+}
+
+void SnapPoint::setParentContainer(Container *c)
+{
+ pcontainer = c;
+}
+
+Container *SnapPoint::getParentContainer()
+{
+ return pcontainer;
+}
+
+Layout *SnapPoint::getParentLayout()
+{
+ return playout;
+}
+
+const wchar_t *SnapPoint::getId()
+{
+ return id;
+}
+
+int SnapPoint::getX()
+{
+ if (getParentLayout())
+ return (int)((double)x * getParentLayout()->getRenderRatio());
+ return x;
+}
+
+int SnapPoint::getY()
+{
+ if (getParentLayout())
+ return (int)((double)y * getParentLayout()->getRenderRatio());
+ return y;
+}
+
+PtrList<SnapPoint> SnapPoint::points;
+
+int SnapPoint::match(ifc_window *master, RECT *z, ifc_window *slave, int flag, int *donex, int *doney, int w, int h)
+{
+ SnapPoint *pmast;
+ SnapPoint *pslav;
+
+ for (int i = 0;i < points.getNumItems();i++)
+ if (points.enumItem(i)->getParentLayout() == master)
+ {
+ pmast = points.enumItem(i);
+ for (int j = 0;j < points.getNumItems();j++)
+ if (points.enumItem(j)->getParentLayout() == slave)
+ {
+ pslav = points.enumItem(j);
+ int r = do_match(pmast, pslav, z, flag, donex, doney, w, h);
+ if (r)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int SnapPoint::do_match(SnapPoint *pmast, SnapPoint *pslav, RECT *z, int mask, int *donex, int *doney, int w, int h)
+{
+ //#if 0//BU> lone needs to make this work again
+ //fg> maybe it would have been a good idea to tell me about it... especially since it *works fine*
+
+ ASSERT(pmast);
+ ASSERT(pslav);
+ int f = 0;
+
+ if (((mask & KEEPSIZE) == 0) && !z)
+ {
+ ASSERTPR(0, "match resize with no rect");
+ }
+
+ if (!z)
+ { // just testing if docked
+
+ if (!WCSICMP(pmast->getId(), pslav->getId()))
+ {
+ BaseWnd *wm = pmast->getParentLayout();
+ BaseWnd *ws = pslav->getParentLayout();
+ if (ws && ws)
+ {
+ RECT pmr, psr;
+ wm->getWindowRect(&pmr);
+ ws->getWindowRect(&psr);
+ pmr.left += pmast->relatx ? pmast->getX() : (pmr.right - pmr.left + pmast->getX());
+ pmr.top += pmast->relaty ? pmast->getY() : (pmr.bottom - pmr.top + pmast->getY());
+ psr.left += pmast->relatx ? pslav->getX() : (psr.right - psr.left + pslav->getX());
+ psr.top += pmast->relaty ? pslav->getY() : (psr.bottom - psr.top + pslav->getY());
+ if (pmr.left == psr.left && pmr.top == psr.top)
+ {
+ if (donex) *donex = 1;
+ if (doney) *doney = 1;
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+
+ ASSERT(donex);
+ ASSERT(doney);
+
+ if (!WCSICMP(pmast->getId(), pslav->getId()))
+ {
+ //CUT: BaseWnd *wm = pmast->getParentLayout();
+ BaseWnd *ws = pslav->getParentLayout();
+ if (ws && ws)
+ {
+ RECT pmr, psr, osr, omr;
+ pmr = omr = *z;
+ ws->getWindowRect(&psr);
+ osr = psr;
+ pmr.left += pmast->relatx ? pmast->getX() : (pmr.right - pmr.left + pmast->getX());
+ pmr.top += pmast->relaty ? pmast->getY() : (pmr.bottom - pmr.top + pmast->getY());
+ psr.left += pmast->relatx ? pslav->getX() : (psr.right - psr.left + pslav->getX());
+ psr.top += pmast->relaty ? pslav->getY() : (psr.bottom - psr.top + pslav->getY());
+ if (pmr.left > psr.left - 10 && pmr.left < psr.left + 10 && (mask & LEFT) && ! *donex)
+ {
+ *donex = 1;
+ z->left = omr.left - (pmr.left - psr.left);
+ if (mask & KEEPSIZE)
+ z->right = z->left + w;
+ f++;
+ }
+ if (pmr.top > psr.top - 10 && pmr.top < psr.top + 10 && (mask & TOP) && ! *doney)
+ {
+ z->top = omr.top - (pmr.top - psr.top);
+ *doney = 1;
+ if (mask & KEEPSIZE)
+ z->bottom = z->top + h;
+ f++;
+ }
+ }
+ }
+
+ return f > 0;
+ }
+ return 0;
+}
+
+
+
diff --git a/Src/Wasabi/api/wndmgr/snappnt.h b/Src/Wasabi/api/wndmgr/snappnt.h
new file mode 100644
index 00000000..997e8fd7
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/snappnt.h
@@ -0,0 +1,49 @@
+#ifndef __SNAPPOINT_H
+#define __SNAPPOINT_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+#include <api/skin/xmlobject.h>
+
+#define SNAPPOINT_XMLPARENT XmlObjectI
+
+class Container;
+class Layout;
+class SnapPoint;
+class ifc_window;
+
+class SnapPoint : public SNAPPOINT_XMLPARENT {
+
+public:
+ SnapPoint(Layout *l, Container *c);
+ virtual ~SnapPoint();
+
+ virtual int setXmlParam(const wchar_t *name, const wchar_t *strvalue);
+
+ virtual void setParentContainer(Container *c);
+ virtual void setParentLayout(Layout *l);
+ virtual Container *getParentContainer();
+ virtual Layout *getParentLayout();
+ virtual const wchar_t *getId();
+
+ virtual int getX();
+ virtual int getY();
+
+ static int match(ifc_window *master, RECT *z, ifc_window *slave, int flag, int *donex, int *doney, int w, int h);
+ static void removeAll();
+
+private:
+ int x;
+ int y;
+ int relatx;
+ int relaty;
+ StringW id;
+
+ Container *pcontainer;
+ Layout *playout;
+
+ static PtrList<SnapPoint> points;
+ static int do_match(SnapPoint *pmast, SnapPoint *pslav, RECT *z, int mask, int *donex, int *doney, int w, int h);
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/wndmgr/wndmgrapi.cpp b/Src/Wasabi/api/wndmgr/wndmgrapi.cpp
new file mode 100644
index 00000000..7d77a792
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/wndmgrapi.cpp
@@ -0,0 +1,279 @@
+#include <precomp.h>
+#include "wndmgrapi.h"
+#include <api/wndmgr/autopopup.h>
+#include <api/wndmgr/skinembed.h>
+#include <api/wndmgr/animate.h>
+#include <api/wnd/wndtrack.h>
+#include <api/skin/skinparse.h>
+#include <api/wndmgr/msgbox.h>
+#include <api/util/varmgr.h>
+
+wndmgr_api *wndManagerApi = NULL;
+
+WndMgrApi::WndMgrApi()
+{
+ skinEmbedder = new SkinEmbedder();
+ windowTracker = new WindowTracker();
+}
+
+WndMgrApi::~WndMgrApi()
+{
+ delete skinEmbedder;
+ skinEmbedder = NULL;
+ delete windowTracker;
+ windowTracker = NULL;
+}
+
+void WndMgrApi::wndTrackAdd(ifc_window *wnd)
+{
+ if (wnd == NULL)
+ {
+ DebugString("wndTrackAdd, illegal param : wnd == NULL\n");
+ return ;
+ }
+ windowTracker->addWindow(wnd);
+}
+
+void WndMgrApi::wndTrackRemove(ifc_window *wnd)
+{
+ if (wnd == NULL)
+ {
+ DebugString("wndTrackAdd, illegal param : wnd == NULL\n");
+ return ;
+ }
+ windowTracker->removeWindow(wnd);
+}
+
+bool WndMgrApi::wndTrackDock(ifc_window *wnd, RECT *r, int mask)
+{
+ return windowTracker->autoDock(wnd, r, mask);
+}
+
+bool WndMgrApi::wndTrackDock2(ifc_window *wnd, RECT *r, RECT *orig_r, int mask)
+{
+ return windowTracker->autoDock(wnd, r, orig_r, mask);
+}
+
+void WndMgrApi::wndTrackStartCooperative(ifc_window *wnd)
+{
+ windowTracker->startCooperativeMove(wnd);
+}
+
+void WndMgrApi::wndTrackEndCooperative(void)
+{
+ windowTracker->endCooperativeMove();
+}
+
+int WndMgrApi::wndTrackWasCooperative(void)
+{
+ return windowTracker->wasCooperativeMove();
+}
+
+void WndMgrApi::wndTrackInvalidateAll()
+{
+ windowTracker->invalidateAllWindows();
+}
+
+int WndMgrApi::skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient)
+{
+ return skinEmbedder->toggle(g, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+int WndMgrApi::skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient)
+{
+ return skinEmbedder->toggle(groupid, prefered_container, container_flag, sourceanimrect, transcient);
+}
+
+ifc_window *WndMgrApi::skinwnd_createByGuid(GUID g, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew)
+{
+ return skinEmbedder->create(g, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+ifc_window *WndMgrApi::skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container, int container_flag, RECT *sourceanimrect, int transcient, int starthidden, int *isnew)
+{
+ return skinEmbedder->create(groupid, prefered_container, container_flag, sourceanimrect, transcient, starthidden, isnew);
+}
+
+void WndMgrApi::skinwnd_destroy(ifc_window *w, RECT *destanimrect)
+{
+ skinEmbedder->destroy(w, destanimrect);
+}
+
+int WndMgrApi::skinwnd_getNumByGuid(GUID g)
+{
+ return skinEmbedder->getNumItems(g);
+}
+
+ifc_window *WndMgrApi::skinwnd_enumByGuid(GUID g, int n)
+{
+ return skinEmbedder->enumItem(g, n);
+}
+
+int WndMgrApi::skinwnd_getNumByGroupId(const wchar_t *groupid)
+{
+ return skinEmbedder->getNumItems(groupid);
+}
+
+ifc_window *WndMgrApi::skinwnd_enumByGroupId(const wchar_t *groupid, int n)
+{
+ return skinEmbedder->enumItem(groupid, n);
+}
+
+void WndMgrApi::skinwnd_attachToSkin(ifc_window *w, int side, int size)
+{
+ skinEmbedder->attachToSkin(w, side, size);
+}
+
+ScriptObject *WndMgrApi::skin_getContainer(const wchar_t *container_name)
+{
+ Container *c = SkinParser::getContainer(container_name);
+ if (c != NULL) return c->getScriptObject();
+ return NULL;
+}
+
+ScriptObject *WndMgrApi::skin_getLayout(ScriptObject *container, const wchar_t *layout_name)
+{
+ ASSERT(container != NULL);
+ Container *c = static_cast<Container *>(container->vcpu_getInterface(containerGuid));
+ if (c != NULL)
+ {
+ Layout *l = c->getLayout(layout_name);
+ if (l != NULL) return l->getScriptObject();
+ }
+ return NULL;
+}
+
+void WndMgrApi::wndholder_register(WindowHolder *wh)
+{
+ skinEmbedder->registerWindowHolder(wh);
+}
+
+void WndMgrApi::wndholder_unregister(WindowHolder *wh)
+{
+ skinEmbedder->unregisterWindowHolder(wh);
+}
+
+int WndMgrApi::messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parentwnd)
+{
+#ifdef WASABI_WNDMGR_OSMSGBOX
+ #ifdef WIN32
+
+ int f = 0;
+ if (flags & MSGBOX_OK) f |= MB_OK;
+ if (flags & MSGBOX_CANCEL) f |= MB_OKCANCEL;
+ if (flags & MSGBOX_YES) f |= MB_YESNO;
+ if ((flags & MSGBOX_YES) && (flags & MSGBOX_CANCEL)) f |= MB_YESNOCANCEL;
+
+ int r = MessageBoxW(parentwnd ? parentwnd->gethWnd() : NULL, txt, title, f);
+
+ if (r == IDOK) r = MSGBOX_OK;
+ if (r == IDCANCEL) r = MSGBOX_CANCEL;
+ if (r == IDYES) r = MSGBOX_YES;
+ if (r == IDNO) r = MSGBOX_NO;
+
+ return r;
+
+#else
+ // port me!
+#endif
+#else
+ MsgBox _mb(txt, title, flags, not_anymore_identifier);
+ return _mb.run();
+#endif
+}
+
+void WndMgrApi::drawAnimatedRects(const RECT *r1, const RECT *r2)
+{
+ if (r1 == NULL)
+ {
+ DebugString("drawAnimatedRects, illegal param : r1 == NULL\n");
+ return ;
+ }
+ if (r2 == NULL)
+ {
+ DebugString("drawAnimatedRects, illegal param : r2 == NULL\n");
+ return ;
+ }
+ AnimatedRects::draw(r1, r2);
+}
+
+int WndMgrApi::autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container, int container_flag)
+{
+ return AutoPopup::registerGuid(SKINPARTID_NONE, g, desc, prefered_container, container_flag);
+}
+
+int WndMgrApi::autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container, int container_flag)
+{
+ return AutoPopup::registerGroupId(SKINPARTID_NONE, groupid, desc, prefered_container, container_flag);
+}
+
+void WndMgrApi::autopopup_unregister(int id)
+{
+ AutoPopup::unregister(id);
+}
+
+int WndMgrApi::autopopup_getNumGuids()
+{
+ return AutoPopup::getNumGuids();
+}
+
+GUID WndMgrApi::autopopup_enumGuid(int n)
+{
+ return AutoPopup::enumGuid(n);
+}
+
+int WndMgrApi::autopopup_getNumGroups()
+{
+ return AutoPopup::getNumGroups();
+}
+
+const wchar_t *WndMgrApi::autopopup_enumGroup(int n)
+{
+ return AutoPopup::enumGroup(n);
+}
+
+const wchar_t *WndMgrApi::autopopup_enumGuidDescription(int n)
+{
+ return AutoPopup::enumGuidDescription(n);
+}
+
+const wchar_t *WndMgrApi::autopopup_enumGroupDescription(int n)
+{
+ return AutoPopup::enumGroupDescription(n);
+}
+
+const wchar_t *WndMgrApi::varmgr_translate(const wchar_t *str)
+{
+ StringW *s = PublicVarManager::translate_nocontext(str);
+ if (s)
+ {
+ ret.swap(s);
+ delete s;
+ return ret.getValueSafe();
+ }
+ return str;
+}
+
+Stack<ifc_window*> WndMgrApi::modal_wnd_stack;
+
+ifc_window *WndMgrApi::getModalWnd()
+{
+ if (!modal_wnd_stack.peek()) return NULL;
+ return modal_wnd_stack.top();
+}
+
+void WndMgrApi::pushModalWnd(ifc_window *wnd)
+{
+ modal_wnd_stack.push(wnd);
+}
+
+void WndMgrApi::popModalWnd(ifc_window *wnd)
+{
+ if (getModalWnd() != wnd) return ;
+ modal_wnd_stack.pop();
+}
+
+Container *WndMgrApi::newDynamicContainer(const wchar_t *name, int transcient)
+{
+ return SkinParser::newDynamicContainer(name, transcient);
+}
diff --git a/Src/Wasabi/api/wndmgr/wndmgrapi.h b/Src/Wasabi/api/wndmgr/wndmgrapi.h
new file mode 100644
index 00000000..88637d49
--- /dev/null
+++ b/Src/Wasabi/api/wndmgr/wndmgrapi.h
@@ -0,0 +1,59 @@
+#ifndef __APIWNDMGR_H
+#define __APIWNDMGR_H
+
+#include <api/wndmgr/api_wndmgr.h>
+#include <bfc/stack.h>
+#include <bfc/string/StringW.h>
+
+class WndMgrApi : public wndmgr_apiI {
+ public:
+ WndMgrApi();
+ virtual ~WndMgrApi();
+
+ virtual void wndTrackAdd(ifc_window *wnd);
+ virtual void wndTrackRemove(ifc_window *wnd);
+ virtual bool wndTrackDock(ifc_window *wnd, RECT *r, int mask);
+ virtual bool wndTrackDock2(ifc_window *wnd, RECT *r, RECT *orig_r, int mask);
+ virtual void wndTrackStartCooperative(ifc_window *wnd);
+ virtual void wndTrackEndCooperative();
+ virtual int wndTrackWasCooperative();
+ virtual void wndTrackInvalidateAll();
+ virtual int skinwnd_toggleByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ virtual int skinwnd_toggleByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0);
+ virtual ifc_window *skinwnd_createByGuid(GUID g, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL);
+ virtual ifc_window *skinwnd_createByGroupId(const wchar_t *groupid, const wchar_t *prefered_container = NULL, int container_flag = 0, RECT *sourceanimrect = NULL, int transcient = 0, int starthidden = 0, int *isnew=NULL);
+ virtual void skinwnd_destroy(ifc_window *w, RECT *destanimrect = NULL);
+ virtual int skinwnd_getNumByGuid(GUID g);
+ virtual ifc_window *skinwnd_enumByGuid(GUID g, int n);
+ virtual int skinwnd_getNumByGroupId(const wchar_t *groupid);
+ virtual ifc_window *skinwnd_enumByGroupId(const wchar_t *groupid, int n);
+ virtual void skinwnd_attachToSkin(ifc_window *w, int side, int size);
+ virtual ScriptObject *skin_getContainer(const wchar_t *container_name);
+ virtual ScriptObject *skin_getLayout(ScriptObject *container, const wchar_t *layout_name);
+ virtual void wndholder_register(WindowHolder *wh);
+ virtual void wndholder_unregister(WindowHolder *wh);
+ virtual int messageBox(const wchar_t *txt, const wchar_t *title, int flags, const wchar_t *not_anymore_identifier, ifc_window *parenwnt);
+ virtual ifc_window *getModalWnd();
+ virtual void pushModalWnd(ifc_window *w = MODALWND_NOWND);
+ virtual void popModalWnd(ifc_window *w = MODALWND_NOWND);
+ virtual void drawAnimatedRects(const RECT *r1, const RECT *r2);
+ virtual int autopopup_registerGuid(GUID g, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ virtual int autopopup_registerGroupId(const wchar_t *groupid, const wchar_t *desc, const wchar_t *prefered_container = NULL, int container_flag = 0);
+ virtual void autopopup_unregister(int id);
+ virtual int autopopup_getNumGuids();
+ virtual GUID autopopup_enumGuid(int n);
+ virtual int autopopup_getNumGroups();
+ virtual const wchar_t *autopopup_enumGroup(int n);
+ virtual const wchar_t *varmgr_translate(const wchar_t *str);
+ virtual Container *newDynamicContainer(const wchar_t *name, int transcient);
+ virtual const wchar_t *autopopup_enumGuidDescription(int n);
+ virtual const wchar_t *autopopup_enumGroupDescription(int n);
+
+ private:
+
+ static Stack<ifc_window*> modal_wnd_stack;
+ StringW ret;
+};
+
+
+#endif // __APIWNDMGR_H
diff --git a/Src/Wasabi/api/xml/LoadXML.cpp b/Src/Wasabi/api/xml/LoadXML.cpp
new file mode 100644
index 00000000..35709227
--- /dev/null
+++ b/Src/Wasabi/api/xml/LoadXML.cpp
@@ -0,0 +1,92 @@
+#include <precomp.h>
+#include "LoadXML.h"
+#include <bfc/file/wildcharsenum.h>
+#include <wchar.h>
+
+void LoadXmlServiceProvider(obj_xml *parser, const wchar_t *filename)
+{
+ /* TODO:
+ svc = XmlProviderEnum(filename).getNext();
+ pbuf = svc->getXmlData(filename, incpath, &p);
+ SvcEnum::release(svc);
+ svc = NULL;
+ */
+}
+
+// when filename begins with "buf:"
+void LoadXmlBuffer(obj_xml *parser, const wchar_t *filename)
+{
+ filename += 4;
+ if (parser->xmlreader_feed((void *)filename, wcslen(filename)*sizeof(wchar_t)) == API_XML_SUCCESS)
+ parser->xmlreader_feed(0, 0);
+}
+
+bool LoadXmlFilename(obj_xml *parser, const wchar_t *filename)
+{
+ OSFILETYPE file = WFOPEN(filename, WF_READONLY_BINARY, NO_FILEREADERS);
+// HANDLE file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
+
+// if (file == INVALID_HANDLE_VALUE)
+ if (file == OPEN_FAILED)
+ return false;
+
+ size_t bytesRead=0;
+ do
+ {
+ char data[4096] = {0};
+ bytesRead = FREAD(data, 1, sizeof(data), file);
+// if (ReadFile(file, data, 1024, &bytesRead, NULL) && bytesRead)
+ if (bytesRead)
+ {
+ if (parser->xmlreader_feed(data, bytesRead)!=API_XML_SUCCESS)
+ {
+// CloseHandle(file);
+ FCLOSE(file);
+ return false;
+ }
+ }
+ else
+ {
+ if (parser->xmlreader_feed(0, 0) != API_XML_SUCCESS)
+ {
+ FCLOSE(file);
+// CloseHandle(file);
+ return false;
+ }
+ bytesRead=0;
+ }
+ } while (bytesRead);
+
+ FCLOSE(file);
+// CloseHandle(file);
+ return true;
+}
+
+/*** TODO:
+ ** move this to a separate file
+ ** deal with wildcard filenames (e.g. *.xml)
+ */
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename)
+{
+ if (!WCSNICMP(filename, L"buf:", 4))
+ {
+ LoadXmlBuffer(parser, filename);
+ return ;
+ }
+ WildcharsEnumerator e(filename);
+
+ if (e.getNumFiles() > 0) // if we're including multiple files
+ {
+ for (int i = 0;i < e.getNumFiles();i++)
+ {
+ if (i) // don't reset the first time around
+ parser->xmlreader_reset();
+ LoadXmlFilename(parser, e.enumFile(i));
+ }
+ }
+ else if (!LoadXmlFilename(parser, filename))
+ {
+ LoadXmlServiceProvider(parser, filename);
+ return ;
+ }
+}
diff --git a/Src/Wasabi/api/xml/LoadXML.h b/Src/Wasabi/api/xml/LoadXML.h
new file mode 100644
index 00000000..8e6ef2c3
--- /dev/null
+++ b/Src/Wasabi/api/xml/LoadXML.h
@@ -0,0 +1,7 @@
+#ifndef NULLSOFT_WASABI_LOADXML_H
+#define NULLSOFT_WASABI_LOADXML_H
+
+#include "../xml/obj_xml.h"
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/xml/XMLAutoInclude.cpp b/Src/Wasabi/api/xml/XMLAutoInclude.cpp
new file mode 100644
index 00000000..8821fe4d
--- /dev/null
+++ b/Src/Wasabi/api/xml/XMLAutoInclude.cpp
@@ -0,0 +1,87 @@
+#include <precomp.h>
+#include <bfc/wasabi_std.h>
+#include "XMLAutoInclude.h"
+#include <bfc/file/wildcharsenum.h>
+#include <api/util/varmgr.h>
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+XMLAutoInclude::XMLAutoInclude(obj_xml *_parser, const wchar_t *_path)
+{
+ path=_path;
+ parser = _parser;
+ if (parser)
+ {
+ parser->xmlreader_registerCallback(L"*\finclude", this);
+ }
+}
+
+XMLAutoInclude::~XMLAutoInclude()
+{
+ if (parser)
+ {
+ parser->xmlreader_unregisterCallback(this);
+ }
+}
+static const wchar_t *varmgr_translate(const wchar_t *str)
+{
+ static StringW ret;
+ StringW *s = PublicVarManager::translate_nocontext(str);
+ if (s)
+ {
+ ret.swap(s);
+ delete s;
+ return ret.getValueSafe();
+ }
+ return str;
+}
+void XMLAutoInclude::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ const wchar_t *includeFile = params->getItemValue(L"file");
+ const wchar_t *trans = /*WASABI_API_WNDMGR->*/varmgr_translate(includeFile);
+ if (trans)
+ {
+ //const char *path = WASABI_API_SKIN->getSkinsPath();
+ if (!Wasabi::Std::isRootPath(trans))
+ includeFn=StringPathCombine(path, trans);
+ else
+ includeFn=trans;
+ }
+
+}
+
+void XMLAutoInclude::Include(const wchar_t *filename)
+{
+ if (filename && *filename)
+ {
+ parser->xmlreader_interrupt();
+ StringW oldPath = path;
+
+ const wchar_t *file = Wasabi::Std::filename(filename);
+ int fnlen = wcslen(file);
+ path = filename;
+ path.trunc(-fnlen);
+ LoadXmlFile(parser, filename);
+ path = oldPath;
+ parser->xmlreader_resume();
+ }
+}
+
+void XMLAutoInclude::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ if (!includeFn.isempty())
+ {
+ WildcharsEnumerator e(includeFn);
+ if (e.getNumFiles() > 0) // if we're including multiple files
+ {
+ for (int i = 0;i < e.getNumFiles();i++)
+ {
+ Include(e.enumFile(i));
+ }
+ }
+ else
+ Include(includeFn);
+ }
+
+}
+
diff --git a/Src/Wasabi/api/xml/XMLAutoInclude.h b/Src/Wasabi/api/xml/XMLAutoInclude.h
new file mode 100644
index 00000000..8b3df85e
--- /dev/null
+++ b/Src/Wasabi/api/xml/XMLAutoInclude.h
@@ -0,0 +1,22 @@
+#ifndef NULLSOFT_WASABI_XMLAUTOINCLUDE_H
+#define NULLSOFT_WASABI_XMLAUTOINCLUDE_H
+
+#include "../xml/obj_xml.h"
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include <bfc/string/StringW.h>
+
+class XMLAutoInclude : public ifc_xmlreadercallbackI
+{
+public:
+ XMLAutoInclude(obj_xml *_parser, const wchar_t *_path);
+ ~XMLAutoInclude();
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+//private:
+ obj_xml *parser;
+ StringW path, includeFn;
+private:
+ void Include(const wchar_t *filename);
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/xml/api_xmlreadercallback.cpp b/Src/Wasabi/api/xml/api_xmlreadercallback.cpp
new file mode 100644
index 00000000..c6741d87
--- /dev/null
+++ b/Src/Wasabi/api/xml/api_xmlreadercallback.cpp
@@ -0,0 +1,2 @@
+#include <precomp.h>
+#include <api/xml/ifc_xmlreadercallback.h>
diff --git a/Src/Wasabi/api/xml/xmlparams.cpp b/Src/Wasabi/api/xml/xmlparams.cpp
new file mode 100644
index 00000000..c8570eee
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparams.cpp
@@ -0,0 +1,12 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparams.cpp
+// Class : ifc_xmlreaderparams
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#include <precomp.h>
+#include "xmlparams.h"
+
+
diff --git a/Src/Wasabi/api/xml/xmlparams.h b/Src/Wasabi/api/xml/xmlparams.h
new file mode 100644
index 00000000..06d915a7
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparams.h
@@ -0,0 +1,103 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparams.h
+// Class : skin_xmlreaderparams
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __XMLREADERPARAMS_H
+#define __XMLREADERPARAMS_H
+
+#include <bfc/dispatch.h>
+//#include <bfc/common.h>
+#include "../xml/ifc_xmlreaderparams.h"
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE skin_xmlreaderparams : public ifc_xmlreaderparams
+{
+ protected:
+ skin_xmlreaderparams() {}
+ ~skin_xmlreaderparams() {}
+ public:
+ /*
+ const wchar_t *getItemName(int i);
+ const wchar_t *getItemValue(int i);
+ const wchar_t *getItemValue(const wchar_t *name);
+ const wchar_t *enumItemValues(const wchar_t *name, int nb);
+ int getItemValueInt(const wchar_t *name, int def = 0);
+ int getNbItems();
+ */
+ void addItem(const wchar_t *parm, const wchar_t *value);
+ void removeItem(const wchar_t *parm);
+ void replaceItem(const wchar_t *parm, const wchar_t *value);
+ int findItem(const wchar_t *parm);
+
+ protected:
+ enum {
+ /*XMLREADERPARAMS_GETITEMNAME = 100,
+ XMLREADERPARAMS_GETITEMVALUE = 200,
+ XMLREADERPARAMS_GETITEMVALUE2 = 201,
+ XMLREADERPARAMS_ENUMITEMVALUES = 202,
+ XMLREADERPARAMS_GETITEMVALUEINT = 300,
+ XMLREADERPARAMS_GETNBITEMS = 400,*/
+ XMLREADERPARAMS_ADDITEM = 500,
+ XMLREADERPARAMS_REMOVEITEM = 600,
+ XMLREADERPARAMS_REPLACEITEM = 700,
+ XMLREADERPARAMS_FINDITEM = 800,
+ };
+};
+
+// ----------------------------------------------------------------------------
+/*
+inline const wchar_t *skin_xmlreaderparams::getItemName(int i) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_GETITEMNAME, (const wchar_t *)0, i);
+ return __retval;
+}
+
+inline const wchar_t *skin_xmlreaderparams::getItemValue(int i) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_GETITEMVALUE, (const wchar_t *)0, i);
+ return __retval;
+}
+
+inline const wchar_t *skin_xmlreaderparams::getItemValue(const wchar_t *name) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_GETITEMVALUE2, (const wchar_t *)0, name);
+ return __retval;
+}
+
+inline const wchar_t *skin_xmlreaderparams::enumItemValues(const wchar_t *name, int nb) {
+ const wchar_t *__retval = _call(XMLREADERPARAMS_ENUMITEMVALUES, (const wchar_t *)0, name, nb);
+ return __retval;
+}
+
+inline int skin_xmlreaderparams::getItemValueInt(const wchar_t *name, int def) {
+ int __retval = _call(XMLREADERPARAMS_GETITEMVALUEINT, (int)0, name, def);
+ return __retval;
+}
+
+inline int skin_xmlreaderparams::getNbItems() {
+ int __retval = _call(XMLREADERPARAMS_GETNBITEMS, (int)0);
+ return __retval;
+}
+*/
+inline void skin_xmlreaderparams::addItem(const wchar_t *parm, const wchar_t *value) {
+ _voidcall(XMLREADERPARAMS_ADDITEM, parm, value);
+}
+
+inline void skin_xmlreaderparams::removeItem(const wchar_t *parm) {
+ _voidcall(XMLREADERPARAMS_REMOVEITEM, parm);
+}
+
+inline void skin_xmlreaderparams::replaceItem(const wchar_t *parm, const wchar_t *value) {
+ _voidcall(XMLREADERPARAMS_REPLACEITEM, parm, value);
+}
+
+inline int skin_xmlreaderparams::findItem(const wchar_t *parm) {
+ int __retval = _call(XMLREADERPARAMS_FINDITEM, (int)0, parm);
+ return __retval;
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __XMLREADERPARAMS_H
diff --git a/Src/Wasabi/api/xml/xmlparamsi.cpp b/Src/Wasabi/api/xml/xmlparamsi.cpp
new file mode 100644
index 00000000..9ac7b711
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsi.cpp
@@ -0,0 +1,119 @@
+#include <precomp.h>
+#include "xmlparamsi.h"
+#include <bfc/wasabi_std.h>
+
+XmlReaderParamsI::~XmlReaderParamsI()
+{
+ parms_list.deleteAll();
+}
+
+const wchar_t *XmlReaderParamsI::getItemName(int i)
+{
+ if(i>getNbItems())
+ return L"";
+ return
+ parms_list[i]->parm;
+}
+
+
+const wchar_t *XmlReaderParamsI::getItemValue(int i)
+{
+ if(i>getNbItems())
+ return L"";
+ return
+ parms_list[i]->value;
+}
+
+const wchar_t *XmlReaderParamsI::getItemValue(const wchar_t *name)
+{
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, name))
+ return parms_list[i]->value;
+ return NULL;
+}
+
+const wchar_t *XmlReaderParamsI::enumItemValues(const wchar_t *name, int nb)
+{
+ int f=0;
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, name))
+ if(f==nb)
+ return parms_list[i]->value;
+ else f++;
+ return NULL;
+}
+
+int XmlReaderParamsI::getItemValueInt(const wchar_t *name, int def)
+{
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, name))
+ {
+ // TODO: benski> do we want to return "def" when there's an empty value?
+ return WTOI(parms_list[i]->value);
+ }
+ return def;
+}
+
+
+int XmlReaderParamsI::getNbItems()
+{
+ return parms_list.getNumItems();
+}
+
+void XmlReaderParamsI::addItem(const wchar_t *parm, const wchar_t *value)
+{
+ parms_struct *p= new parms_struct;
+ p->parm = WCSDUP(parm);
+ p->ownValue = true;
+ p->value = value;
+ parms_list.addItem(p);
+}
+
+void XmlReaderParamsI::removeItem(const wchar_t *parm)
+{
+ for (int i=0;i<parms_list.getNumItems();i++)
+ {
+ parms_struct *s = parms_list.enumItem(i);
+ if (!WCSICMP(parm, s->parm))
+ {
+ delete s;
+ parms_list.removeByPos(i);
+ i--;
+ }
+ }
+}
+
+void XmlReaderParamsI::replaceItem(const wchar_t *parm, const wchar_t *value)
+{
+ if (!value)
+ {
+ removeItem(parm);
+ return;
+ }
+
+ StringW s = value; // if we were passed our current value's pointer ...
+
+ const wchar_t *curval = getItemValue(parm);
+ if (s.isequal(value) && curval) return; // (hey, if we're replacing with same value, forget about it, but only if we did have that value, because isequal will return true if curval is NULL and we pass it ("") )
+
+ removeItem(parm); // ... then this call would make the value param invalid ...
+
+ addItem(parm, s); // ... so we're sending a saved buffer instead
+}
+
+int XmlReaderParamsI::findItem(const wchar_t *parm)
+{
+ for(int i=0;i<getNbItems();i++)
+ if(!WCSICMP(parms_list[i]->parm, parm))
+ return i;
+ return -1;
+}
+
+ // calling this will destroy your String... here for optimization ...
+void XmlReaderParamsI::addItemSwapValue(const wchar_t *parm, StringW &value)
+{
+ parms_struct *p= new parms_struct;
+ p->parm = parm;
+ p->value.swap(&value);
+ parms_list.addItem(p);
+}
diff --git a/Src/Wasabi/api/xml/xmlparamsi.h b/Src/Wasabi/api/xml/xmlparamsi.h
new file mode 100644
index 00000000..606c462c
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsi.h
@@ -0,0 +1,52 @@
+#ifndef __XMLPARAMSI_H
+#define __XMLPARAMSI_H
+
+#include <bfc/dispatch.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/ptrlist.h>
+#include <bfc/string/StringW.h>
+
+/*<?<autoheader/>*/
+#include <api/xml/xmlparams.h>
+#include <api/xml/xmlparamsx.h>
+/*?>*/
+
+
+class XmlReaderParamsI : public XmlReaderParamsX
+{
+public:
+ XmlReaderParamsI() {}
+ virtual ~XmlReaderParamsI();
+
+ DISPATCH(100) const wchar_t *getItemName(int i);
+ DISPATCH(200) const wchar_t *getItemValue(int i);
+ DISPATCH(201) const wchar_t *getItemValue(const wchar_t *name);
+ DISPATCH(202) const wchar_t *enumItemValues(const wchar_t *name, int nb);
+ DISPATCH(300) int getItemValueInt(const wchar_t *name, int def = 0);
+ DISPATCH(400) int getNbItems();
+
+ DISPATCH(500) void addItem(const wchar_t *parm, const wchar_t *value);
+ DISPATCH(600) void removeItem(const wchar_t *parm);
+ DISPATCH(700) void replaceItem(const wchar_t *parm, const wchar_t *value);
+ DISPATCH(800) int findItem(const wchar_t *parm);
+
+ NODISPATCH void addItemSwapValue(const wchar_t *parm, StringW &value); // calling this will destroy your String... here for optimization ...
+private:
+ struct parms_struct
+ {
+ parms_struct() : parm(0), ownValue(false)
+ {}
+ ~parms_struct()
+ {
+ if (ownValue)
+ FREE((wchar_t *)parm);
+ }
+ const wchar_t *parm;
+ StringW value;
+ bool ownValue;
+ };
+ PtrList<parms_struct> parms_list;
+};
+
+
+#endif
diff --git a/Src/Wasabi/api/xml/xmlparamsx.cpp b/Src/Wasabi/api/xml/xmlparamsx.cpp
new file mode 100644
index 00000000..2b6b91ac
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsx.cpp
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparamsx.cpp
+// Class : skin_xmlreaderparams
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+#include <precomp.h>
+
+#include "xmlparamsx.h"
+#include "xmlparamsi.h"
+
+#ifdef CBCLASS
+#undef CBCLASS
+#endif
+
+#define CBCLASS XmlReaderParamsX
+START_DISPATCH;
+ CB(XMLREADERPARAMS_GETITEMNAME, getItemName);
+ CB(XMLREADERPARAMS_GETITEMVALUE, getItemValue);
+ CB(XMLREADERPARAMS_GETITEMVALUE2, getItemValue2);
+ CB(XMLREADERPARAMS_ENUMITEMVALUES, enumItemValues);
+ CB(XMLREADERPARAMS_GETITEMVALUEINT, getItemValueInt);
+ CB(XMLREADERPARAMS_GETNBITEMS, getNbItems);
+ VCB(XMLREADERPARAMS_ADDITEM, addItem);
+ VCB(XMLREADERPARAMS_REMOVEITEM, removeItem);
+ VCB(XMLREADERPARAMS_REPLACEITEM, replaceItem);
+ CB(XMLREADERPARAMS_FINDITEM, findItem);
+END_DISPATCH;
+#undef CBCLASS
+
+const wchar_t *XmlReaderParamsX::getItemValue2(const wchar_t *name) { return static_cast<XmlReaderParamsI *>(this)->getItemValue(name); }
diff --git a/Src/Wasabi/api/xml/xmlparamsx.h b/Src/Wasabi/api/xml/xmlparamsx.h
new file mode 100644
index 00000000..8e2c6eae
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparamsx.h
@@ -0,0 +1,38 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Thu May 15 21:07:09 2003]
+//
+// File : xmlparamsx.h
+// Class : ifc_xmlreaderparams
+// class layer : Dispatchable Receiver
+// ----------------------------------------------------------------------------
+
+#ifndef __XMLREADERPARAMSX_H
+#define __XMLREADERPARAMSX_H
+
+#include "xmlparams.h"
+
+
+
+
+// ----------------------------------------------------------------------------
+
+class XmlReaderParamsX : public skin_xmlreaderparams {
+ protected:
+ XmlReaderParamsX() {}
+ public:
+ virtual const wchar_t *getItemName(int i)=0;
+ virtual const wchar_t *getItemValue(int i)=0;
+ virtual const wchar_t *getItemValue2(const wchar_t *name);
+ virtual const wchar_t *enumItemValues(const wchar_t *name, int nb)=0;
+ virtual int getItemValueInt(const wchar_t *name, int def = 0)=0;
+ virtual int getNbItems()=0;
+ virtual void addItem(const wchar_t *parm, const wchar_t *value)=0;
+ virtual void removeItem(const wchar_t *parm)=0;
+ virtual void replaceItem(const wchar_t *parm, const wchar_t *value)=0;
+ virtual int findItem(const wchar_t *parm)=0;
+
+ protected:
+ RECVS_DISPATCH;
+};
+
+#endif // __XMLREADERPARAMSX_H
diff --git a/Src/Wasabi/api/xml/xmlparse.h b/Src/Wasabi/api/xml/xmlparse.h
new file mode 100644
index 00000000..68c81b43
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlparse.h
@@ -0,0 +1,23 @@
+#ifndef _XMLPARSE_H
+#define _XMLPARSE_H
+
+class XMLParse {
+private:
+ void *parser;
+
+public:
+ XMLParse();
+ virtual ~XMLParse();
+
+ virtual void SetUserData(void *param);
+ virtual void SetElementHandler(void (*start)(void *userData, const wchar_t *name, const wchar_t **atts),
+ void (*end)(void *userData, const wchar_t *name));
+ virtual void SetCharacterDataHandler(void (*handler)(void *userData,const wchar_t *s, int len));
+ virtual int Parse(const wchar_t *s, int len, int isFinal);
+ virtual const wchar_t *ErrorString(int code);
+ virtual int GetErrorCode();
+ virtual int GetCurrentLineNumber();
+
+};
+
+#endif
diff --git a/Src/Wasabi/api/xml/xmlreader.cpp b/Src/Wasabi/api/xml/xmlreader.cpp
new file mode 100644
index 00000000..c6d649b8
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlreader.cpp
@@ -0,0 +1,197 @@
+#include <precomp.h>
+#include "xmlreader.h"
+#include <bfc/parse/pathparse.h>
+#include <bfc/file/wildcharsenum.h>
+#include <bfc/string/url.h>
+#include <api/service/svcs/svc_xmlprov.h>
+#ifdef WASABI_COMPILE_WNDMGR
+#include <api/util/varmgr.h>
+#endif
+#include <api/xml/xmlparamsi.h>
+#include <api/xml/XMLAutoInclude.h>
+#include "../nu/regexp.h"
+
+void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
+
+void XmlReader::registerCallback(const wchar_t *matchstr, XmlReaderCallbackI *callback)
+{
+ if (matchstr == NULL || callback == NULL) return ;
+ xmlreader_cb_struct *s = new xmlreader_cb_struct(matchstr, TYPE_CLASS_CALLBACK, callback);
+ callback_list.addItem(s, 0); // mig: add to FRONT of list... so we don't step on hierarchical toes.
+}
+
+void XmlReader::registerCallback(const wchar_t *matchstr, void (* callback)(int, const wchar_t *, skin_xmlreaderparams *))
+{
+ if (matchstr == NULL || callback == NULL) return ;
+ xmlreader_cb_struct *s = new xmlreader_cb_struct(matchstr, TYPE_STATIC_CALLBACK, (XmlReaderCallbackI *)callback);
+ callback_list.addItem(s, 0); // mig: add to FRONT of list... so we don't step on hierarchical toes.
+}
+
+void XmlReader::unregisterCallback(void *callback)
+{
+ for (int i = 0;i < callback_list.getNumItems();i++)
+ {
+ if (callback_list[i]->callback == callback)
+ {
+ delete callback_list[i];
+ callback_list.delByPos(i);
+ i--;
+ }
+ }
+}
+
+int XmlReader::loadFile(const wchar_t *filename, const wchar_t *incpath, int isinclude)
+{
+ includePath=incpath;
+ waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
+ if (parserFactory)
+ {
+ obj_xml *parser = (obj_xml *)parserFactory->getInterface();
+
+ if (parser)
+ {
+ includer = new XMLAutoInclude(parser, incpath);
+ parser->xmlreader_registerCallback(L"*", this);
+ parser->xmlreader_open();
+
+ LoadXmlFile(parser, filename);
+ parser->xmlreader_unregisterCallback(this);
+ delete includer;
+ includer=0;
+
+ parser->xmlreader_close();
+ parserFactory->releaseInterface(parser);
+ parser = 0;
+ return 1;
+ }
+
+ }
+
+ return 0;
+}
+
+const wchar_t *XmlReader::getIncludePath()
+{
+ // return include_stack.top()->getValue();
+ return (includer != NULL ? includer->path.getValue() : L"");
+ //return includePath;
+}
+
+void XmlReader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ size_t numParams = params->getNbItems();
+ XmlReaderParamsI p;
+ for (size_t i = 0;i!=numParams;i++)
+ { //CT> removed api-> for speed
+ // BU String* for no exploit
+ const wchar_t *paramStr = params->getItemValue(i);
+ StringW *str = PublicVarManager::translate_nocontext(paramStr);
+ if (str)
+ {
+ Url::decode(str->getNonConstVal());
+ p.addItemSwapValue(params->getItemName(i), *str);
+ delete str;
+ }
+ else
+ {
+
+ StringW temp = paramStr;
+ Url::decode(temp.getNonConstVal());
+ p.addItemSwapValue(params->getItemName(i), temp);
+ }
+ }
+
+ foreach(callback_list)
+ if (Match(callback_list.getfor()->matchstr.v(), xmlpath))
+ {
+ switch (callback_list.getfor()->type)
+ {
+ case TYPE_CLASS_CALLBACK:
+ callback_list.getfor()->callback->xmlReaderOnStartElementCallback(xmltag, &p);
+ break;
+ case TYPE_STATIC_CALLBACK:
+ ((void (*)(int, const wchar_t *, skin_xmlreaderparams *))callback_list.getfor()->callback)(1, xmltag, &p);
+ break;
+ }
+ }
+
+ endfor
+}
+
+void XmlReader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ foreach(callback_list)
+ if (Match(callback_list.getfor()->matchstr.v(), xmlpath))
+ {
+ switch (callback_list.getfor()->type)
+ {
+ case TYPE_CLASS_CALLBACK:
+ callback_list.getfor()->callback->xmlReaderOnEndElementCallback(xmltag);
+ break;
+ case TYPE_STATIC_CALLBACK:
+ ((void (*)(int, const wchar_t *, skin_xmlreaderparams *))callback_list.getfor()->callback)(0, xmltag, NULL);
+ break;
+ }
+
+ }
+ endfor
+
+}
+
+void XmlReader::xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr)
+{
+ int disperr = 1;
+ StringPrintfW txt(L"error parsing xml layer\n");
+ StringPrintfW err(L"%s at line %d\n", errstr, linenum);
+
+ if (disperr)
+ {
+#ifdef WASABI_COMPILE_WND
+ Wasabi::Std::messageBox(err, txt, 0);
+#else
+ DebugStringW("%s - %s", err.getValue(), txt.getValue());
+#endif
+
+ }
+ else
+ {
+#ifdef _WIN32
+ OutputDebugStringW(txt);
+ OutputDebugStringW(err);
+#endif
+ }
+}
+
+#if 0 // TODO: benski> need to do onError for obj_xml
+int XmlReader::parseBuffer(void *parser, const char *xml, int size, int final, const char *filename, const char *incpath)
+{
+ if (!XML_Parse(parser, xml, size, final))
+ {
+ int disperr = 1;
+ StringPrintf txt("error parsing xml layer (%s)\n", filename);
+ StringPrintf err("%s at line %d\n",
+ XML_ErrorString(XML_GetErrorCode(parser)),
+ XML_GetCurrentLineNumber(parser));
+ if (disperr)
+ {
+#ifdef WASABI_COMPILE_WND
+ Std::messageBox(err, txt, 0);
+#else
+ DebugString("%s - %s", err.getValue(), txt.getValue());
+#endif
+
+ }
+ else
+ {
+ OutputDebugString(txt);
+ OutputDebugString(err);
+ }
+ currentpos = "";
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+
+XmlReader skinXML; \ No newline at end of file
diff --git a/Src/Wasabi/api/xml/xmlreader.h b/Src/Wasabi/api/xml/xmlreader.h
new file mode 100644
index 00000000..b8a599d9
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlreader.h
@@ -0,0 +1,75 @@
+#ifndef _XMLREADER_H
+#define _XMLREADER_H
+
+#include <bfc/ptrlist.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/stack.h>
+#include <bfc/dispatch.h>
+#include <api/xml/xmlparams.h>
+#include "../xml/ifc_xmlreadercallbackI.h"
+#include <api/xml/XMLAutoInclude.h>
+class svc_xmlProvider;
+
+typedef enum {
+ TYPE_CLASS_CALLBACK = 1,
+ TYPE_STATIC_CALLBACK,
+} xmlreader_callbackType;
+
+
+class XmlReaderCallbackI
+{
+public:
+ XmlReaderCallbackI() : handle(NULL) {}
+
+ virtual void xmlReaderOnStartElementCallback(const wchar_t *xmltag, skin_xmlreaderparams *params) { }
+ virtual void xmlReaderOnEndElementCallback(const wchar_t *xmltag) { }
+
+private:
+ void *handle;
+};
+
+
+class xmlreader_cb_struct
+{
+public:
+ xmlreader_cb_struct(const wchar_t *m, xmlreader_callbackType t, XmlReaderCallbackI *cb) : matchstr(m), type(t), callback(cb)
+ {
+ matchstr.toupper();
+ }
+
+ StringW matchstr;
+ xmlreader_callbackType type;
+ XmlReaderCallbackI * callback;
+};
+
+class XmlReader : public ifc_xmlreadercallbackI
+{
+public:
+ // matchstr is a regexp string such as "WinampAbstractionLayer/Layer[a-z]"
+ // or "Winamp*Layer/*/Layout"
+ void registerCallback(const wchar_t *matchstr, XmlReaderCallbackI *callback);
+ void registerCallback(const wchar_t *matchstr, void (*static_callback)(int start, const wchar_t *xmltag, skin_xmlreaderparams *params));
+
+ void unregisterCallback(void *callback);
+
+ // if only_this_class param is specified, only this class will be called back
+ // returns 1 on success, 0 on error
+ int loadFile(const wchar_t *filename, const wchar_t *incpath = NULL, int isinclude = 0);
+ const wchar_t *getIncludePath();
+
+ int getNumCallbacks() { return callback_list.getNumItems(); }
+
+private:
+ void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
+ void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
+ void xmlReaderOnError(int linenum, int errcode, const wchar_t *errstr);
+// int doLoadFile(FILE *fp, svc_xmlProvider *svc, const wchar_t *filename, const wchar_t *incpath);
+
+ PtrList<xmlreader_cb_struct> callback_list;
+ StringW includePath;
+XMLAutoInclude *includer;
+};
+
+extern XmlReader skinXML;
+
+#endif
diff --git a/Src/Wasabi/api/xml/xmlwrite.cpp b/Src/Wasabi/api/xml/xmlwrite.cpp
new file mode 100644
index 00000000..732c05f7
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlwrite.cpp
@@ -0,0 +1,262 @@
+#include <precomp.h>
+
+#include "xmlwrite.h"
+
+#include <bfc/wasabi_std.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/parse/paramparser.h>
+
+#if 0
+static unsigned char xmltypecheck[256] =
+{
+#define BT_COLON BT_NMSTRT
+#include "latin1tab.h"
+#undef BT_COLON
+#include "asciitab.h"
+ };
+#endif
+
+#define EFPRINTF (nohicharconversion ? eutf8fprintf : efprintf)
+
+#include "../nu/AutoChar.h"
+XMLWrite::XMLWrite(const wchar_t *filename, const wchar_t *doctype, const wchar_t *dtddoctype, int no_hi_chars_conversion)
+{
+ nohicharconversion = no_hi_chars_conversion;
+ FILE *f = _wfopen(filename, WF_WRITE_BINARY);
+ Init(f, doctype, dtddoctype);
+}
+
+XMLWrite::XMLWrite(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype, int no_hi_chars_conversion)
+{
+ nohicharconversion = no_hi_chars_conversion;
+ Init(file, doctype, dtddoctype);
+}
+
+void XMLWrite::Init(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype)
+{
+ fp = file;
+ ASSERT(fp != NULL); // sheet, need exceptions here
+ indenter.setValue(L"");
+ utf8fprintf(fp, L"<?xml version=\"1.0\" encoding='UTF-8' standalone=\"yes\"?>\n");
+ if (dtddoctype != NULL)
+ utf8fprintf(fp, L"<!DOCTYPE %s>\n", dtddoctype);
+ pushCategory(doctype, 1, 0);
+}
+
+XMLWrite::~XMLWrite()
+{
+ popCategory(1, 0);
+ fflush(fp);
+ fclose(fp);
+ ASSERT(titles.peek() == 0);
+}
+
+void XMLWrite::comment(const wchar_t *comment)
+{
+ utf8fprintf(fp, L"<!-- %s -->\n", comment);
+}
+
+void XMLWrite::pushCategory(const wchar_t *title, int wantcr, int wantindent)
+{
+ if (wantindent)
+ {
+ utf8fprintf(fp, L"%s<%s>%s", indenter.getValue(), title, wantcr ? L"\n" : L"");
+ }
+ else
+ utf8fprintf(fp, L"<%s>%s", title, wantcr ? L"\n" : L"");
+ indenter+=L" ";
+ ParamParser pp(title, L" ");
+ titles.push(WCSDUP(pp.enumItem(0)));
+}
+
+void XMLWrite::pushCategoryAttrib(const wchar_t *title, int nodata)
+{
+ utf8fprintf(fp, L"%s<%s", indenter.getValue(), title);
+ indenter+=L" ";
+ titles.push(nodata ? NULL : WCSDUP(title));
+}
+
+void XMLWrite::writeCategoryAttrib(const wchar_t *title, const int val)
+{
+ utf8fprintf(fp, L" %s=\"%d\"", title, val);
+}
+
+void XMLWrite::writeCategoryAttrib(const wchar_t *title, const wchar_t *str)
+{
+ if (!str)
+ str = L"";
+ utf8fprintf(fp, L" %s=\"", title);
+ EFPRINTF(fp, L"%s", str);
+ utf8fprintf(fp, L"\"");
+}
+
+void XMLWrite::closeCategoryAttrib(int wantcr)
+{
+ if (titles.top() == NULL)
+ utf8fprintf(fp, L" /");
+ utf8fprintf(fp, L">%s", wantcr ? L"\n" : L"");
+}
+
+void XMLWrite::writeAttribEmpty(const wchar_t *title, int wantcr, int wantindent)
+{
+ if (wantindent)
+ utf8fprintf(fp, L"%s<%s/>%s", indenter.getValue(), title, wantcr ? L"\n" : L"");
+ else
+ utf8fprintf(fp, L"<%s/>%s", title, wantcr ? L"\n" : L"");
+}
+
+void XMLWrite::writeAttrib(const wchar_t *title, const wchar_t *text, int wantcr, int wantindent)
+{
+ if (text && *text)
+ {
+ if (wantindent)
+ utf8fprintf(fp, L"%s<%s>", indenter.getValue(), title);
+ else
+ utf8fprintf(fp, L"<%s>", title);
+ EFPRINTF(fp, L"%s", text);
+ utf8fprintf(fp, L"</%s>%s", title, wantcr ? L"\n" : L"");
+ }
+ else
+ {
+ writeAttribEmpty(title, wantcr, wantindent);
+ }
+}
+
+void XMLWrite::writeAttrib(const wchar_t *title, int val, int wantcr, int wantindent)
+{
+ if (wantindent)
+ utf8fprintf(fp, L"%s<%s>%d</%s>%s", indenter.getValue(), title, val, title, wantcr ? L"\n" : L"");
+ else
+ utf8fprintf(fp, L"<%s>%d</%s>%s", title, val, title, wantcr ? L"\n" : L"");
+}
+
+int XMLWrite::popCategory(int wantcr, int wantindent)
+{
+ indenter.trunc(-2);
+ wchar_t *title;
+ int r = titles.pop(&title);
+ if (!r) return 0;
+ if (title != NULL)
+ {
+ if (wantindent)
+ utf8fprintf(fp, L"%s</%s>%s", indenter.getValue(), title, wantcr ? L"\n" : L"");
+ else
+ utf8fprintf(fp, L"</%s>%s", title, wantcr ? L"\n" : L"");
+ FREE(title);
+ }
+ return titles.peek();
+}
+
+int XMLWrite::utf8fprintf(FILE *fp, const wchar_t *format, ...)
+{
+ va_list v;
+ StringW outstr;
+ va_start(v, format);
+ outstr.va_sprintf(format, v);
+ va_end(v);
+
+#ifdef _WIN32
+ AutoChar utf8(outstr, CP_UTF8);
+#else
+#warning port me
+ AutoChar utf8(outstr);
+#endif
+ const char *data = (const char *)utf8; // to make the next line less messay
+ fwrite(data, STRLEN(data), 1, fp);
+ return 0;
+}
+
+int XMLWrite::eutf8fprintf(FILE *fp, const wchar_t *format, ...)
+{
+ va_list v;
+ StringW outstr;
+ va_start(v, format);
+ outstr.va_sprintf(format, v);
+ va_end(v);
+
+#ifdef _WIN32
+ AutoChar utf8(outstr, CP_UTF8);
+#else
+#warning port me
+ AutoChar utf8(outstr);
+#endif
+
+ const char *data = (const char *)utf8; // to make the next line less messay
+ while (data && *data)
+ {
+ size_t cur_length=0;
+ while (data[cur_length] && data[cur_length] != '<' && data[cur_length] != '>' && data[cur_length] != '&' && data[cur_length] != '\"' && data[cur_length] != '\'')
+ {
+ cur_length++;
+ }
+ fwrite(data, cur_length, 1, fp);
+ data += cur_length;
+ if (*data)
+ {
+ // if we get here, it was a special character
+ switch(*data)
+ {
+ case '<': fwrite("&lt;", 4, 1, fp); break;
+ case '>': fwrite("&gt;", 4, 1, fp); break;
+ case '&': fwrite("&amp;", 5, 1, fp); break;
+ case '\"': fwrite("&quot;", 6, 1, fp); break;
+ case '\'': fwrite("&apos;", 6, 1, fp); break;
+ }
+ data++;
+ }
+ };
+
+ return 0;
+}
+
+int XMLWrite::efprintf(FILE *fp, const wchar_t *format, ...)
+{
+ va_list v;
+ // http://www.w3.org/TR/REC-xml#syntax
+ int bcount = 0;
+ StringW outstr;
+ va_start(v, format);
+ outstr.va_sprintf(format, v);
+ va_end(v);
+ size_t n = outstr.len();
+ for (size_t i = 0; i != n; i++)
+ {
+ wchar_t c = outstr.getValue()[i];
+ switch (c)
+ {
+ case '<': fwrite("&lt;", 4, 1, fp); bcount += 4; break;
+ case '>': fwrite("&gt;", 4, 1, fp); bcount += 4; break;
+ case '&': fwrite("&amp;", 5, 1, fp); bcount += 5; break;
+ case '\"': fwrite("&quot;", 6, 1, fp); bcount += 6; break;
+ case '\'': fwrite("&apos;", 6, 1, fp); bcount += 6; break;
+ default:
+ // if (xmltypecheck[c] != 0)
+ {
+ // TODO: benski> optimize by scanning for the next character to be escaped (or NULL)
+ size_t numChars=1;
+ while (1)
+ {
+ wchar_t check = outstr.getValue()[i+numChars];
+ if (check == 0
+ || check == '<'
+ || check == '>'
+ || check == '&'
+ || check == '\''
+ || check == '\"')
+ break;
+ numChars++;
+ }
+ const wchar_t *str = outstr.getValue() + i;
+ int len = WideCharToMultiByte(CP_UTF8, 0, str, (int)numChars, 0, 0, 0, 0);
+ char *utf8 = (char *)malloc(len);
+ WideCharToMultiByte(CP_UTF8, 0, str, (int)numChars, utf8, len, 0, 0);
+ fwrite(utf8, len, 1, fp);
+ free(utf8);
+ bcount+=(int)numChars;
+ i+=(numChars-1);
+ }
+ break;
+ }
+ }
+ return bcount;
+}
diff --git a/Src/Wasabi/api/xml/xmlwrite.h b/Src/Wasabi/api/xml/xmlwrite.h
new file mode 100644
index 00000000..b4c55868
--- /dev/null
+++ b/Src/Wasabi/api/xml/xmlwrite.h
@@ -0,0 +1,45 @@
+#ifndef _XML_H
+#define _XML_H
+
+#include <bfc/wasabi_std.h>
+#include <bfc/stack.h>
+#include <bfc/string/StringW.h>
+
+class XMLWrite
+{
+public:
+ XMLWrite(const wchar_t *filename, const wchar_t *doctype, const wchar_t *dtddoctype = NULL, int no_hi_chars_conversion = 0);
+ XMLWrite(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype = NULL, int no_hi_chars_conversion = 0);
+ ~XMLWrite();
+
+ void Init(FILE *file, const wchar_t *doctype, const wchar_t *dtddoctype);
+
+ void comment(const wchar_t *comment);
+
+ void pushCategory(const wchar_t *title, int wantcr = 1, int wantindent = 1);
+
+ void pushCategoryAttrib(const wchar_t *title, int nodata = FALSE);
+ void writeCategoryAttrib(const wchar_t *title, const int val);
+ void writeCategoryAttrib(const wchar_t *title, const wchar_t *val);
+ void closeCategoryAttrib(int wantcr = 1);
+
+ void writeAttribEmpty(const wchar_t *title, int wantcr = 1, int wantindent = 1);
+ void writeAttrib(const wchar_t *title, const wchar_t *text, int wantcr = 1, int wantindent = 1);
+ void writeAttrib(const wchar_t *title, int val, int wantcr = 1, int wantindent = 1);
+ int popCategory(int wantcr = 1, int wantindent = 1); // returns nonzero if more categories are open
+
+ static int efprintf(FILE *fp, const wchar_t *format, ...);
+ static int utf8fprintf(FILE *fp, const wchar_t *format, ...);
+ static int eutf8fprintf(FILE *fp, const wchar_t *format, ...);
+
+private:
+ FILE *fp;
+ StringW indenter;
+// int indent;
+ Stack<wchar_t *>titles;
+ int nohicharconversion;
+};
+
+
+
+#endif