From 2d5101a54220c88c752ea4b5e54891f5a6e31678 Mon Sep 17 00:00:00 2001 From: Javier Sancho Date: Tue, 26 May 2020 12:37:38 +0200 Subject: [PATCH] user interface example --- examples/05-user-interface.scm | 192 ++++++++++++++++++++++++ examples/media/fonthaettenschweiler.bmp | Bin 0 -> 196662 bytes examples/media/irrlichtlogo2.png | Bin 0 -> 15109 bytes 3 files changed, 192 insertions(+) create mode 100644 examples/05-user-interface.scm create mode 100644 examples/media/fonthaettenschweiler.bmp create mode 100644 examples/media/irrlichtlogo2.png diff --git a/examples/05-user-interface.scm b/examples/05-user-interface.scm new file mode 100644 index 0000000..e723f94 --- /dev/null +++ b/examples/05-user-interface.scm @@ -0,0 +1,192 @@ +;;; guile-irrlicht --- FFI bindings for Irrlicht Engine +;;; Copyright (C) 2020 Javier Sancho +;;; +;;; This file is part of guile-irrlicht. +;;; +;;; Guile-irrlicht 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 3 of the +;;; License, or (at your option) any later version. +;;; +;;; Guile-irrlicht 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 +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with guile-irrlicht. If not, see +;;; . + + +;;; Irrlicht 05.User Interface example +;;; http://irrlicht.sourceforge.net/docu/example005.html + + +(use-modules (irrlicht) + (ice-9 match)) + +;; ask user for driver +(format #t + "Please select the driver you want for this example: + (a) OpenGL 1.5 + (b) Direct3D 9.0c + (c) Direct3D 8.1 + (d) Burning's Software Renderer + (e) Software Renderer + (f) NullDevice + (otherKey) exit~%~%") + +(define device-type (match (read-char) + (#\a 'opengl) + (#\b 'direct3d9) + (#\c 'direct3d8) + (#\d 'burnings) + (#\e 'software) + (#\f 'null) + (_ #f))) + +(when (not device-type) + (exit #f)) + +;; set the skin transparency by changing the alpha values of all skin-colors +(define (set-skin-transparency alpha skin) + (let loop ((default-colors '(3d-dark-shadow 3d-shadow 3d-face 3d-high-light 3d-light + active-border active-caption app-workspace button-text + gray-text high-light high-light-text inactive-border + inactive-caption tooltip tooltip-background scrollbar + window window-symbol icon icon-high-light gray-window-symbol + editable gray-editable focused-editable))) + (cond ((not (null? default-colors)) + (let* ((default-color (car default-colors)) + (color (get-color skin default-color)) + (new-color (cons alpha (cdr color)))) + (set-color! skin default-color new-color)) + (loop (cdr default-colors)))))) + +;; create device +(define device + (create-device + #:device-type device-type + #:window-size '(640 480))) + +(set-window-caption! device "Irrlicht Engine - User Interface Demo") +(set-resizable! device #t) + +(define driver (get-video-driver device)) +(define gui-env (get-gui-environment device)) + +;; load an external font and set it as the new default font in the skin +(let ((skin (get-skin gui-env)) + (font (get-font gui-env "media/fonthaettenschweiler.bmp"))) + (set-font! skin font) + (set-font! skin (get-built-in-font gui-env) #:which 'tooltip)) + +;; define some values that we'll use to identify individual GUI controls +(define GUI-ID-QUIT-BUTTON 101) +(define GUI-ID-NEW-WINDOW-BUTTON 102) +(define GUI-ID-FILE-OPEN-BUTTON 103) +(define GUI-ID-TRANSPARENCY-SCROLLBAR 104) + +;; add three buttons, the first one closes the engine, the second creates a window +;; and the third opens a file open dialog +(add-button! gui-env '(10 240 110 272) + #:id GUI-ID-QUIT-BUTTON + #:text "Quit" + #:tooltiptext "Exits Program") +(add-button! gui-env '(10 280 110 312) + #:id GUI-ID-NEW-WINDOW-BUTTON + #:text "New Window" + #:tooltiptext "Launches a new window") +(add-button! gui-env '(10 320 110 352) + #:id GUI-ID-FILE-OPEN-BUTTON + #:text "File Open" + #:tooltiptext "Opens a file") + +;; we add a scrollbar and a listbox +(add-static-text! gui-env "Transparent Control:" '(150 20 350 40) #:border #t) +(let ((scrollbar (add-scrollbar! gui-env #t '(150 45 350 60) #:id GUI-ID-TRANSPARENCY-SCROLLBAR))) + (set-max! scrollbar 255) + (set-position! scrollbar 255) + (set-skin-transparency (get-position scrollbar) (get-skin gui-env)) + (let ((alpha (car (get-color (get-skin gui-env) 'window)))) + (set-position! scrollbar alpha))) + +(add-static-text! gui-env "Logging ListBox:" '(50 110 250 130 #t)) +(define listbox (add-listbox! gui-env '(50 140 250 210))) +(add-editbox! gui-env "Editable Text" '(350 80 550 100)) + +;; create the event receiver +(define open-new-window #f) +(let ((counter 0)) + (set! open-new-window + (lambda () + (add-item! listbox "Window created") + (set! counter (+ counter 30)) + (if (> counter 200) + (set! counter 0)) + (let* ((window-size (list (+ counter 100) + (+ counter 100) + (+ counter 300) + (+ counter 200))) + (window (add-window! gui-env window-size #:text "Test window"))) + (add-static-text! gui-env "Please close me" '(35 35 140 50) + #:border #t + #:word-wrap #f + #:parent window))))) + +(define (on-event event) + (if (equal? (get-event-type event) 'gui-event) + (let* ((caller (get-event-gui-caller event)) + (id (get-id caller)) + (event-type (get-event-gui-type event))) + + (cond ((equal? event-type 'scrollbar-changed) + (if (= id GUI-ID-TRANSPARENCY-SCROLLBAR) + (let ((pos (get-position caller))) + (set-skin-transparency pos (get-skin gui-env)))) + #f) + + ((equal? event-type 'button-clicked) + (cond ((= id GUI-ID-QUIT-BUTTON) + ;; quit + (close-device device) + #t) + + ((= id GUI-ID-NEW-WINDOW-BUTTON) + ;; new-window + (open-new-window) + #t) + + ((= id GUI-ID-FILE-OPEN-BUTTON) + ;; open file + (add-item! listbox "File open") + (add-file-open-dialog! gui-env + #:title "Please choose a file" + #:restore-cwd #t) + #t) + + (else #f))) + + ((equal? event-type 'file-selected) + (add-item! listbox (get-file-name caller)) + #f) + + (else #f))) + + #f)) + +(set-event-receiver! device (make-event-receiver on-event)) + +;; Irrlicht Engine logo in the top left corner +(add-image! gui-env (get-texture driver "media/irrlichtlogo2.png") '(10 10)) + +;; game loop +(while (run device) + (when (is-window-active? device) + (begin-scene driver #:color '(0 200 200 200)) + (draw-all gui-env) + (end-scene driver))) + +;; delete device +(drop! device) +(exit #t) diff --git a/examples/media/fonthaettenschweiler.bmp b/examples/media/fonthaettenschweiler.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ca301da4b1163c4a8949d790db341fe119950ed5 GIT binary patch literal 196662 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 Aq5uE@ literal 0 HcmV?d00001 diff --git a/examples/media/irrlichtlogo2.png b/examples/media/irrlichtlogo2.png new file mode 100644 index 0000000000000000000000000000000000000000..9086b122c8d3951fece5d1d4fee101d1935d98c5 GIT binary patch literal 15109 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 v