hackedteam/rcs-console

View on GitHub
src/it/ht/rcs/console/entities/view/components/advanced/timeline/AdvancedTimeline.mxml

Summary

Maintainability
Test Coverage
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
                 xmlns:s="library://ns.adobe.com/flex/spark"
                 xmlns:mx="library://ns.adobe.com/flex/mx"
                 width="100%"
                 height="200">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <fx:Metadata>
    [Event(name="dateChange", type="flash.events.Event")]
    [Event(name="stop", type="flash.events.Event")]
    [Event(name="play", type="flash.events.Event")]
    [Event(name="ready", type="flash.events.Event")]
  </fx:Metadata>
    <fx:Script>
        <![CDATA[
            import spark.components.BorderContainer;
            import spark.components.Label;
            import spark.components.SkinnableContainer;
            import spark.core.SpriteVisualElement;
            import spark.primitives.Rect;

            private var days:int=30;
            private var thumb:SpriteVisualElement;
            private var thumbDrag:Boolean;

            [Bindable]
            private var dayHeight:Number=120;
            [Bindable]
            public var startDate:Date;
            [Bindable]
            public var endDate:Date;
            [Bindable]
            public var currentDate:Date;
            [Bindable]
            private var currentIndex:int;
            [Bindable]
            public var currentItem:HourRenderer;
            [Bindable]
            public var isPlaying:Boolean;

            public var frames:Array;
            public var hours:Dictionary;

            private var timeline:Group;
            private var monthsHeader:Group;
            public var t:Timer;


            public static const DAY:int=1000 * 60 * 60 * 24;
            public static const HOUR:int=1000 * 60 * 60;



            private var monthNames:Array=["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "Dicember"]


            private static const MINUTES_PER_DAY:int=60 * 24;

            public function init():void
            {

                t=new Timer(250);
                t.addEventListener(TimerEvent.TIMER, onTick)

                currentDate=new Date()
                currentDate.date=startDate.date;
                currentDate.month=startDate.month;
                currentDate.fullYear=startDate.fullYear;
                currentDate.hours=startDate.hours;
                currentDate.minutes=startDate.minutes
                currentIndex=0;
                currentItem=null //??TODO
                dispatchEvent(new Event("dateChange"));

                thumb=new SpriteVisualElement();
                thumb.graphics.beginFill(0xFF0000, 0.5);
                thumb.graphics.drawRect(0, 0, 12, 6);
                thumb.buttonMode=true;
                thumb.useHandCursor=true;
                thumb.addEventListener(MouseEvent.MOUSE_DOWN, onThumbClick)

                draw();
            }

            private function onThumbClick(e:MouseEvent):void
            {
                thumbDrag=true;
                thumb.removeEventListener(MouseEvent.MOUSE_DOWN, onThumbClick)

                thumb.addEventListener(MouseEvent.MOUSE_UP, onThumbUp)
                this.stage.addEventListener(MouseEvent.MOUSE_UP, onThumbUp)

            }

            private function onThumbMove(e:MouseEvent):void
            {
                if (thumbDrag)
                {
                    isPlaying=false;
                    t.stop();
                    dispatchEvent(new Event("stop"));

                    var h:HourRenderer=e.currentTarget as HourRenderer;
                    trace(h.date)
                    thumb.x=h.x;
                    thumb.y=h.y;
                    currentDate.date=h.date.date;
                    currentDate.month=h.date.month;
                    currentDate.fullYear=h.date.fullYear;
                    currentDate.hours=h.date.hours;
                    currentDate.minutes=h.date.minutes
                    currentItem=h;
                    currentIndex=h.index;
                    dispatchEvent(new Event("dateChange"));
                }

            }

            public function reset():void
            {
                currentDate.time=endDate.time;
                currentItem=frames[frames.length - 1]
                currentIndex=frames.length - 1
          
        thumb.x=frames[currentIndex].x;
        thumb.y=frames[currentIndex].y;
        
                dispatchEvent(new Event("dateChange"));
            }



            private function onThumbUp(e:MouseEvent):void
            {
                thumbDrag=false;
                thumb.addEventListener(MouseEvent.MOUSE_DOWN, onThumbClick)

                thumb.removeEventListener(MouseEvent.MOUSE_UP, onThumbUp)
                this.stage.removeEventListener(MouseEvent.MOUSE_UP, onThumbUp)
            }

            public function draw():void
            {
                //remove if needed


                this.removeAllElements();

                timeline=new Group()
                timeline.y=12;
                addElement(timeline)

                monthsHeader=new Group();
                addElement(monthsHeader)

                t.stop();
                dispatchEvent(new Event("stop"));
                isPlaying=false;

                frames=new Array();
                hours=new Dictionary();

                var numDays:int=Math.floor((endDate.time - startDate.time + DAY) / DAY);

                currentDate.time=startDate.time;

                var currentHour:Number=0;
                var xPos:Number=0;

                var months:Array=new Array()
                var currentMonth:Number=currentDate.month;
                var month:Object={days: 0, index: currentMonth}
                months.push(month)
                var index:int=0;

        var d:Group;
        var l:Label;
        var yPos:Number;
        
                for (var i:int=0; i < numDays; i++)
                {
                    d=drawDay();
                    l=new Label();
                    l.text=String(currentDate.date)
                    l.width=12;

                    l.y=-10
                    l.setStyle("textAlign", "center")
                    l.setStyle("fontSize", 8)
                    //l.setStyle("fontWeight", "bold")
                    d.addElement(l)
                    yPos=0;

                    for (var j:int=0; j < 24; j++)
                    {
                        var h:HourRenderer=new HourRenderer()
                        h.date.time=currentDate.time;
                        h.date.hours=j;
                        h.date.minutes=0;
                        h.date.seconds=0;
                        h.index=index
                        //h.toolTip=String(h.date);
                        h.y=yPos;
                        h.x=xPos
                        h.mouseChildren=false;
                        h.addEventListener(MouseEvent.CLICK, onHourClick)
                        h.addEventListener(MouseEvent.MOUSE_OVER, onThumbMove)

                        timeline.addElement(h);
                        index++;
                        var key:String=formatDate(h.date)
                        frames.push(h);
                        hours[key]=h;
                        yPos+=dayHeight / 24;
                    }
                    d.x=xPos;
                    timeline.addElement(d);
                    month.days++;
                    xPos+=12;

                    currentDate.time+=DAY;
                    if (currentDate.month != currentMonth)
                    {
                        currentMonth=currentDate.month;
                        month={days: 0, index: currentMonth}
                        months.push(month)
                    }
                }


                //draw months headers  //remove elements

                xPos=0;
        var m:int
        var monthRenderer:Group;
        
                for (m=0; m < months.length; m++)
                {
                    monthRenderer=new Group;
                    monthRenderer.height=30
                    monthRenderer.width=12 * months[m].days;
                    monthRenderer.x=xPos;
                    monthRenderer.graphics.lineStyle(1, 0x000000);
                    monthRenderer.graphics.moveTo(0, 0)
                    monthRenderer.graphics.lineTo(0, 132)
                    l=new Label();
                    l.text=monthNames[months[m].index];
                    l.width=monthRenderer.width;
                    l.y=50
                    l.alpha=0.2;
                    l.setStyle("textAlign", "center");
                    l.setStyle("fontSize", 24);
                    if (monthRenderer.width > 6 * 20)
                        monthRenderer.addElement(l);
                    monthsHeader.addElement(monthRenderer);
                    xPos+=monthRenderer.width;
                }

                thumb.x=0;
                thumb.y=0;
                timeline.addElement(thumb);

                this.setElementIndex(monthsHeader, 0)
          
                currentDate.time=startDate.time;
                dispatchEvent(new Event("ready"))
                dispatchEvent(new Event("dateChange"));
            }

            private function onHourClick(e:MouseEvent):void
            {
                isPlaying=false;
                t.stop();
                dispatchEvent(new Event("stop"));

                var h:HourRenderer=e.currentTarget as HourRenderer;
                h.date.minutes=0;
                trace(h.date);
                thumb.x=h.x
                thumb.y=h.y;
                currentDate.date=h.date.date;
                currentDate.month=h.date.month;
                currentDate.fullYear=h.date.fullYear;
                currentDate.hours=h.date.hours;
                currentDate.minutes=h.date.minutes
                currentIndex=h.index
                currentItem=h;
                dispatchEvent(new Event("dateChange"));
            }



            private function drawDay():Group
            {
                var s:Group=new Group();
                s.graphics.lineStyle(0.5, 0xCCCCCC, 0.5);
                s.graphics.drawRect(0, -14, 12, dayHeight + 14);
                return s;
            }

            private function onTick(e:TimerEvent):void
            {
                //thumb.y+=(6/59)
                if (currentDate.minutes == 59)
                {
                    if (currentIndex < frames.length - 1)
                    {
                        currentIndex++;
                        thumb.x=frames[currentIndex].x;
                        thumb.y=frames[currentIndex].y;
                    }
                    else
                    {
                        isPlaying=false;
                        t.stop();
                        dispatchEvent(new Event("stop"));
                    }
                }
                currentDate.minutes++
                currentItem=frames[currentIndex]
                dispatchEvent(new Event("dateChange"));
            }

            public function doPlay():void
            {
                isPlaying=true;
                t.start()
                dispatchEvent(new Event("play"));
            }

            public function doStop():void
            {
                isPlaying=false;
                t.stop()
                dispatchEvent(new Event("stop"));

            }

            private function doubleDigits(n:Number):String
            {
                if (n < 10)
                    return "0" + String(n);
                return String(n);
            }

            private function formatDate(d:Date):String
            {
                if (!d)
                    return "";
                return String(d.fullYear) + doubleDigits(d.month + 1) + doubleDigits(d.date) + doubleDigits(d.hours);
            }
        ]]>
    </fx:Script>
</s:Group>