1 /** 2 * PBR widget: clickable logo. 3 * Copyright: Copyright Auburn Sounds 2015 and later. 4 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 5 * Authors: Guillaume Piolat 6 */ 7 module dplug.pbrwidgets.logo; 8 9 import std.math; 10 import dplug.gui.element; 11 import dplug.core.math; 12 13 class UILogo : UIElement 14 { 15 public: 16 nothrow: 17 @nogc: 18 19 /// Change this to point to your website 20 string targetURL = "http://example.com"; 21 float animationTimeConstant = 30.0f; 22 ubyte defaultEmissive = 0; // emissive where the logo isn't 23 24 // these are offset on top of defaultEmissive 25 ubyte emissiveOn = 40; 26 ubyte emissiveOff = 0; 27 28 /// Note: once called, the logo now own the diffuse image, and will destroy it. 29 this(UIContext context, OwnedImage!RGBA diffuseImage) 30 { 31 super(context); 32 _diffuseImage = diffuseImage; 33 _animation = 0; 34 } 35 36 ~this() 37 { 38 _diffuseImage.destroyNoGC(); 39 } 40 41 override void onAnimate(double dt, double time) nothrow @nogc 42 { 43 float target = ( isDragged() || isMouseOver() ) ? 1 : 0; 44 45 float newAnimation = lerp(_animation, target, 1.0 - exp(-dt * animationTimeConstant)); 46 47 if (abs(newAnimation - _animation) > 0.001f) 48 { 49 _animation = newAnimation; 50 setDirtyWhole(); 51 } 52 } 53 54 override void onDraw(ImageRef!RGBA diffuseMap, ImageRef!L16 depthMap, ImageRef!RGBA materialMap, box2i[] dirtyRects) nothrow @nogc 55 { 56 foreach(dirtyRect; dirtyRects) 57 { 58 auto croppedDiffuseIn = _diffuseImage.crop(dirtyRect); 59 auto croppedDiffuseOut = diffuseMap.crop(dirtyRect); 60 61 int w = dirtyRect.width; 62 int h = dirtyRect.height; 63 64 ubyte emissive = cast(ubyte)(0.5f + lerp!float(emissiveOff, emissiveOn, _animation)); 65 66 for(int j = 0; j < h; ++j) 67 { 68 RGBA[] input = croppedDiffuseIn.scanline(j); 69 RGBA[] output = croppedDiffuseOut.scanline(j); 70 71 for(int i = 0; i < w; ++i) 72 { 73 ubyte alpha = input[i].a; 74 RGBA color = RGBA.op!q{.blend(a, b, c)}(input[i], output[i], alpha); 75 76 // emissive has to be multiplied by alpha, and added to the default background emissive 77 color.a = cast(ubyte)( (128 + defaultEmissive * 256 + (emissive * color.a) ) >> 8); 78 output[i] = color; 79 } 80 } 81 } 82 } 83 84 override bool onMouseClick(int x, int y, int button, bool isDoubleClick, MouseState mstate) 85 { 86 browseNoGC(targetURL); 87 return true; 88 } 89 90 private: 91 float _animation; 92 OwnedImage!RGBA _diffuseImage; 93 }