/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ /******************************************************************************* Version: 1.0 Author: Bastien BOURINEAU Date: 10/07/2012 Warning: loading too much bitmaps at start can take long and use uncessary large amount of memory *******************************************************************************/ struct PlugButton = [ PBTN_instance : PInstance, PBTN_bOnMaterial : I, PBTN_Material : SO3_MATERIAL, PBTN_iTechnique : I, PBTN_iPass : I, PBTN_iTexture : I, PBTN_win : SO3_WIDGET, PBTN_AlphaBuffer : AlphaBitmap, PBTN_AlphaDraw : AlphaBitmap, PBTN_iPosX : I, PBTN_iPosY : I, PBTN_iWidth : I, PBTN_iHeight : I, PBTN_tPercent : [I I I I I I I I], PBTN_tAlign : [I I], PBTN_bTransparency : I, PBTN_iOpacity : I, PBTN_iTransition : I, PBTN_fTransOpacity : F, PBTN_fontStyle : [S I I], PBTN_font : VUIfont, PBTN_sLabel : S, PBTN_ifColor : I, PBTN_bUrl : I, PBTN_sPath : S, PBTN_iClick : I, PBTN_bLastCursor : I, PBTN_bShowCursor : I, PBTN_bEnableMouse : I, PBTN_bShow : I, PBTN_iAvStates : I, PBTN_iState : I, PBTN_iNbFrames : I, PBTN_iCurFrame : I, PBTN_iTick : I, PBTN_iLastInputState : I, PBTN_tLastPos : [I I], PBTN_lInputs : [[S [I I]] r1], PBTN_trmMouseState : Timer, // to enable the mouse after touch manipulation PBTN_httpReq : ObjCURL, PBTN_iZorder : I, PBTN_bSplit : I, PBTN_iTouchHack : I ] MkPlugButton;; var sTmpDownloadPath = "tmp/buttons/";; var iTexWidth = 512;; var iTexHeight = 512;; var sHandCursor = "os3dlib/res/link_cursor.bmp";; typeof cHandCursor = ObjCursor;; typeof cPrevCursor = ObjCursor;; fun restoreTexture(btnstr)= V3DremoveWidgetControl (V3DgetDefaultViewport (V3DgetSessionView c3dXsession)) btnstr.PBTN_win; SO3WidgetDestroy btnstr.PBTN_win; set btnstr.PBTN_win = nil; _DSalphaBitmap btnstr.PBTN_AlphaBuffer; _DSalphaBitmap btnstr.PBTN_AlphaDraw; set btnstr.PBTN_AlphaDraw = nil; set btnstr.PBTN_AlphaBuffer = nil; if (!btnstr.PBTN_bShowCursor || !btnstr.PBTN_bLastCursor || (!V3DgetCursorVisible (V3DgetSessionView c3dXsession))) then nil else ( V3DsetCursor (V3DgetSessionView c3dXsession) cPrevCursor; set btnstr.PBTN_bLastCursor = 0; set cPrevCursor = nil; ); 0;; fun drawLabel(abmp, btnstr)= let _GETalphaBitmaps abmp -> [bmp bmp8] in let _GETbitmapSize bmp -> [bw bh] in let if (sizelist (strextr btnstr.PBTN_sLabel)) > 1 then 1 else 0 -> multilines in ( if (btnstr.PBTN_font != nil) then nil else let btnstr.PBTN_fontStyle -> [fname fsize fbold] in set btnstr.PBTN_font = VUIaddFont fname fsize (if fbold then iVUITEXT_BOLD else 0) btnstr.PBTN_ifColor 1 1; VUIdrawTextAlphaBitmap abmp btnstr.PBTN_font [0 0 bw bh] [0 0] btnstr.PBTN_ifColor iVUITEXT_HALIGNCENTER|iVUITEXT_VALIGNCENTER btnstr.PBTN_sLabel; ); 0;; fun updateButton(btnstr)= if (btnstr.PBTN_win == nil) then nil else let _GETalphaBitmapSize btnstr.PBTN_AlphaBuffer -> [bw bh] in let _GETalphaBitmapSize btnstr.PBTN_AlphaDraw -> [dbw dbh] in let bw / btnstr.PBTN_iNbFrames -> width in let bh / (btnstr.PBTN_iAvStates + 1) -> height in let (bw / btnstr.PBTN_iNbFrames) * btnstr.PBTN_iCurFrame -> wpos in let if (!btnstr.PBTN_iAvStates || (btnstr.PBTN_iState > btnstr.PBTN_iAvStates)) then 0 else (height * btnstr.PBTN_iState) -> ypos in ( if ((btnstr.PBTN_AlphaDraw == nil) || (dbw != width) || (dbh != height)) then ( _DSalphaBitmap btnstr.PBTN_AlphaDraw; let SO3WidgetGetSize btnstr.PBTN_win -> [ww wh] in let if btnstr.PBTN_bSplit then ww else width -> ww in let if btnstr.PBTN_bSplit then wh else height -> wh in let _CRbitmap _channel ww wh -> bmp24 in let _CRbitmap8 _channel ww wh -> bmp8 in set btnstr.PBTN_AlphaDraw = _CRalphaBitmap _channel bmp24 bmp8 nil nil; ) else nil; /*let _GETalphaBitmaps btnstr.PBTN_AlphaBuffer -> [colorLayer alphaLayer] in let _GETalphaBitmaps btnstr.PBTN_AlphaDraw -> [colorDraw alphaDraw] in ( _CPbitmap24 colorDraw 0 0 colorLayer wpos ypos width height nil; _CPbitmap8 alphaDraw 0 0 alphaLayer wpos ypos width height nil; );*/ G2DstrechAlphaBitmapRectToBackgroundBitmap btnstr.PBTN_AlphaBuffer [wpos ypos width height] btnstr.PBTN_AlphaDraw btnstr.PBTN_bSplit; if (!strcmp btnstr.PBTN_sLabel "") then nil else drawLabel btnstr.PBTN_AlphaDraw btnstr; SO3BitmapWidgetBlitAlpha btnstr.PBTN_win btnstr.PBTN_AlphaDraw; //TODO use a final buffer and do not create an alphabitmap each time /* let G2DstrechAlphaBitmapToBackgroundBitmap _channel btnstr.PBTN_AlphaDraw btnstr.PBTN_iWidth btnstr.PBTN_iHeight -> nabmp in ( if (!strcmp btnstr.PBTN_sLabel "") then nil else drawLabel nabmp btnstr; SO3BitmapWidgetBlitAlpha btnstr.PBTN_win nabmp; ); */ ); 0;; fun computePosSize(btnstr, vw, vh)= let btnstr.PBTN_tPercent -> [px py pw ph xo yo wo ho] in let btnstr.PBTN_tAlign -> [ax ay] in let if pw then (ftoi (((itof btnstr.PBTN_iWidth) /. 100.0) *. (itof vw))) + wo else btnstr.PBTN_iWidth -> pw in let if ph then (ftoi (((itof btnstr.PBTN_iHeight) /. 100.0) *. (itof vh))) + ho else btnstr.PBTN_iHeight -> ph in let if px then (ftoi (((itof btnstr.PBTN_iPosX) /. 100.0) *. (itof vw))) + xo else btnstr.PBTN_iPosX -> px in let if (ax == 1) then ((vw / 2) - (pw / 2)) + px else if (ax == 2) then (vw - pw) - px else px -> px in let if py then (ftoi (((itof btnstr.PBTN_iPosY) /. 100.0) *. (itof vh))) + yo else btnstr.PBTN_iPosY -> py in let if (ay == 1) then ((vh / 2) - (ph / 2)) + py else if (ay == 2) then (vh - ph) - py else py -> py in [px py pw ph];; fun updateSizePos(btnstr)= if btnstr.PBTN_win == nil || btnstr.PBTN_bOnMaterial then nil else let V3DgetSessionView c3dXsession -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in let computePosSize btnstr vw vh -> [px py pw ph] in ( //addLogMessage strcatn "View : "::(itoa vw)::" - "::(itoa vh)::nil; //addLogMessage strcatn "Position : "::(itoa px)::" - "::(itoa py)::" - "::(itoa pw)::"x"::(itoa ph)::nil; SO3WidgetSetPosition btnstr.PBTN_win px py; SO3WidgetSetSize btnstr.PBTN_win pw ph; updateButton btnstr; ); 0;; fun cbResizeCtrl(inst, viewstr, ww, wh, btnstr)= updateSizePos btnstr; 0;; fun cbMouseIn(widget, btnstr)= if(btnstr.PBTN_iState == 3) || (btnstr.PBTN_iClick != 0) then nil else ( set btnstr.PBTN_iState = 1; let V3DgetSessionView c3dXsession -> viewstr in if (!btnstr.PBTN_bShowCursor || btnstr.PBTN_bLastCursor || (!V3DgetCursorVisible viewstr)) then nil else ( set btnstr.PBTN_bLastCursor = 1; let V3DgetCursor viewstr -> pcursor in if (pcursor == cHandCursor) then nil else set cPrevCursor = pcursor; V3DsetCursor viewstr cHandCursor; ); //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "MouseOver" nil nil; ); 0;; fun cbMouseOut(widget, btnstr)= if(btnstr.PBTN_iState == 3) then nil else ( if (btnstr.PBTN_iClick != 0) then nil else ( let V3DgetSessionView c3dXsession -> viewstr in if (!btnstr.PBTN_bShowCursor || !btnstr.PBTN_bLastCursor || (!V3DgetCursorVisible viewstr)) then nil else ( set btnstr.PBTN_bLastCursor = 0; V3DsetCursor viewstr cPrevCursor; set cPrevCursor = nil; ); set btnstr.PBTN_iState = 0; //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); //SendPluginEvent btnstr.PBTN_instance "Released" nil nil; SendPluginEvent btnstr.PBTN_instance "MouseOut" nil nil; ); ); 0;; fun cbClick(widget, btnstr, x, y, btn)= if(btnstr.PBTN_iState == 3) then nil else let 0 -> pushed in ( if (btnstr.PBTN_iState == 2) && (btnstr.PBTN_iClick == 0) then nil else ( set pushed = 1; set btnstr.PBTN_tLastPos = [x y]; ); set btnstr.PBTN_iClick = btnstr.PBTN_iClick|btn; set btnstr.PBTN_iState = 2; if(btnstr.PBTN_iAvStates <= 1) then nil else //update bitmap ( updateButton btnstr; 0; ); if (!pushed) then nil else SendPluginEvent btnstr.PBTN_instance "Pushed" nil nil; ); 0;; fun cbUnClick(widget, btnstr, x, y, btn)= if (btnstr.PBTN_iState == 3) then nil else let btnstr.PBTN_iState -> lstate in ( set btnstr.PBTN_iState = if (SO3WidgetIsMouseOver btnstr.PBTN_win) then 1 else 0; //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); if (lstate != 2) then nil else ( set btnstr.PBTN_tLastPos = nil; SendPluginEvent btnstr.PBTN_instance "Released" nil nil; if (SO3WidgetIsMouseOver btnstr.PBTN_win) then nil else ( SendPluginEvent btnstr.PBTN_instance "MouseOut" nil nil; ); ); if (!SO3WidgetIsMouseOver btnstr.PBTN_win) then ( let V3DgetSessionView c3dXsession -> viewstr in if (!btnstr.PBTN_bShowCursor || !btnstr.PBTN_bLastCursor || (!V3DgetCursorVisible viewstr)) then nil else ( set btnstr.PBTN_bLastCursor = 0; V3DsetCursor viewstr cPrevCursor; set cPrevCursor = nil; ); SendPluginEvent btnstr.PBTN_instance "MouseOut" nil nil; 0; ) else ( if btn == 1 then SendPluginEvent btnstr.PBTN_instance "LeftClick" nil nil else if btn == 2 then SendPluginEvent btnstr.PBTN_instance "RightClick" nil nil else if btn == 16 then SendPluginEvent btnstr.PBTN_instance "MiddleClick" nil nil else nil; 0; ); ); SO3WidgetUnFocus btnstr.PBTN_win; set btnstr.PBTN_iClick = 0; 0;; fun cbMouseMove(widget, btnstr, x, y, btn)= if (btnstr.PBTN_iClick == 0) || (btnstr.PBTN_tLastPos == nil) then nil else let btnstr.PBTN_tLastPos -> [px py] in let (min btnstr.PBTN_iWidth btnstr.PBTN_iHeight) -> msize in let if msize <= 0 then 1 else msize -> msize in let (itof (x - px)) /. (itof msize) -> fx in let if (fx >. 1.0) then 1.0 else if (fx <. (-.1.0)) then (-.1.0) else fx -> fx in let (itof (py - y)) /. (itof msize) -> fy in let if (fy >. 1.0) then 1.0 else if (fy <. (-.1.0)) then (-.1.0) else fy -> fy in ( SendPluginEvent btnstr.PBTN_instance "Pushed move" strcatn (ftoa fx)::" "::(ftoa fy)::nil nil; ); 0;; fun cbFocused(widget, btnstr, state)= if (state || (btnstr.PBTN_iState != 2) || (btnstr.PBTN_iClick == 0)) then nil else ( set btnstr.PBTN_tLastPos = nil; set btnstr.PBTN_iClick = 0; set btnstr.PBTN_iState = 0; //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "Released" nil nil; let V3DgetSessionView c3dXsession -> viewstr in if (!btnstr.PBTN_bShowCursor || !btnstr.PBTN_bLastCursor || (!V3DgetCursorVisible viewstr)) then nil else ( set btnstr.PBTN_bLastCursor = 0; V3DsetCursor viewstr cPrevCursor; set cPrevCursor = nil; ); SendPluginEvent btnstr.PBTN_instance "MouseOut" nil nil; ); 0;; fun createPicture(inst, btnstr)= let V3DgetSessionView c3dXsession -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in if btnstr.PBTN_win != nil then nil else ( V3DremoveWidgetControl viewportstr btnstr.PBTN_win; SO3WidgetDestroy btnstr.PBTN_win; if btnstr.PBTN_bOnMaterial then ( set btnstr.PBTN_win = SO3BitmapWidgetCreateOnMaterial (V3DgetSession c3dXsession) btnstr.PBTN_Material (strcat (getPluginInstanceName inst) "_pictureCtrl") btnstr.PBTN_iWidth btnstr.PBTN_iHeight btnstr.PBTN_iTechnique btnstr.PBTN_iPass btnstr.PBTN_iTexture; 0; ) else ( let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in let computePosSize btnstr vw vh -> [px py pw ph] in set btnstr.PBTN_win = SO3BitmapWidgetCreate (V3DgetSession c3dXsession) viewportstr.V3D_viewport (strcat (getPluginInstanceName inst) "_pictureCtrl") px py pw ph btnstr.PBTN_iZorder; SO3WidgetSetTopOnFocus btnstr.PBTN_win 0; SO3WidgetSetForeground btnstr.PBTN_win 1; 0; ); SO3WidgetEnterEventCb btnstr.PBTN_win @cbMouseIn btnstr; SO3WidgetExitEventCb btnstr.PBTN_win @cbMouseOut btnstr; SO3WidgetMouseDownEventCb btnstr.PBTN_win @cbClick btnstr; SO3WidgetMouseUpEventCb btnstr.PBTN_win @cbUnClick btnstr; SO3WidgetMouseMoveEventCb btnstr.PBTN_win @cbMouseMove btnstr; SO3WidgetFocusEventCb btnstr.PBTN_win @cbFocused btnstr; V3DaddWidgetControl viewportstr btnstr.PBTN_win; SO3WidgetSetKeyboardEnable btnstr.PBTN_win 0; SO3WidgetSetMouseEnable btnstr.PBTN_win btnstr.PBTN_bEnableMouse; SO3WidgetSetTransparency btnstr.PBTN_win btnstr.PBTN_bTransparency; SO3WidgetSetOpacity btnstr.PBTN_win (itof btnstr.PBTN_iOpacity) *. 0.01; SO3WidgetSetVisibility btnstr.PBTN_win 0; ); 0;; // button animation is updated at 10 FPS fun cbControlPreRenderAnim(inst, sessionstr, etime, btnstr)= let if etime <= 1000 then 1000 else etime -> etime in let (set btnstr.PBTN_iTick = btnstr.PBTN_iTick + (etime / 1000)) -> rtick in if (rtick < (1000 / 10)) then nil else ( set btnstr.PBTN_iCurFrame = btnstr.PBTN_iCurFrame + 1; if (btnstr.PBTN_iCurFrame < (btnstr.PBTN_iNbFrames - 1)) then nil else set btnstr.PBTN_iCurFrame = 0; updateButton btnstr; set btnstr.PBTN_iTick = 0; ); 0;; fun cbControlPreRenderShow(inst, sessionstr, etime, btnstr)= let if etime <= 1000 then 1000 else etime -> etime in let (itof btnstr.PBTN_iOpacity) /. (itof btnstr.PBTN_iTransition) -> step in ( set btnstr.PBTN_fTransOpacity = btnstr.PBTN_fTransOpacity +. (step *. (itof (etime / 1000))); if btnstr.PBTN_fTransOpacity >=. (itof btnstr.PBTN_iOpacity) then ( set btnstr.PBTN_fTransOpacity = itof btnstr.PBTN_iOpacity; SO3WidgetSetOpacity btnstr.PBTN_win (itof btnstr.PBTN_iOpacity) *. 0.01; if (btnstr.PBTN_iNbFrames <= 1) then setPluginInstanceCbScenePreRender inst nil else setPluginInstanceCbScenePreRender btnstr.PBTN_instance mkfun4 @cbControlPreRenderAnim btnstr; SendPluginEvent btnstr.PBTN_instance "Shown" nil nil; 0; ) else ( SO3WidgetSetOpacity btnstr.PBTN_win (btnstr.PBTN_fTransOpacity *. 0.01); 0; ); ); if (btnstr.PBTN_iNbFrames <= 1) then nil else cbControlPreRenderAnim inst sessionstr etime btnstr; 0;; fun cbControlPreRenderHide(inst, sessionstr, etime, btnstr)= let if etime <= 1000 then 1000 else etime -> etime in let (itof btnstr.PBTN_iOpacity) /. (itof btnstr.PBTN_iTransition) -> step in ( set btnstr.PBTN_fTransOpacity = btnstr.PBTN_fTransOpacity -. (step *. (itof (etime / 1000))); if btnstr.PBTN_fTransOpacity <=. 0.0 then ( set btnstr.PBTN_fTransOpacity = 0.0; SO3WidgetSetOpacity btnstr.PBTN_win 0.0; setPluginInstanceCbScenePreRender inst nil; if (btnstr.PBTN_win == nil) then nil else ( V3DremoveWidgetControl (V3DgetDefaultViewport (V3DgetSessionView c3dXsession)) btnstr.PBTN_win; SO3WidgetDestroy btnstr.PBTN_win; set btnstr.PBTN_win = nil; _DSalphaBitmap btnstr.PBTN_AlphaBuffer; set btnstr.PBTN_AlphaBuffer = nil; _DSalphaBitmap btnstr.PBTN_AlphaDraw; set btnstr.PBTN_AlphaDraw = nil; SendPluginEvent btnstr.PBTN_instance "Hidden" nil nil; ); 0; ) else ( SO3WidgetSetOpacity btnstr.PBTN_win (btnstr.PBTN_fTransOpacity *. 0.01); 0; ); ); if (btnstr.PBTN_iNbFrames <= 1) then nil else cbControlPreRenderAnim inst sessionstr etime btnstr; 0;; fun cbDownloaded(file, data, btnstr)= if data == nil then nil else let strcatn sTmpDownloadPath::(getPluginInstanceName btnstr.PBTN_instance)::".tmp"::nil -> tmpfile in ( _storepack data tmpfile; let G2DloadAlphaBmp _channel tmpfile -> bmp in if bmp == nil then nil else ( if(btnstr.PBTN_iState >= 2) then nil else set btnstr.PBTN_iState = 0; _DSalphaBitmap btnstr.PBTN_AlphaBuffer; set btnstr.PBTN_AlphaBuffer = bmp; if (!btnstr.PBTN_bShow) then nil else ( createPicture btnstr.PBTN_instance btnstr; updateButton btnstr; if (btnstr.PBTN_iTransition == 0) then ( SO3WidgetSetVisibility btnstr.PBTN_win 1; if (btnstr.PBTN_iNbFrames <= 1) then nil else setPluginInstanceCbScenePreRender btnstr.PBTN_instance mkfun4 @cbControlPreRenderAnim btnstr; SendPluginEvent btnstr.PBTN_instance "Shown" nil nil; 0; ) else ( SO3WidgetSetOpacity btnstr.PBTN_win (btnstr.PBTN_fTransOpacity *. 0.01); SO3WidgetSetVisibility btnstr.PBTN_win 1; setPluginInstanceCbScenePreRender btnstr.PBTN_instance mkfun4 @cbControlPreRenderShow btnstr; 0; ); ); ); ); 0;; fun cbChange(inst, from, action, param, reply, btnstr)= let if param == nil then btnstr.PBTN_bUrl else strIsUrl param -> isurl in let if param == nil then btnstr.PBTN_sPath else param -> url in ( set btnstr.PBTN_bUrl = isurl; set btnstr.PBTN_sPath = url; if (!btnstr.PBTN_bShow) then nil else ( if(btnstr.PBTN_iState >= 2) then nil else set btnstr.PBTN_iState = 0; if !btnstr.PBTN_bUrl then ( let G2DloadAlphaBmp _channel btnstr.PBTN_sPath -> bmp in if bmp == nil then nil else ( set btnstr.PBTN_AlphaBuffer = bmp; createPicture inst btnstr; updateButton btnstr; SO3WidgetSetVisibility btnstr.PBTN_win 1; ); 0; ) else ( if (btnstr.PBTN_httpReq == nil) then nil else ( killHttpRequest btnstr.PBTN_httpReq; set btnstr.PBTN_httpReq = nil; ); set btnstr.PBTN_httpReq = downloadFile btnstr.PBTN_sPath mkfun3 @cbDownloaded btnstr; 0; ); ); ); 0;; fun cbEnable(inst, from, action, param, reply, btnstr)= set btnstr.PBTN_iState = 0; if(btnstr.PBTN_iAvStates <= 0) then nil else updateButton btnstr; 0;; fun cbDisable(inst, from, action, param, reply, btnstr)= set btnstr.PBTN_iState = 3; if(btnstr.PBTN_iAvStates <= 1) then nil else updateButton btnstr; 0;; fun cbSetLabel(inst, from, action, param, reply, btnstr)= set btnstr.PBTN_sLabel = param; updateButton btnstr; 0;; fun cbSendLeftClick(inst, from, action, param, reply, btnstr)= if (!btnstr.PBTN_bShow) then nil else SendPluginEvent btnstr.PBTN_instance "LeftClick" nil nil; 0;; fun cbSendRightClick(inst, from, action, param, reply, btnstr)= if (!btnstr.PBTN_bShow) then nil else SendPluginEvent btnstr.PBTN_instance "RightClick" nil nil; 0;; fun cbSendMiddleClick(inst, from, action, param, reply, btnstr)= if (!btnstr.PBTN_bShow) then nil else SendPluginEvent btnstr.PBTN_instance "MiddleClick" nil nil; 0;; fun cbSetState(inst, from, action, param, reply, btnstr)= let strtrim param -> param in if (!strcmpi param "Active") || ((atoi param) == 1) then ( // active state set btnstr.PBTN_iState = 0; if(btnstr.PBTN_iAvStates <= 0) then nil else //update bitmap ( updateButton btnstr; 0; ); 0; ) else if (!strcmpi param "Hover") || ((atoi param) == 2) then ( // hover state set btnstr.PBTN_iState = 1; if(btnstr.PBTN_iAvStates <= 0) then nil else //update bitmap ( updateButton btnstr; 0; ); 0; ) else if (!strcmpi param "Down") || ((atoi param) == 3) then ( // hover state set btnstr.PBTN_iState = 2; if(btnstr.PBTN_iAvStates <= 0) then nil else //update bitmap ( updateButton btnstr; 0; ); 0; ) else if (!strcmpi param "Disable") || ((atoi param) == 4) then ( // disable state set btnstr.PBTN_iState = 3; if(btnstr.PBTN_iAvStates <= 1) then nil else //update bitmap ( updateButton btnstr; 0; ); 0; ) else nil; 0;; fun cbShow(inst, from, action, param, reply, btnstr)= if (btnstr.PBTN_bShow) then nil else ( setPluginInstanceCbScenePreRender inst nil; set btnstr.PBTN_bShow = 1; if(btnstr.PBTN_iState >= 2) then nil else set btnstr.PBTN_iState = 0; if !btnstr.PBTN_bUrl then ( let G2DloadAlphaBmp _channel btnstr.PBTN_sPath -> bmp in if bmp == nil then nil else ( set btnstr.PBTN_AlphaBuffer = bmp; createPicture inst btnstr; updateButton btnstr; if (btnstr.PBTN_iTransition == 0) then ( SO3WidgetSetVisibility btnstr.PBTN_win 1; if (btnstr.PBTN_iNbFrames <= 1) then nil else setPluginInstanceCbScenePreRender btnstr.PBTN_instance mkfun4 @cbControlPreRenderAnim btnstr; SendPluginEvent btnstr.PBTN_instance "Shown" nil nil; 0; ) else ( SO3WidgetSetOpacity btnstr.PBTN_win (btnstr.PBTN_fTransOpacity *. 0.01); SO3WidgetSetVisibility btnstr.PBTN_win 1; setPluginInstanceCbScenePreRender inst mkfun4 @cbControlPreRenderShow btnstr; 0; ); ); updateSizePos btnstr; 0; ) else ( if (btnstr.PBTN_httpReq == nil) then nil else ( killHttpRequest btnstr.PBTN_httpReq; set btnstr.PBTN_httpReq = nil; ); set btnstr.PBTN_httpReq = downloadFile btnstr.PBTN_sPath mkfun3 @cbDownloaded btnstr; 0; ); ); 0;; fun cbHide(inst, from, action, param, reply, btnstr)= if (!btnstr.PBTN_bShow) then nil else ( setPluginInstanceCbScenePreRender inst nil; set btnstr.PBTN_lInputs = nil; set btnstr.PBTN_bShow = 0; if(btnstr.PBTN_iState >= 2) then nil else set btnstr.PBTN_iState = 0; if (!btnstr.PBTN_bShowCursor || !btnstr.PBTN_bLastCursor || (!V3DgetCursorVisible (V3DgetSessionView c3dXsession))) then nil else ( set btnstr.PBTN_bLastCursor = 0; V3DsetCursor (V3DgetSessionView c3dXsession) cPrevCursor; set cPrevCursor = nil; ); if (btnstr.PBTN_iTransition == 0) then ( if (btnstr.PBTN_win == nil) then nil else ( V3DremoveWidgetControl (V3DgetDefaultViewport (V3DgetSessionView c3dXsession)) btnstr.PBTN_win; SO3WidgetDestroy btnstr.PBTN_win; set btnstr.PBTN_win = nil; _DSalphaBitmap btnstr.PBTN_AlphaBuffer; set btnstr.PBTN_AlphaBuffer = nil; _DSalphaBitmap btnstr.PBTN_AlphaDraw; set btnstr.PBTN_AlphaDraw = nil; SendPluginEvent btnstr.PBTN_instance "Hidden" nil nil; ); 0; ) else ( set btnstr.PBTN_lInputs = nil; SO3WidgetSetOpacity btnstr.PBTN_win (btnstr.PBTN_fTransOpacity *. 0.01); setPluginInstanceCbScenePreRender inst mkfun4 @cbControlPreRenderHide btnstr; 0; ); ); 0;; fun cbInput(inst, from, action, param, reply, btnstr)= if (!btnstr.PBTN_bShow) || (param == nil) || (btnstr.PBTN_win == nil) then nil else let strextr param -> lp in let atoi (nth_list (hd lp) 0) -> sx in let atoi (nth_list (hd lp) 1) -> sy in let V3DgetSessionView c3dXsession -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in let computePosSize btnstr vw vh -> [px py pw ph] in ( let switchstr btnstr.PBTN_lInputs from -> icontrol in ( // if not already int the list we add it if (icontrol == nil) then ( set btnstr.PBTN_lInputs = [from [sx sy]]::btnstr.PBTN_lInputs; 0; ) else ( mutate icontrol <- [sx sy]; 0; ); ); let sizelist btnstr.PBTN_lInputs -> size in let 0 -> i in let 0 -> over in ( while (i < size) do ( let nth_list btnstr.PBTN_lInputs i -> [n [sx sy]] in if ((sx > px) && (sx < (px + pw)) && (sy > py) && (sy < (py + ph))) then set over = 1 else nil; set i = i + 1; ); if (over == 1) then ( if (btnstr.PBTN_iLastInputState) then nil else ( set btnstr.PBTN_iLastInputState = 1; cbMouseIn nil btnstr; ); 0; ) else if (!btnstr.PBTN_iLastInputState) then nil else ( set btnstr.PBTN_iLastInputState = 0; cbMouseOut nil btnstr; 0; ); ); ); 0;; // multi touch fun cbAddCursor(inst, viewstr, id, sx, sy, btnstr)= if (!btnstr.PBTN_bShow) || (btnstr.PBTN_win == nil) || (btnstr.PBTN_iClick != 0) then nil else ( if (btnstr.PBTN_trmMouseState == nil) then nil else ( _deltimer btnstr.PBTN_trmMouseState; set btnstr.PBTN_trmMouseState = nil; ); //disable mouse SO3WidgetEnterEventCb btnstr.PBTN_win nil nil; SO3WidgetExitEventCb btnstr.PBTN_win nil nil; SO3WidgetMouseDownEventCb btnstr.PBTN_win nil nil; SO3WidgetMouseUpEventCb btnstr.PBTN_win nil nil; SO3WidgetMouseMoveEventCb btnstr.PBTN_win nil nil; SO3WidgetFocusEventCb btnstr.PBTN_win @cbFocused nil; set btnstr.PBTN_iClick = 0; let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in let computePosSize btnstr vw vh -> [px py pw ph] in ( if ((sx > px) && (sx < (px + pw)) && (sy > py) && (sy < (py + ph))) then let switchstr btnstr.PBTN_lInputs (itoa id) -> icontrol in ( // if not already int the list we add it if (icontrol == nil) then ( set btnstr.PBTN_lInputs = [(itoa id) [sx sy]]::btnstr.PBTN_lInputs; 0; ) else ( mutate icontrol <- [sx sy]; 0; ); if (btnstr.PBTN_iState >= 2) then nil else ( set btnstr.PBTN_iState = 1; //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "MouseOver" nil nil; set btnstr.PBTN_iState = 2; //update bitmap if(btnstr.PBTN_iAvStates <= 1) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "Pushed" nil nil; set btnstr.PBTN_tLastPos = [sx sy]; ); ) else nil; ); ); 0;; fun cbUpdateCursor(inst, viewstr, id, sx, sy, vx, vy, btnstr)= if (!btnstr.PBTN_bShow) || (btnstr.PBTN_win == nil) then nil else ( let switchstr btnstr.PBTN_lInputs (itoa id) -> icontrol in if (icontrol == nil) || (btnstr.PBTN_tLastPos == nil) then nil else ( let icontrol -> [ppx ppy] in if ((ppx == sx) && (ppy == sy)) then nil else ( mutate icontrol <- [sx sy]; let btnstr.PBTN_tLastPos -> [px py] in let (min btnstr.PBTN_iWidth btnstr.PBTN_iHeight) -> msize in let (itof (sx - px)) /. (itof msize) -> fx in let if (fx >. 1.0) then 1.0 else if (fx <. (-.1.0)) then (-.1.0) else fx -> fx in let (itof (py - sy)) /. (itof msize) -> fy in let if (fy >. 1.0) then 1.0 else if (fy <. (-.1.0)) then (-.1.0) else fy -> fy in SendPluginEvent btnstr.PBTN_instance "Pushed move" strcatn (ftoa fx)::" "::(ftoa fy)::nil nil; ); ); ); /* let (V3DgetDefaultViewport (V3DgetSessionView c3dXsession)) -> viewportstr in let SO3ViewportGetPixelPositionSize viewportstr.V3D_viewport -> [_ _ vw vh] in let computePosSize btnstr vw vh -> [px py pw ph] in ( let switchstr btnstr.PBTN_lInputs (itoa id) -> icontrol in if (icontrol == nil) then nil else if ((sx > px) && (sx < (px + pw)) && (sy > py) && (sy < (py + ph))) then ( mutate icontrol <- [sx sy]; if (btnstr.PBTN_iState == 3) || (btnstr.PBTN_iState == 2) then nil else ( set btnstr.PBTN_iState = 1; //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "MouseOver" nil nil; set btnstr.PBTN_iState = 2; //update bitmap if(btnstr.PBTN_iAvStates <= 1) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "Pushed" nil nil; ); ) else ( mutate icontrol <- [sx sy]; let sizelist btnstr.PBTN_lInputs -> size in let 0 -> i in let 0 -> over in ( while (i < size) do ( let nth_list btnstr.PBTN_lInputs i -> [n [sx sy]] in if ((sx > px) && (sx < (px + pw)) && (sy > py) && (sy < (py + ph))) then set over = 1 else nil; set i = i + 1; ); if (over == 1) then nil else ( if(btnstr.PBTN_iState == 3) || (btnstr.PBTN_iState == 0) then nil else ( set btnstr.PBTN_iState = 0; //update bitmap if(btnstr.PBTN_iAvStates <= 0) then nil else ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "Released" nil nil; SendPluginEvent btnstr.PBTN_instance "MouseOut" nil nil; ); ); ); ); );*/ 0;; fun cbResetMouse(trm, btnstr)= _deltimer trm; set btnstr.PBTN_trmMouseState = nil; SO3WidgetEnterEventCb btnstr.PBTN_win @cbMouseIn btnstr; SO3WidgetExitEventCb btnstr.PBTN_win @cbMouseOut btnstr; SO3WidgetMouseDownEventCb btnstr.PBTN_win @cbClick btnstr; SO3WidgetMouseUpEventCb btnstr.PBTN_win @cbUnClick btnstr; SO3WidgetMouseMoveEventCb btnstr.PBTN_win @cbMouseMove btnstr; SO3WidgetFocusEventCb btnstr.PBTN_win @cbFocused btnstr; 0;; // enable mouse after a possible render lock depending of the action fun cbControlPostRender(inst, sessionstr, etime, btnstr)= set btnstr.PBTN_iTouchHack = btnstr.PBTN_iTouchHack + 1; if ((sizelist btnstr.PBTN_lInputs) > 0) || btnstr.PBTN_iTouchHack < 3 then nil else ( set btnstr.PBTN_iTouchHack = 0; setPluginInstanceCbScenePostRender btnstr.PBTN_instance nil; set btnstr.PBTN_trmMouseState = _rfltimer _starttimer _channel 500 @cbResetMouse btnstr; ); 0;; fun cbRemoveCursor(inst, viewstr, id, btnstr)= let switchstr btnstr.PBTN_lInputs (itoa id) -> icontrol in if (icontrol == nil) then nil else let icontrol -> [sx sy] in let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in let computePosSize btnstr vw vh -> [px py pw ph] in ( let sizelist btnstr.PBTN_lInputs -> size in let 0 -> i in let 0 -> over in ( while (i < size) do ( let nth_list btnstr.PBTN_lInputs i -> [n [sx sy]] in if ((sx > px) && (sx < (px + pw)) && (sy > py) && (sy < (py + ph)) && (id != (atoi n))) then set over = 1 else nil; set i = i + 1; ); if (over == 1) then nil else ( if (btnstr.PBTN_iState == 3) || (btnstr.PBTN_iState == 0) then nil else ( set btnstr.PBTN_iState = 0; if(btnstr.PBTN_iAvStates <= 0) then nil else //update bitmap ( updateButton btnstr; 0; ); SendPluginEvent btnstr.PBTN_instance "Released" nil nil; SendPluginEvent btnstr.PBTN_instance "MouseOut" nil nil; if ((sx > px) && (sx < (px + pw)) && (sy > py) && (sy < (py + ph))) then ( SendPluginEvent btnstr.PBTN_instance "LeftClick" nil nil; ) else nil; set btnstr.PBTN_tLastPos = nil; ); SO3WidgetUnFocus btnstr.PBTN_win; ); ); ); set btnstr.PBTN_lInputs = remove_sid_from_list btnstr.PBTN_lInputs (itoa id); //enable mouse again if ((sizelist btnstr.PBTN_lInputs) > 0) then nil else ( setPluginInstanceCbScenePostRender btnstr.PBTN_instance mkfun4 @cbControlPostRender btnstr; ); 0;; fun cbSetPosition(inst, from, action, param, reply, btnstr)= if param == nil then nil else let strextr param -> lp in let (nth_list (hd lp) 0) -> sx in let (nth_list (hd lp) 1) -> sy in let V3DgetSessionView c3dXsession -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in ( let 0 -> xpercent in let if (!strcmp "%" (substr sx ((strlen sx) - 1) 1)) then ( set xpercent = 1; atoi sx; ) else atoi sx -> px in let 0 -> ypercent in let if (!strcmp "%" (substr sy ((strlen sy) - 1) 1)) then ( set ypercent = 1; atoi sy; ) else atoi sy -> py in let [(if px == nil then 0 else px) (if py == nil then 0 else py)] -> [px py] in ( mutate btnstr.PBTN_tPercent <- [xpercent ypercent _ _ _ _ _ _]; set btnstr.PBTN_iPosX = px; set btnstr.PBTN_iPosY = py; let computePosSize btnstr vw vh -> [px py pw ph] in ( SO3WidgetSetPosition btnstr.PBTN_win px py; SO3WidgetSetSize btnstr.PBTN_win pw ph; updateButton btnstr; ); ); ); 0;; fun cbSetSize(inst, from, action, param, reply, btnstr)= if param == nil then nil else let strextr param -> lp in let (nth_list (hd lp) 0) -> sx in let (nth_list (hd lp) 1) -> sy in let V3DgetSessionView c3dXsession -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ vw vh] in ( let 0 -> wpercent in let if (!strcmp "%" (substr sx ((strlen sx) - 1) 1)) then ( set wpercent = 1; atoi sx; ) else atoi sx -> px in let 0 -> hpercent in let if (!strcmp "%" (substr sy ((strlen sy) - 1) 1)) then ( set hpercent = 1; atoi sy; ) else atoi sy -> py in let [(if px == nil then 0 else px) (if py == nil then 0 else py)] -> [px py] in ( mutate btnstr.PBTN_tPercent <- [_ _ wpercent hpercent _ _ _ _]; set btnstr.PBTN_iWidth = px; set btnstr.PBTN_iHeight = py; let computePosSize btnstr vw vh -> [px py pw ph] in ( SO3WidgetSetPosition btnstr.PBTN_win px py; SO3WidgetSetSize btnstr.PBTN_win pw ph; updateButton btnstr; ); ); ); 0;; fun cbSetOpacity(inst, from, action, param, reply, btnstr)= if (param == nil) || (!strcmp "" strtrim param) || ((atoi param) == nil) then nil else let atoi param -> opacity in ( set btnstr.PBTN_iOpacity = opacity; SO3WidgetSetOpacity btnstr.PBTN_win (itof btnstr.PBTN_iOpacity) *. 0.01; ); 0;; fun cbSetColor(inst, from, action, param, reply, btnstr)= let hd strextr param -> lp in let atoi hd lp -> pr in let atoi hd tl lp -> pg in let atoi hd tl tl lp -> pb in let make_rgb (if pr == nil then 0 else pr) (if pg == nil then 0 else pg) (if pb == nil then 0 else pb) -> fcolor in set btnstr.PBTN_ifColor = fcolor; updateButton btnstr; 0;; // Destroy instance fun deleteOb(inst, btnstr)= setPluginInstanceCbScenePreRender inst nil; if (btnstr.PBTN_trmMouseState == nil) then nil else ( _deltimer btnstr.PBTN_trmMouseState; set btnstr.PBTN_trmMouseState = nil; ); if (btnstr.PBTN_httpReq == nil) then nil else ( killHttpRequest btnstr.PBTN_httpReq; set btnstr.PBTN_httpReq = nil; ); VUIdelFont btnstr.PBTN_font; restoreTexture btnstr; 0;; fun cbNewOb(inst)= let (getPluginInstanceParam inst "object") -> objname in let (getPluginInstanceParam inst "material") -> matname in let atoi (getPluginInstanceParam inst "technique") -> technique in let if (technique == nil) || (technique < 0) then 0 else technique -> technique in let atoi (getPluginInstanceParam inst "pass") -> pass in let if (pass == nil) || (pass < 0) then 0 else pass -> pass in let atoi (getPluginInstanceParam inst "texture") -> texture in let if (texture == nil) || (texture < 0) then 0 else texture -> texture in let atoi (getPluginInstanceParam inst "istexture") -> istexture in let if istexture == nil then 0 else istexture -> istexture in let (getPluginInstanceParam inst "path") -> path in let atoi (getPluginInstanceParam inst "isurl") -> isurl in let if isurl == nil then 0 else isurl -> isurl in let (getPluginInstanceParam inst "url") -> url in let atoi (getPluginInstanceParam inst "btnstates") -> btnstates in let if btnstates == nil then 0 else btnstates -> btnstates in let atoi (getPluginInstanceParam inst "nbframes") -> nbframes in let if (nbframes == nil) || (nbframes < 1) then 1 else nbframes -> nbframes in let atoi (getPluginInstanceParam inst "xpercent") -> xpercent in let if xpercent == nil then 0 else xpercent -> xpercent in let atoi (getPluginInstanceParam inst "xalign") -> xalign in let if xalign == nil then 0 else xalign -> xalign in let atoi (getPluginInstanceParam inst "posx") -> posx in let if posx == nil then 0 else posx -> posx in let atoi (getPluginInstanceParam inst "ypercent") -> ypercent in let if ypercent == nil then 0 else ypercent -> ypercent in let atoi (getPluginInstanceParam inst "yalign") -> yalign in let if yalign == nil then 0 else yalign -> yalign in let atoi (getPluginInstanceParam inst "posy") -> posy in let if posy == nil then 0 else posy -> posy in let atoi (getPluginInstanceParam inst "wpercent") -> wpercent in let if wpercent == nil then 0 else wpercent -> wpercent in let atoi (getPluginInstanceParam inst "width") -> width in let if width == nil then 100 else width -> width in let atoi (getPluginInstanceParam inst "hpercent") -> hpercent in let if hpercent == nil then 0 else hpercent -> hpercent in let atoi (getPluginInstanceParam inst "xoffset") -> xoffset in let if xoffset == nil then 0 else xoffset -> xoffset in let atoi (getPluginInstanceParam inst "yoffset") -> yoffset in let if yoffset == nil then 0 else yoffset -> yoffset in let atoi (getPluginInstanceParam inst "woffset") -> woffset in let if woffset == nil then 0 else woffset -> woffset in let atoi (getPluginInstanceParam inst "hoffset") -> hoffset in let if hoffset == nil then 0 else hoffset -> hoffset in let atoi (getPluginInstanceParam inst "height") -> height in let if height == nil then 100 else height -> height in let getPluginInstanceParam inst "fontname" -> fname in let if fname == nil then "Sans" else fname -> fname in let atoi (getPluginInstanceParam inst "fontcolor") -> fcolor in let if fcolor == nil then 0 else fcolor -> fcolor in let atoi (getPluginInstanceParam inst "fontsize") -> fsize in let if fsize == nil then 12 else fsize -> fsize in let atoi (getPluginInstanceParam inst "fontbold") -> fbold in let if fbold == nil then 0 else fbold -> fbold in let getPluginInstanceParam inst "label" -> label in let if label == nil then "" else label -> label in let atoi (getPluginInstanceParam inst "opacity") -> opacity in let if opacity == nil then 100 else opacity -> opacity in let atoi (getPluginInstanceParam inst "transition") -> transition in let if transition == nil then 0 else transition -> transition in let atoi (getPluginInstanceParam inst "transparency") -> trans in let if (trans == nil) then 0 else trans -> trans in let atoi (getPluginInstanceParam inst "enablemouse") -> enablemouse in let if enablemouse == nil then 1 else enablemouse -> enablemouse in let atoi (getPluginInstanceParam inst "cursor") -> cursor in let if cursor == nil then 1 else cursor -> cursor in let atoi (getPluginInstanceParam inst "show") -> show in let if (show == nil) then 1 else show -> show in let if !isurl then path else url -> file in let atoi (getPluginInstanceParam inst "zorder") -> zorder in let if zorder == nil then 101 else zorder -> zorder in let SO3SceneGetObject (V3DgetSession c3dXsession) objname -> obj in let if !istexture then nil else SO3SceneGetMaterial (V3DgetSession c3dXsession) (SO3EntityGetResourceGroup obj) matname -> mat in let MkPlugButton [inst istexture mat technique pass texture nil nil nil posx posy width height [xpercent ypercent wpercent hpercent xoffset yoffset woffset hoffset] [xalign yalign] trans opacity transition 0.0 [fname fsize fbold] nil label fcolor isurl file 0 0 cursor enablemouse 0 btnstates 0 nbframes 0 0 0 nil nil nil nil zorder 0 0] -> btnstr in ( if ((file != nil) && (strcmp "" file)) then nil else let VUIgetThemeDef (getThemeFromInstance inst) "common" -> defstr in let VUIgetThemeElement defstr "button" -> ethstr in ( set btnstr.PBTN_sPath = ethstr.VUITHE_res.VUITHR_pSource; set btnstr.PBTN_iAvStates = ethstr.VUITHE_res.VUITHR_iNbStates; set btnstr.PBTN_iNbFrames = ethstr.VUITHE_res.VUITHR_iNbFrames; set btnstr.PBTN_bSplit = if (ethstr.VUITHE_res.VUITHR_iFlags & VUI_ResSplited) then 1 else 0; ); //addLogMessage strcatnSep "path:"::btnstr.PBTN_sPath::"nbstates:"::(itoa btnstr.PBTN_iAvStates)::"nbframes:"::(itoa btnstr.PBTN_iNbFrames)::"split:"::(itoa btnstr.PBTN_bSplit)::nil " "; if btnstr.PBTN_bOnMaterial then nil else setPluginInstanceCbResizeView inst mkfun5 @cbResizeCtrl btnstr; if (!show) then nil else cbShow inst nil nil nil nil btnstr; PluginRegisterAction inst "Show" mkfun6 @cbShow btnstr; PluginRegisterAction inst "Hide" mkfun6 @cbHide btnstr; PluginRegisterAction inst "Change" mkfun6 @cbChange btnstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable btnstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable btnstr; PluginRegisterAction inst "Set state" mkfun6 @cbSetState btnstr; PluginRegisterAction inst "Set label" mkfun6 @cbSetLabel btnstr; PluginRegisterAction inst "Send left click" mkfun6 @cbSendLeftClick btnstr; PluginRegisterAction inst "Send right click" mkfun6 @cbSendRightClick btnstr; PluginRegisterAction inst "Send middle click" mkfun6 @cbSendMiddleClick btnstr; PluginRegisterAction inst "Set position" mkfun6 @cbSetPosition btnstr; PluginRegisterAction inst "Set size" mkfun6 @cbSetSize btnstr; PluginRegisterAction inst "Set opacity" mkfun6 @cbSetOpacity btnstr; PluginRegisterAction inst "Set label color" mkfun6 @cbSetColor btnstr; PluginRegisterAction inst "Input" mkfun6 @cbInput btnstr; if (istexture) then nil else ( setPluginInstanceCbTouchPointAdd inst mkfun6 @cbAddCursor btnstr; setPluginInstanceCbTouchPointRemove inst mkfun4 @cbRemoveCursor btnstr; setPluginInstanceCbTouchPointUpdate inst mkfun8 @cbUpdateCursor btnstr; ); setPluginInstanceCbDel inst mkfun2 @deleteOb btnstr; SendPluginEvent btnstr.PBTN_instance "Started" nil nil; ); 0;; fun IniPlug(file)= VUIsetEnable c3dXsession 1; set sHandCursor = strcat APPBASEDIR sHandCursor; let _LDbitmap _channel _checkpack sHandCursor -> bmpcursor in let _CRcursor _channel bmpcursor 12 6 0x000000 0xffffff -> cursor in ( _DSbitmap bmpcursor; set cHandCursor = cursor; ); PlugRegister @cbNewOb nil; setPluginEditor @dynamicedit; 0;;