Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: [VID//menu]

From: info:id-net:ch at: 2-Jun-2004 1:20

While the Cyphre 's code is not released, I publish here the result of an old effort to have a cascaded menu style. There's still some bugs, specially sometimes when a cascaded menu pane is displayed and a clik is made on a menu header. I appreciate any help to finish the job, because I cant' find the problem... Philippe Oehler REBOL [ title: "View Menu" authors: "Frank Sievertsen (version 1.0.0) & Philippe Oehler (v.2.0.0)" date:22-5-04/14:39 version: 2.0.0 purpose: "Adds a grafical menu to a window or a face + Cascaded-menu" ] ;/*****************************************/ Needed to run the script well, with new version of View flag-face?: func [ "Checks a flag in a VID face." face [object!] 'flag ][all [in face 'flags face/flags find face/flags flag]] ;/*****************************************/ ao2: :print ; a function, that I actually activates/deactivates, to be simple, here : ao2: : print ;/*****************************************/head of the object! CONTEXT [ ;/*****************************************/ ; LOCAL PARSE - VARS t1: t2: none name: none out-block: none out-face: none SUB-out-face: none ;SUB-out-block: COPY [] offset: 0x0 direction: 0x1 menu: none degree-from-top-face: "" ;/*****************************************/ ;[STYLIZE];/*****************************************/; MENU-I-STYLES: stylize [ ;[STYLE : MENU-ITEM];/*****************************************/; menu-item: txt bold font-name "verdana" black "" font-size 10 with [ pane-size: 900x900 colors: reduce [[gradient 1x1 167.163.179 167.163.179] none];colors: reduce [167.163.179 none] Append init [state: no] state: no menu-description: none ;its text' block menu-action: none ;its behavior title-of-submenu?: none menu-number: 0 parent-name: "" path-from-system-for-Cascaded-Menu: "" ; to be a private data, shared into different funcs init: [ size: 900x900 size: (size-text self) + para/origin + para/margin ] para: make para [ margin: origin: 4x2 ] ] feel [ redraw: func [face][ face/color: pick face/colors face/state ] over: func [face action event][ face/state: action show face ] engage: func [face action event][ switch action [ down [ ;ao2 "normal action of the basic style" ;ao2 "CALL unview-menu" unview-menu ;effacement du menu d=E9roul=E9 face/menu-action face ;call the menu' menu-action with its argument face IF face/menu-description [ ;if there's something in the block's menu-descritption. unview-menu ;time 1 : unview of the menu displayed view-menu face ;time 2 : 'redraw' ] ] away [ over face no event ;calling of the function 'over with false (no) as 2nd argument ] over [ over face yes event ;calling of the function 'over with true (yes) as 2nd argument ] ] ] ] ;/*****************************************/ end of MENU-ITEM ] ;/*****************************************/; ;[/STYLIZE] ;/*****************************************/; Menu-Functions Unview-menu: func [][ ao2 "ENTR UNVIEW-MENU" IF menu [ ;ao2 "Menu activated!" remove find menu/parent-face/pane menu show menu/parent-face menu: none ] IF error? try [ IF Cascaded-menu [ ;ao2 "mark 161" unview-Cascaded-menu Cascaded-menu: none ] ][] ] ;/*****************************************/ Unview-Cascaded-menu: func [/only][ ;ao2 "ENTR Unview-Cascaded-menu" nb-Cascaded-menu: 0 IF Cascaded-menu [ ;AO2 "Cascaded-menu activated!!!" remove find Path-from-system-for-Cascaded-Menu Cascaded-menu show Path-from-system-for-Cascaded-Menu Cascaded-menu: none ] IF Not only [ IF menu [ ;ao2 "CALL unview-Cascaded-menu" unview-menu menu: none ] ] ;ao2 "DONE Unview-Cascaded-menu" ] ;/*****************************************/ view-Cascaded-menu: func [ bk /minimize ][ ao2 "ENTR view-Cascaded-menu" len-bk: length? bk offs: sub-offset ;private variable of the object! either global-affichage-old-school [ path-from-system-for-Cascaded-Menu: system/view/screen-face/pane/1/pane/8/pane/pane ] [ path-from-system-for-Cascaded-Menu: ystem/view/screen-face/pane/1/pane ] Append path-from-system-for-Cascaded-Menu Cascaded-menu: make system/words/face [ dirty?: yes flags: [on-unfocus] ] Cascaded-menu/edge: make Cascaded-menu/edge [ effect: 'bevel color: 200.200.200 size: 2x1 ] Cascaded-menu/color: 212.212.212 ;Cascaded-menu/effect: [ merge gradmul 1x1 212.212.212 212.212.212]; 120.255.195 Cascaded-menu/pane: copy [] EITHER Not minimize [ size-x: 0 forEach item bk [ ;calcul de la longueur maximale du sous-menu size-text-x: (my-size-text item/text) + 8x0 size-x: max size-x (size-text-x/x) ] ][ size-x: 0 ] o: 0x0 forEach item bk [ item/colors: reduce [[gradient 1x1 167.163.179 167.163.179] none] item/offset/y: o/y item/size: To-pair (join size-x "x18") item/feel/redraw: func [face][ face/effect: pick face/colors face/state ] item/feel/over: func [face action event][ EITHER all [(face/parent-name = "")(Not face/title-of-submenu?) ] [ unview-Cascaded-menu/only isCascaded-menu-visible?: false unfocus system/view/focal-face: menu ][ view-Cascaded-menu-procedure ] face/state: action ; true or false show face ] Append Cascaded-menu/pane item o/y: o/y + 18 ] Cascaded-menu/offset: offs Cascaded-menu/size/y: 18 * len-bk Cascaded-menu/size/x: size-x ;alert faceOne/parent-face/text show path-from-system-for-Cascaded-Menu ; Those line is important !! the path depends on where is the menu related the system path unfocus ;system/view/focal-face: Cascaded-menu ; I remove this line, producing the right action of items that are Not in a Cascaded-menu ;/*****************************************/; Cascaded-menu/action: func [face value][ unview-Cascaded-menu ] ;/*****************************************/; ao2 "DONE view-Cascaded-menu" ] ; not necessary, those function doesn't the right job. If someone can make this function right. ;/*****************************************/; Set-degree-from-top-face: func [face /local i][ the-path: face/parent-face ;print mold "lll" ;print mold face/var i: 1 if not none? the-path [ i: 2 the-path: face/parent-face/parent-face if not none? the-path [ i: 3 the-path: face/parent-face/parent-face/parent-face if not none? the-path [ i: 4 the-path: face/parent-face/parent-face/parent-face/parent-face if not none? the-path [ i: 5 the-path: face/parent-face/parent-face/parent-face/parent-face if not none? the-path [ i: 6 the-path: face/parent-face/parent-face/parent-face/parent-face ] ] ] ] ] return i ] isCascaded-menu-visible?: false ;/*****************************************/; view-Cascaded-menu-procedure: does [ IF Not isCascaded-menu-visible? [view-Cascaded-menu Cascaded-menu-block isCascaded-menu-visible?: true] ] Cascaded-menu-block: copy [] sub-offset: 0x0 ;/*****************************************/; View-menu: func [face /local tmp][ ao2 "ENTR view-menu" ;the object 'menu is added to the system' words ;ao2 mold face/parent-face/parent-face/pane Set-degree-from-top-face face; call of this function, but it doesn't work yet ; The next 2 lines are specific to the place where the menu is placed related to the system root MyPath-pane: face/parent-face/parent-face/pane ;MyPath-pane: face/parent-face/pane MyPath: face/parent-face/parent-face ;MyPath: face/parent-face clear Cascaded-menu-block Append face/parent-face/parent-face/pane menu: make system/words/face [ ;append the menu to the main pane (layout) where is the menu dirty?: yes flags: [on-unfocus] ] menu/edge: make menu/edge [ effect: 'bevel color: 200.200.200 size: 2x1] menu/offset: face/offset + 0x18 + face/parent-face/offset menu/color: none menu/effect: [ gradient 1x1 212.212.212 212.212.212 ;;;;;6-merge gradmul 0x8 97.99.135 97.99.135; 120.255.195 ;merge gradmul 0x1 115.115.195 120.120.195 ;multiply 85.85.85 ;merge gradcol 0x1 250.250.250 250.250.250 ] build-menu/below menu face/menu-description ; actually the parsing of the dialect is called menu/size: 1x1 menu/size/x: face/size/x has-OneCascade-InPane?: false offs: 1x1 IF menu/pane/1 [une-hauteur: menu/pane/1/size/y] menu-pane-temp: copy menu/pane ; variable temp is used to remove find menu/pane item because it's hard to make it in the foreach loop forEach item menu-pane-temp [ SUB?: false IF error? try [ IF item/user-data <> none [SUB?: has-OneCascade-InPane?: true] ][] EITHER SUB? = FALSE [ ;normal case menu/size: max menu/size item/offset + item/size item/size/x: menu/size/x offs/x: menu/offset/x + item/size/x + 2 IF face/title-of-submenu? [ ;ao2 ["title-of-submenu?" face/text ] ] ][ Append/only Cascaded-menu-block item ;ao2 menu/offset/x offs/y: menu/offset/y + item/size/y ; ao2 ["--->" length? menu/pane] remove find menu/pane item ; ao2 ["--->" length? menu/pane] ] ] ;IF face/title-of-submenu? [ao2 face/text ] menu/size: menu/size + 2x2 show myPath unfocus system/view/focal-face: menu menu/action: func [face value][ unview-menu ao2 "2-unview" ] print has-OneCascade-InPane? IF has-OneCascade-InPane? [ offs/y: offs/y - une-hauteur sub-offset: offs ;;;;6-view-Cascaded-menu/minimize Cascaded-menu-block ; args 1 : la face (le sous-sous-menu) ; arg 2 : l'offset view-Cascaded-menu Cascaded-menu-block ; args 1 : la face (le sous-sous-menu) ; arg 2 : l'offset ] ] ;/*****************************************/; Build-menu: func [face [object!] descr [block!] /below "without 'below, the menu's elements are horizontal"][ face/pane: out-block: copy [] direction: EITHER below [0x1][1x0] IF Not parse Compose descr [menu-data][ ;make error! "menu-parse error" ] ] ;/*****************************************/; ;=============== ; PARSE - RULES menu-data: [ (offset: 0x0) any menu-item ] menu-counter: 0 ; Second rule of parsing menu-item: [ set name string! ;used for titles of menu + its elements but not for cascaded menu's elements (out-face: make menu-i-styles/menu-item []) ;out-face become a style element, then some specifities will be append (out-face/text: copy name) ;out-face/text will be titles of the menu (out-face/offset: offset) ; its offset any menu-options ; second block of parsing rules (cf. below) (do out-face/init) ;call of the init function of the style (offset: out-face/size * direction + offset) ; the offset is *saved* to later use (Append out-block out-face) ; all infos (style + new infos) are added to a larger block | ; or, reading of the splitting and graphic creation of the splitting line '--- ( Append out-block t1: make face [ size: 10x3 edge: make edge [ effect: 'ibevel size: 1x1 color: none color: 200.200.200 ] ] t1/offset: offset offset: t1/size * direction + offset ) ] reference-menu-name: "" ; begin with the name, then either it's a SUB, or a block menu-options: [ 'SUB set t1 block! ( menu-counter: menu-counter + 1 out-face/menu-description: t1 out-face/font/color: 72.132.167 out-face/menu-number: menu-counter ;ao2 out-face/menu-number ) | set t1 block! ( out-face/menu-action: func [face] t1 ) | 'SUB-SUB set t2 block! (GLOBAL-existence-de-Cascaded-menu?: true) (out-face/title-of-submenu?: true) ;it works (reference-menu-name: out-face/text) ;(out-face/menu-number: menu-counter) ;;;;;6-(ao2 out-face/menu-number) (parse t2 menu-SUB-options) ;when it encounters SUB-SUB then block parsing du block that follows ] ; what is after the | is something that I added (Philippe) ; Rules for sub-options menu-SUB-options: [ any [ set SUB-name string! ; the Name of SubMenu is set (SUB-out-face: make menu-i-styles/menu-item []) ; sub-out-face become a menu-item and has its style now (SUB-out-face/text: copy SUB-name) ; get-copy of the sub-name (sub-out-face/parent-name: reference-menu-name) (SUB-out-face/effect: menu/effect) ; get the main effect set t2 block! ; le block ( SUB-out-face/menu-description: t2 SUB-out-face/menu-action: func [face] t2 SUB-out-face/user-data: true ; if <> none then the face will be a Cascaded-menu ) (do SUB-out-face/init) (Append out-block SUB-out-face);out-block is actually a face/pane! (a kind of pointeur) ] ] ;/*****************************************/; system/words/menu-styles: stylize [ menu: box 1x1 with [ Append init: init [ size: 1x1 build-menu self second :action ] words: [ SUB [ ;ao2 "SUB" ] SUB-SUB [] ] ] feel [ engage: none redraw: func [face][ face/offset: -1x-1 face/size: face/parent-face/size + 10x1 face/size/y: 19 ; starting menu height ] ] edge [effect: 'bevel size: 1x1 color: 200.200.200] ] ] ;[END OF CONTEXT] ; EXAMPLE : ;win: compose [ backdrop 212.212.212 origin 0x4 styles menu-styles] myMenu: Compose/deep [ menu [ "File |" sub [ "Save As" [save-as] --- ] "Edit |" sub [ "Delete -->" sub-sub [ "Word" [delete-word] ("Line" [delete-line] ] --- "Cut" [] "Copy" [] "Paste" [] --- ] ] ] Append win Compose [Menu2: (myMenu)]