Rebol [Title: "Guitar Chord Diagram Maker"] ; load embedded images: fretboard: load 64#{ iVBORw0KGgoAAAANSUhEUgAAAFUAAABkCAIAAAB4sesFAAAACXBIWXMAAAsTAAAL EwEAmpwYAAAA2UlEQVR4nO3YQQqDQBAF0XTIwXtuNjfrLITs0rowGqbqbRWxEEL+ RFU9wJ53v8DN7Gezn81+NvvZXv3liLjmPX6n/4NL//72s9l/QGbWd5m53dbc8/kR uv5RJ/QvzH42+9nsZ7OfzX62nfOPzZzzyNUxxh8+qhfVHo94/rM49y+b/Wz2s9nP Zj+b/WzuX/cvmfuXzX42+9nsZ7OfzX4296/7l8z9y2Y/m/1s9rPZz2Y/m/vX/Uvm /mWzn81+NvvZ7Gezn8396/4l2/n+y6N/f/vZ7Gezn81+tjenRWXD3TC8nAAAAABJ RU5ErkJggg== } barimage: load 64#{ iVBORw0KGgoAAAANSUhEUgAAAEoAAAAFCAIAAABtvO2fAAAACXBIWXMAAAsTAAAL EwEAmpwYAAAAHElEQVR4nGNsaGhgGL6AaaAdQFsw6r2hDIa59wCf/AGKgzU3RwAA AABJRU5ErkJggg== } dot: load 64#{ iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAAL EwEAmpwYAAAAFElEQVR4nGNsaGhgwA2Y8MiNYGkA22EBlPG3fjQAAAAASUVORK5C YII= } ; Gui Design: ; The routine below was copied from ; movestyle: [ engage: func [face action event] [ if action = 'down [ face/data: event/offset remove find face/parent-face/pane face append face/parent-face/pane face ] if find [over away] action [ face/offset: face/offset + event/offset - face/data ] show face ] ] ; With that defined, adding "feel movestyle" to any style ; makes it movable within the GUI. It's very useful for all ; sorts of graphic applications... If you want to pursue ; building graphic layouts that respond to user events, learning ; all about how "feel" works in Rebol is very important. gui: [ backdrop white ; makes the GUI background white currentfretboard: image fretboard 255x300 ; show the fretboard image, and resize it ; (the saved image is actually 85x100 pixels) currentbar: image barimage 240x15 feel movestyle ; Show the bar image, resize it, and make it movable. ; Notice the "feel movestyle". Thats' what enables ; the dragging. text "INSTRUCTIONS:" underline text "Drag dots and other widgets onto the fretboard." across text "Resize the fretboard:" tab ; "tab" aligns the next GUI element with a predefined ; column spacer rotary "255x300" "170x200" "85x100" [ currentfretboard/size: to-pair value show currentfretboard switch value [ "255x300" [currentbar/size: 240x15 show currentbar] "170x200" [currentbar/size: 160x10 show currentbar] "85x100" [currentbar/size: 80x5 show currentbar] ] ] ; The rotary button above lets you select a size for the ; fretboard. In the action block, the fretboard image is ; resized, and then the bar image is also resized, ; according to the value chosen. This keeps the bar size ; proportioned correctly to the fretboard image. ; After each resize, the GUI is updated to actually display ; the changed image. The built-in word "show" updates the ; display. This needs to be done whenever a widget is ; changed within a GUI. Be aware of this - not "show"ing ; a changed GUI element is an easily overlooked source of ; errors. return button "Save Diagram" [ filename: to-file request-file/save/file "1.png" save/png filename to-image currentfretboard ] ; The action block of the above button requests a filename ; from the user, and then saves the current fretboard image ; to that filename. tab ; The action block of the button below prints out a user- ; selected set of images to an html page, where they can be ; viewed together, uploaded the Internet, sent to a printer, ; etc. button "Print" [ filelist: sort request-file/title "Select image(s) to print:" ; Get a list of files to print. html: copy "" ; start creating a block that holds the html layout, ; and give it the label "html". foreach file filelist [ append html rejoin [ {} ] ] ; The foreach loop builds an html layout that displays ; each of the selected images. append html [] ; finish up the html layout. Now the variable "html" ; contains a complete html document that will be ; written to the hard drive and opened in the default ; browser. The code below accomplishes that. write %chords.html trim/auto html browse %chords.html ] ] ; Each of the following loops puts 50 moveable dots onto the GUI, ; all at the same locations. This creates three stacks of dots ; that the user can move around the screen and put onto the ; fretboard. There are three sizes to accomodate the resizing ; feature of the fretboard image. Notice the "feel movestyle" ; code at the end of each line. Again, that's what makes the ; dots draggable. loop 50 [append gui [at 275x50 image dot 30x30 feel movestyle]] loop 50 [append gui [at 275x100 image dot 20x20 feel movestyle]] loop 50 [append gui [at 275x140 image dot 10x10 feel movestyle]] ; The following loops add some additional dragable widgets to ; the GUI. loop 6 [append gui [at 273x165 text "X" bold feel movestyle]] loop 6 [append gui [at 273x185 text "O" bold feel movestyle]] view layout gui