view mde/gui/renderer/IRenderer.d @ 109:2a1428ec5344

Optional, visible spacing in grid layouts.
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 04 Dec 2008 10:32:20 +0000
parents c9fc2d303178
children 1655693702fc
line wrap: on
line source

/* LICENSE BLOCK
Part of mde: a Modular D game-oriented Engine
Copyright © 2007-2008 Diggory Hardy

This program is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either
version 2 of the License, or (at your option) any later version.

This program 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 General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>. */

/** Interface for the renderer. This is planned to replace decoration.d */
module mde.gui.renderer.IRenderer;

public import mde.gui.types;
import mde.font.font;

/** Interface for renderers.
*
* Renderers provide unified drawing methods for widget, e.g. to draw a window background, a frame,
* or a button. The renderer will effectively be synonymous with the theme, except that a scripted
* renderer may also be available.
*
* The renderer is intended to be per-GUI. */
interface IRenderer
{
    //BEGIN Types
    /** For floating widget borders. Like TextAdapter above, could be more flexible. */
    struct Border {
        /** Border type.
         * 
         * No border, small non-functional border, movement only border, resize only border, or
         * full border. */
        enum BTYPE : int {
            NONE = 0, SMALL = 1, LARGE = 2, MOVE = 4, RESIZE = 8, BOTH = MOVE | RESIZE
        }
        /** Which edges of a window are being resized.
         *
         * E.g. X1 == left, X2 | Y1 == right and top. */
        enum RESIZE : int {
            NONE = 0x0, X1 = 0x1, X2 = 0x2, Y1 = 0x4, Y2 = 0x8
        }
        
        wdim x1,x2;     /// First and second (lef & right) horizontal borders
        wdim y1,y2;     /// First and second vertical borders
        RESIZE capability;      /// Which resizes are possible.
        
        void opAddAssign (Border d) {
            x1 += d.x1;
            x2 += d.x2;
            y1 += d.y1;
            y2 += d.y2;
        }
        
        /** Used to tell if a click on a window's border is for resizing or moving.
         *
         * Depends on setSizable's parameters.
         *
         * Params:
         *   cx =
         *   cy = click coordinates relative to window border
         *   w  =
         *   h  = window size
         *
         * Returns:
         *   RESIZE = Describes whether the click resizes or moves the widget. */
        RESIZE getResize (wdim cx, wdim cy, wdim w, wdim h) {
            RESIZE r = RESIZE.NONE;
            if (cx + cy < x1 + y1)
                r = RESIZE.X1 | RESIZE.Y1;
            else if (cx + h - cy < x1 + y2)
                r = RESIZE.X1 | RESIZE.Y2;
            else if (w - cx + cy < x2 + y1)
                r = RESIZE.X2 | RESIZE.Y1;
            else if (w - cx + h - cy < x2 + y2)
                r = RESIZE.X2 | RESIZE.Y2;
            return r & capability;
        }
    }
    
    /** For drawing text - one instance per string.
     *
     * NOTE: currently inflexible. Could use (function) pointers, class interfaces or struct
     * interfaces when available to allow flexibility. */
    struct TextAdapter {
	char[] text () {
	    return content;
	}
        void text (char[] str) {
            content = str;
	    textCache.cacheVer = -1;	// force update
        }
	
	void colour (int colour = 0xFFFFFF) {
	    colour_ = Colour (colour);
	}
	
	/** If not size_t.max, an edit marker is drawn before character index. */
	void index (size_t index = size_t.max) {
	    index_ = index;
	}
        
        void getDimensions (out wdsize w, out wdsize h) {
            font.updateBlock (content, textCache);
            w = cast(wdim) textCache.w;
            h = cast(wdim) textCache.h;
        }
        
        void draw (wdabs x, wdabs y) {
            font.textBlock (x,y, content, textCache, colour_, index_);
        }
        
        char[] content;
        TextBlock textCache;
	size_t index_;
        Colour colour_;
        FontStyle font;
    }
    //END Types
    
    //BEGIN Methods
    /** Returns a Border containing dimensions.
     *
     * The dimensions may depend on whether the widget is resizable (horizontally and vertically).
     */
    Border getBorder (Border.BTYPE type, bool wSizable, bool hSizable);
    
    /** Return the renderer's between-widget spacing (for layout widgets). */
    wdim layoutSpacing ();
    
    /** Restrict following draw operations to given box.
     *
     * Restrict "pushes" a restriction onto a stack; relax must be called afterwards to "pop" the
     * restriction. */
    void restrict (wdim x, wdim y, wdim w, wdim h);
    void relax ();      /// ditto
    
    /** Draw a window border plus background. */
    void drawWindow (Border* border, wdim x, wdim y, wdim w, wdim h);
    
    /** Draw vertical and horizontal spacers.
     *
     * x,y and w,h are the position and size of the grid containing spacers.
     * 
     * For each col in cols, spacers should be drawn in the rectangle
     * [x+col-layoutSpacing,x+col)*[y,y+h), and similarly for rows. */
    void drawSpacers (wdabs x, wdabs y, wdsize w, wdsize h, wdims cols, wdims rows);
    
    /** Draws a widget background. Usually doesn't do anything since backgrounds are transparent.
     *
     * It used to be required for all widgets to do this, but I lapsed since mostly it's unused. */
    void drawWidgetBack (wdim x, wdim y, wdim w, wdim h);
    
    /** Draws a blank widget (temporary) */
    void drawBlank (wdim x, wdim y, wdim w, wdim h);
    
    /** Draws a button frame, in if pushed == true. */
    void drawButton (wdim x, wdim y, wdim w, wdim h, bool pushed);
    
    /** Toggle buttons.
     *
     * These have a fixed size which getToggleSize returns. */
    wdimPair getToggleSize ();
    void drawToggle (wdim x, wdim y, bool state, bool pushed);  /// ditto
    
    /** Get a TextAdapter to draw some text.
     *
     * If no colour is passes, a default is used (white). */
    TextAdapter getAdapter (char[] text, int colour = 0xFFFFFF);
    //END Methods
}