LibUI

 view release on metacpan or  search on metacpan

eg/histogram.pl  view on Meta::CPAN

use strict;
use warnings;
use lib '../lib';
use LibUI ':all';
use LibUI::Window;
use LibUI::Label;
use LibUI::Area;
use LibUI::HBox;
use LibUI::VBox;
use LibUI::Spinbox;
use LibUI::ColorButton;
use LibUI::Window::ResizeEdge;
use LibUI::Draw::Brush;
use LibUI::Draw::Path;
use LibUI::Draw;
use LibUI::Draw::Matrix;
#
my $currentPoint = -1;
my $dps          = 10;
my ( $window, $histogram, $colorButton, @datapoints );
#
# some metrics
sub xoffLeft()     {20}    # histogram margins
sub yoffTop ()     {20}
sub xoffRight ()   {20}
sub yoffBottom ()  {20}
sub pointRadius () {5}

# helper to quickly set a brush color
sub setSolidBrush {
    my ( $color, $alpha ) = @_;
    my $component;
    my $brush;
    #
    $brush->{type} = LibUI::Draw::BrushType::Solid();
    $component     = ( ( $color >> 16 ) & 0xFF );
    $brush->{R}    = ($component) / 255;
    $component     = ( ( $color >> 8 ) & 0xFF );
    $brush->{G}    = ($component) / 255;
    $component     = ( $color & 0xFF );
    $brush->{B}    = ($component) / 255;
    $brush->{A}    = $alpha;
    $brush;
}

# and some colors
# names and values from https://msdn.microsoft.com/en-us/library/windows/desktop/dd370907%28v=vs.85%29.aspx
sub White()      {0xFFFFFF}
sub Black()      {0x000000}
sub DodgerBlue() {0x1E90FF}
#
sub pointLocations {
    my ( $width, $height ) = @_;
    my $xincr = $width / ( $dps - 1 );    # 10 - 1 to make the last point be at the end
    my $yincr = $height / 100;
    my ( $xs, $ys );
    my $n = 0;
    for ( 0 .. ( $dps - 1 ) ) {
        $n = $datapoints[$_]->value();    # get the value of the point

        # because y=0 is the top but n=0 is the bottom, we need to flip
        $n        = 100 - $n;
        $xs->[$_] = $xincr * $_;
        $ys->[$_] = $yincr * $n;
    }
    ( $xs, $ys );
}

sub constructGraph {
    my ( $width, $height, $extend ) = @_;
    my ( $xs, $ys ) = pointLocations( $width, $height );
    my $path = LibUI::Draw::Path->new( LibUI::Draw::FillMode::Winding() );
    $path->newFigure( $xs->[0], $ys->[0] );
    $path->lineTo( $xs->[$_], $ys->[$_] ) for 1 .. ( $dps - 1 );
    if ($extend) {
        $path->lineTo( $width, $height );
        $path->lineTo( 0,      $height );
        $path->closeFigure;
    }
    $path->end;
    return $path;
}

sub graphSize {
    my ( $clientWidth, $clientHeight ) = @_;
    return ( $clientWidth - xoffLeft - xoffRight, $clientHeight - yoffTop - yoffBottom );
}

sub handlerDraw {    #(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
    my ( $a, $area, $p ) = @_;

    # fill the are with white
    my $brush = setSolidBrush( White, 1.0 );
    my $path  = LibUI::Draw::Path->new( LibUI::Draw::FillMode::Winding() );
    $path->addRectangle( 0, 0, $p->{width}, $p->{height} );
    $path->end;
    LibUI::Draw::fill( $p->{context}, $path, $brush );
    $path->free;

    # figure out dimensions
    my ( $graphWidth, $graphHeight ) = graphSize( $p->{width}, $p->{height} );
    my $sp = {    # stroke params
        cap        => LibUI::Draw::LineCap::Flat(),
        join       => LibUI::Draw::LineJoin::Miter(),
        thickness  => 2,
        miterLimit => 10                                # uiDrawDefaultMiterLimit;
    };



( run in 1.480 second using v1.01-cache-2.11-cpan-39bf76dae61 )