/* Copyright (C) 2011, Stephane Bisaro, aka iri License : you can do what you want with this source code This code is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */ /* To build a graphic resource for a scrollbar, it must several states like "disable" state, "rollover" state, etc. There are several ways to build that by the code. I'll propose one here. A state can be structured like that : ____ ........ 0 /|\ | | yspacing | -- | ........ y1 = yspacing \|/ ||/\|| --------------------------------------> top arrow | -- | ........ o1-yspacing | | ........ o1 | -- | ........ o1+yspacing || || || || || || || || || || --------------------------------------> body || || || || || || || || | -- | ........ o2-yspacing | | ........ o2 | -- | ........ o2+yspacing ||\/|| --------------------------------------> bottom arrow | -- | ........ o3-yspacing | | ........ o3 | -- | ........ o3+yspacing ||..|| --------------------------------------> cursor | -- | ........ y2 = h-yspacing | | ____ ........ h .. .. .. .. .. .. 0. .w x1 x2 x3 (= center of x1,x2) To build, this is needed to make step by step with the functions of bitmaps manipulations : http://www.scolring.org/files/doc_html/bitmap.html You must be strict and precise. Next, you must know : - the number of states - the direction (verticale or horizontale) - the size of one state (displayed by default), others will have the same size - the three offsets in this order : first pixel of body, of right (botom) arrow and of cursor so, you must have : - from 0 to first offset value (o1) : the left(top) arrow - from the first offset value (o1) to the second offset value (o2) : the body - from the second offset value (o2) to the third offset value (o3) : the right(bottom) arrow - from the third offset value (o3) to the end (w or h) : the cursor - the differents width and/or height sub-components (arrows, body and cursor) - the bitmaps manipulations Steps : 1 - create the full bitmap 2 - create the first arrow - create the background (usually, a square with a border) - create the arrow inside the previous background 3 - create the body 4 - create the second arrow - create the background (usually, a square with a border) - create the arrow inside the previous background 5 - create the cursor 6 - create the mask state, if needed 7 - create the alpha layer (ObjBitmap8), may be done with previous steps Note : the function below should be updated and compacted. I separate each step and each manipulation for this example ... These arguments are : 1 - the width of one state (like the scroll bar will be displayed) 2 - the height of one state 3 - the flags of the creation (SLB_DISABLE and/or SLB_ROLLOVER and/or SLB_MASK) 4 - the direction : 0 = horizontal, 1 = vertical 5 - horizontal spacing 6 - vertical spacing 7 - offsets : a tuple with three values (see above) It returns a new AlphaBitmap */ /* Create a scroll bar depending of some parameters. See above for more explanations. Prototype : fun [I I I I I I [I I I]] AlphaBitmap */ fun buildScrollBar (width, height, flag, direction, xspacing, yspacing, offsets)= let _tickcount -> tc in let 0 -> counter in let 2 -> f in // number of states, except mask state, if any let 2 -> allf in // total number of states let nil -> alphabitmap in // the output AlphaBitmap ( set f = if flag&SLB_DISABLE then f+1 else f; set f = if flag&SLB_ROLLOVER then f+1 else f; set allf = if flag&SLB_MASK then f+1 else f; let if direction == 0 then // horizontal scroll bar [width height*allf] else // vertical scroll bar [width*allf height] -> [w h] in // For the below variables/values, see the comment above let offsets -> [offset1 offset2 offset3] in let offset1-1 -> o1 in let offset2-1 -> o2 in let offset3-1 -> o3 in let xspacing -> x1 in let width-xspacing -> x2 in let x2-x1 -> ws in let width/2 -> x3 in let yspacing -> y1 in let height-yspacing -> y2 in let y2-y1 -> hs in let height/2 -> y3 in let 0xff9999 -> bgcolor in let 0x000000 -> border in // Create the bitmap and the alpha layer let _CRbitmap _channel w h -> bmp in let _CRbitmap8 _channel w h -> bmp8 in ( // Fill the bitmap and the alpha layer in white _FILLbitmap bmp 0xffffff; _FILLbitmap8 bmp8 0xffffff; // left or top arrow // first, the square while counter < f do ( if direction == 0 then // horizontal let height*counter -> hf in let (o1-xspacing)-x1 -> warrow in ( _DRAWrectangle bmp x1 y1+hf warrow hs DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 0 0+hf o1 height DRAW_SOLID xspacing 0xffffff DRAW_INVISIBLE 0xffffff ) else if direction == 1 then // vertical let width*counter -> wf in let (o1-yspacing)-y1 -> harrow in ( _DRAWrectangle bmp x1+wf y1 ws harrow DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 0+wf 0 width o1 DRAW_SOLID yspacing 0xffffff DRAW_INVISIBLE 0xffffff ) else // others cases, nothing to do nil; set counter = counter+1 ); set counter = 0; // second, the arrow itself while counter < f do ( let mktab 3 nil -> t in if direction == 0 then // horizontal let height*counter -> hf in ( set t.0 = [(xspacing*2)+x1 y3+hf]; set t.1 = [o1-(xspacing*3) y1+yspacing+hf]; set t.2 = [o1-(xspacing*3) y2-yspacing+hf]; _DRAWpoly24 bmp 3 t DRAW_SOLID 1 border DRAW_SOLID border ) else if direction == 1 then // vertical let width*counter -> wf in ( set t.0 = [x3+wf (2*yspacing)+y1]; set t.1 = [x1+xspacing+wf o1-(yspacing*4)]; set t.2 = [x2-xspacing+wf o1-(yspacing*4)]; _DRAWpoly24 bmp 3 t DRAW_SOLID 1 border DRAW_SOLID border ) else // others cases, nothing to do nil; set counter = counter+1 ); set counter = 0; // body while counter < f do ( if direction == 0 then // horizontal let height*counter -> hf in let (o2-xspacing)-(o1+xspacing) -> wbody in ( _DRAWrectangle bmp o1+xspacing y1+hf wbody hs DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 o1 0+hf o2 height DRAW_SOLID xspacing 0xffffff DRAW_INVISIBLE 0xffffff ) else if direction == 1 then // vertical let width*counter -> wf in let (o2-yspacing)-(o1+yspacing) -> hbody in ( _DRAWrectangle bmp x1+wf o1+yspacing ws hbody DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 0+wf o1 width o2-o1 DRAW_SOLID yspacing 0xffffff DRAW_INVISIBLE 0xffffff ) else // others cases, nothing to do nil; set counter = counter+1 ); set counter = 0; // right or bottom arrow // first, the square while counter < f do ( if direction == 0 then // horizontal let height*counter -> hf in let (o3-xspacing)-(o2+xspacing) -> warrow in ( _DRAWrectangle bmp o2+xspacing y1+hf warrow hs DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 o2 0+hf o3-o2 height DRAW_SOLID xspacing 0xffffff DRAW_INVISIBLE 0xffffff ) else if direction == 1 then // vertical let width*counter -> wf in let (o3-yspacing)-(o2+yspacing) -> harrow in ( _DRAWrectangle bmp x1+wf o2+yspacing ws harrow DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 0+wf o2 width o3-o2 DRAW_SOLID yspacing 0xffffff DRAW_INVISIBLE 0xffffff ) else // others cases, nothing to do nil; set counter = counter+1 ); set counter = 0; // the arrow itself while counter < f do ( let mktab 3 nil -> t in if direction == 0 then // horizontal let height*counter -> hf in ( set t.0 = [o2+(3*xspacing) y1+yspacing+hf]; set t.1 = [o2+(3*xspacing) y2-yspacing+hf]; set t.2 = [o3-(3*xspacing) y3+hf]; _DRAWpoly24 bmp 3 t DRAW_SOLID 1 border DRAW_SOLID border ) else if direction == 1 then // vertical let width*counter -> wf in ( set t.0 = [x1+xspacing+wf o2+(3*yspacing)]; set t.1 = [x2-xspacing+wf o2+(3*yspacing)]; set t.2 = [x3+wf o3-(4*yspacing)]; _DRAWpoly24 bmp 3 t DRAW_SOLID 1 border DRAW_SOLID border ) else // others cases, nothing to do nil; set counter = counter+1 ); set counter = 0; // cursor while counter < f do ( if direction == 0 then // horizontal let height*counter -> hf in let (x2-xspacing)-(o3+xspacing) -> wcursor in ( _DRAWrectangle bmp o3+xspacing y1+hf wcursor hs DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 o3 0+hf w-o3 height DRAW_SOLID yspacing 0xffffff DRAW_INVISIBLE 0xffffff; _DRAWline bmp o3+xspacing+(wcursor/2) y1+(2*yspacing)+hf o3+xspacing+(wcursor/2) y2-(2*yspacing)+hf DRAW_SOLID 1 border ) else if direction == 1 then // vertical let width*counter -> wf in let (y2-yspacing)-(o3+yspacing) -> hcursor in ( _DRAWrectangle bmp x1+wf o3+yspacing ws hcursor DRAW_SOLID 1 border DRAW_SOLID bgcolor; _DRAWrectangle8 bmp8 0+wf o3 width h-o3 DRAW_SOLID yspacing 0xffffff DRAW_INVISIBLE 0xffffff; _DRAWline bmp x1+(2*xspacing)+wf o3+yspacing+(hcursor/2) x2-(2*xspacing)+wf o3+yspacing+(hcursor/2) DRAW_SOLID 1 border ) else // others cases, nothing to do nil; set counter = counter+1 ); set counter = 0; // mask state, if needed if allf != f then if direction == 0 then // horizontal ( _DRAWrectangle bmp (-1) h-height+(2*yspacing) w+3 height-(2*yspacing) DRAW_SOLID yspacing border DRAW_INVISIBLE 0xffffff; _DRAWline bmp o1 h-height+(2*yspacing) o1 h DRAW_SOLID yspacing border; _DRAWline bmp o2 h-height+(2*yspacing) o2 h DRAW_SOLID yspacing border; _DRAWline bmp o3 h-height+(2*yspacing) o3 h DRAW_SOLID yspacing border ) else if direction == 1 then // vertical ( _DRAWrectangle bmp w-width+(2*xspacing) (-1) width-(2*xspacing) h+3 DRAW_SOLID xspacing border DRAW_INVISIBLE 0xffffff; _DRAWline bmp w-width+(2*xspacing) o1 w o1 DRAW_SOLID xspacing border; _DRAWline bmp w-width+(2*xspacing) o2 w o2 DRAW_SOLID xspacing border; _DRAWline bmp w-width+(2*xspacing) o3 w o3 DRAW_SOLID xspacing border ) else // others cases, nothing to do nil else nil; // _SAVEbitmap bmp _getmodifypack "examples/alphabitmap/test.bmp"; // to verify the bitmap, if any // Create the AlphaBitmap from the bitmap and the alpha layer set alphabitmap = _CRalphaBitmap _channel bmp bmp8 nil nil; // Don't forget to destroy the bitmap and the alpha layer (these are no longer needed) _DSbitmap bmp; _DSbitmap8 bmp8; ); // display the elapsed time (depends on a lot of things !!!) let _tickcount - tc -> t in _fooS strcat "elapsed time (ms) : " itoa t; _fooS "Done !"; // return the AlphaBitmap alphabitmap );; /* Before to close the VM, all graphics components and resources should be destroyed ... Remember to do that ! Prototype : fun [ObjWin [ObjContainer CompSlideBar CompSlideBar AlphaBitmap AlphaBitmap]] I */ fun end (win, user_parameter)= let user_parameter -> [container cVertical cHorizontal verticalAlphaBitmap horizontalAlphaBitmap] in ( _DScompSlideBar cVertical; _DScompSlideBar cHorizontal; _DScontainer container; _DSalphaBitmap verticalAlphaBitmap; _DSalphaBitmap horizontalAlphaBitmap; _closemachine; 0 );; /* Main function To show the scroll bars, we add two slider bars. Prototype : fun [] I */ fun main ()= _showconsole; let [400 17] -> [a b] in let _CRwindow _channel nil 0 0 500 500 WN_MENU " Example > AlphaBitmap > Build scroll bar" -> window in let _CRcontainerFromObjWin _channel window 0 0 500 500 CO_CHILDINSIDE 0x888888 "" -> container in let buildScrollBar 17 400 SLB_MASK|SLB_ROLLOVER 1 2 1 [13 373 386] -> verticalAlphaBitmap in let buildScrollBar 400 17 SLB_MASK|SLB_ROLLOVER 0 2 1 [20 366 386] -> horizontalAlphaBitmap in let _CRcompSlideBar _channel container nil [10 20] OBJ_ENABLE|OBJ_VISIBLE|SLB_MASK|SLB_ROLLOVER 0 verticalAlphaBitmap [13 373 386] SLB_VERTICAL 0 100 1 -> cVertical in let _CRcompSlideBar _channel container nil [40 30] OBJ_ENABLE|OBJ_VISIBLE|SLB_MASK|SLB_ROLLOVER 0 horizontalAlphaBitmap [20 366 386] SLB_HORIZONTAL 0 100 1 -> cHorizontal in ( _CBwinDestroy window @end [container cVertical cHorizontal verticalAlphaBitmap horizontalAlphaBitmap]; _PAINTcontainer container; 0 );;