Ejemplo n.º 1
0
        /// <summary>
        /// Vrátí absolutní souřadnice (AbsoluteBounds) viditelné části pro daný Child prvek.
        /// Souřadný systém prvku volí podle toho, zda prvek je umístěn ve fyzických nebo ve virtuálních souřadnicích.
        /// </summary>
        /// <param name="item">Prvek</param>
        /// <param name="layer">Vrstva, ovlivní výběr typu souřadnic</param>
        /// <returns></returns>
        protected Rectangle GetAbsoluteVisibleBounds(IInteractiveItem item, GInteractiveDrawLayer layer)
        {
            Coordinates parentCoordinates = (item.Is.OnPhysicalBounds ? this._PhysicalCoordinates : this._VirtualCoordinates);
            Rectangle   bounds            = GetItemBounds(item, layer);

            return(parentCoordinates.GetVisibleBounds(parentCoordinates.GetAbsoluteBounds(bounds)));
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Vrátí danou barvu, s modifikovanou průhledností Opacity (<see cref="Color.A"/>).
 /// Zadaná Opacity je respektována, ale pokud celý graf má deklarovaou svoji průhlednost v <see cref="TimeGraph.GraphOpacity"/>, pak je akceptována rovněž.
 /// A dále, pokud se aktuálně kreslí do vrstvy <see cref="GInteractiveDrawLayer.Interactive"/>, pak je akceptována i hodnota <see cref="DragDropDrawInteractiveOpacity"/>.
 /// </summary>
 /// <param name="baseColor">Výchozí barva, typicky BackColor nebo ForeColor prvku grafu.</param>
 /// <param name="drawLayer">Vykreslovaná vrstva grafiky</param>
 /// <param name="drawMode">Režim kreslení předaný systémem</param>
 /// <param name="forGroup">true = pro barvu grupy / false = pro barvu prvku</param>
 /// <param name="forBackColor">true = pro barvu pozadí / false = pro barvu okrajů, čar a textů</param>
 /// <returns></returns>
 public Color?GetColorWithOpacity(Color?baseColor, GInteractiveDrawLayer drawLayer, DrawItemMode drawMode, bool forGroup, bool forBackColor)
 {
     if (!baseColor.HasValue)
     {
         return(null);
     }
     return(this.GetColorWithOpacity(baseColor.Value, drawLayer, drawMode, forGroup, forBackColor));
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Vrací souřadnice daného prvku <paramref name="item"/> pro danou vrstvu <paramref name="layer"/>.
 /// Pro vrstvu <see cref="GInteractiveDrawLayer.Interactive"/> vrací interaktivní souřadnice <see cref="IInteractiveItem.BoundsInteractive"/>, pokud jsou zadány.
 /// Standardně vrací <see cref="IInteractiveItem.Bounds"/>.
 /// </summary>
 /// <param name="item"></param>
 /// <param name="layer"></param>
 /// <returns></returns>
 protected Rectangle GetItemBounds(IInteractiveItem item, GInteractiveDrawLayer layer)
 {
     if (item == null)
     {
         return(Rectangle.Empty);
     }
     if (layer == GInteractiveDrawLayer.Interactive && item.BoundsInteractive.HasValue)
     {
         return(item.BoundsInteractive.Value);
     }
     return(item.Bounds);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Vrátí instanci třídy <see cref="BoundsInfo"/> pro daný IInteractiveParent parent. Ten může být i <see cref="IAutoScrollContainer"/>!
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="layer">Vrstva grafiky. Ovlivňuje výběr Bounds z dodaného prvku: pro vrstvu <see cref="GInteractiveDrawLayer.Interactive"/>
        /// akceptuje souřadnice <see cref="IInteractiveItem.BoundsInteractive"/>, jinak bere standardně <see cref="IInteractiveItem.Bounds"/>.</param>
        /// <returns></returns>
        public static BoundsInfo CreateForParent(IInteractiveParent parent, GInteractiveDrawLayer layer = GInteractiveDrawLayer.Standard)
        {
            Coordinates physicalCoordinates = Coordinates.FromSize(parent.ClientSize);
            Coordinates virtualCoordinates  = physicalCoordinates;

            if (parent is IAutoScrollContainer)
            {
                IAutoScrollContainer autoScrollContainer = parent as IAutoScrollContainer;
                if (autoScrollContainer.AutoScrollActive)
                {
                    Point     virtualOrigin = autoScrollContainer.VirtualOrigin;
                    Rectangle virtualBounds = physicalCoordinates.GetVisibleBounds(autoScrollContainer.VirtualBounds);
                    virtualCoordinates = Coordinates.FromOrigin(virtualOrigin, virtualBounds);
                }
            }
            return(new BoundsInfo(physicalCoordinates, virtualCoordinates, true, true, layer));
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Vrátí danou barvu, s modifikovanou průhledností Opacity (<see cref="Color.A"/>).
 /// Zadaná Opacity je respektována, ale pokud celý graf má deklarovaou svoji průhlednost v <see cref="TimeGraph.GraphOpacity"/>, pak je akceptována rovněž.
 /// A dále, pokud se aktuálně kreslí do vrstvy <see cref="GInteractiveDrawLayer.Interactive"/>, pak je akceptována i hodnota <see cref="DragDropDrawInteractiveOpacity"/>.
 /// </summary>
 /// <param name="baseColor">Výchozí barva, typicky BackColor nebo ForeColor prvku grafu.</param>
 /// <param name="drawLayer">Vykreslovaná vrstva grafiky</param>
 /// <param name="drawMode">Režim kreslení předaný systémem</param>
 /// <param name="forGroup">true = pro barvu grupy / false = pro barvu prvku</param>
 /// <param name="forBackColor">true = pro barvu pozadí / false = pro barvu okrajů, čar a textů</param>
 /// <returns></returns>
 public Color GetColorWithOpacity(Color baseColor, GInteractiveDrawLayer drawLayer, DrawItemMode drawMode, bool forGroup, bool forBackColor)
 {
     if (!this.IsDragged)
     {   // Běžný stav prvku, kdy tento pvek není přetahován jinam:
         return(this._GetColorWithOpacityStandard(baseColor, forGroup, forBackColor, null));
     }
     else
     {   // Drag and Drop tohoto prvku, kdy prvek je přemisťován jinam:
         if (drawLayer == GInteractiveDrawLayer.Standard)
         {
             return(this._GetColorWithOpacityDragOriginal(baseColor, forGroup, forBackColor));
         }
         else
         {
             return(this._GetColorWithOpacityDragTarget(baseColor, forGroup, forBackColor));
         }
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Vrátí novou instanci <see cref="BoundsInfo"/> pro daný Child objekt, který od té chvíle bude Parent objektem pro další, v něm vnořené prvky.
        /// Respektuje přitom, že daný Child objekt se může pohybovat ve virtuálních anebo ve fyzických souřadnicích aktuálního systému.
        /// </summary>
        /// <param name="item">Prvek</param>
        /// <param name="layer">Vrstva, ovlivní výběr typu souřadnic</param>
        /// <returns></returns>
        protected BoundsInfo GetChildsBoundsInfo(IInteractiveItem item, GInteractiveDrawLayer layer)
        {
            // Child prvek je umístěn ve svých souřadnicích Bounds, a to buď ve fyzickém nebo ve virtuálním prostoru (koordinátech):
            Coordinates parentCoordinates = (item.Is.OnPhysicalBounds ? this._PhysicalCoordinates : this._VirtualCoordinates);

            // Určíme jeho absolutní souřadnice = jeho Bounds posunuté do odpovídajících (fyzické/virtuální) koordinátů:
            Rectangle bounds         = GetItemBounds(item, layer);
            Rectangle absoluteBounds = parentCoordinates.GetAbsoluteBounds(bounds);

            // Prvek může zmenšit tento prostor o své vnitřní okraje.
            //  Prostor okrajů patří do prvku (=prvek sám si je dokáže vykreslit), ale nepatří do prostoru, který prvek poskytuje svým child prvkům:
            // Toto jsou tedy absolutní souřadnice prostoru, ve kterém budou zobrazovány Child prvky:
            Rectangle clientBounds = absoluteBounds.Sub(item.ClientBorder);

            // Určíme viditelnou oblast (průsečík z prostoru pro childs s prostorem dosud viditelné oblasti):
            Rectangle visibleBounds = parentCoordinates.GetVisibleBounds(clientBounds);

            // V rámci těchto souřadnic prvek item může poskytovat svůj souřadný systém standardní (fyzický) anebo i virtuální:
            Coordinates physicalCoordinates = Coordinates.FromOrigin(clientBounds.Location, visibleBounds);
            Coordinates virtualCoordinates  = physicalCoordinates;

            if (item is IAutoScrollContainer)
            {   // Child prvek (item) je AutoScrollContainer:
                IAutoScrollContainer autoScrollContainer = item as IAutoScrollContainer;
                if (autoScrollContainer.AutoScrollActive)
                {
                    Point     virtualOrigin = parentCoordinates.GetAbsolutePoint(autoScrollContainer.VirtualOrigin);
                    Rectangle virtualBounds = parentCoordinates.GetVisibleBounds(parentCoordinates.GetAbsoluteBounds(autoScrollContainer.VirtualBounds));
                    virtualCoordinates = Coordinates.FromOrigin(virtualOrigin, virtualBounds);
                }
            }
            bool isVisible = this.IsVisible && item.Is.Visible;
            bool isEnabled = this.IsEnabled && item.Is.Enabled;

            return(new BoundsInfo(physicalCoordinates, virtualCoordinates, isVisible, isEnabled, layer));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Metoda vrátí absolutní souřadnice prostoru, který je zadán jako relativní souřadnice v daném containeru.
        /// Pokud tedy například daný container je umístěn na (absolutní) souřadnici Bounds = { 100,20,200,50 }, a dané relativní souřadnice jsou { 5,5,10,10 },
        /// pak výsledné absolutní souřadnice jsou { 105,25,10,10 }.
        /// </summary>
        /// <param name="container"></param>
        /// <param name="relativeBounds"></param>
        /// <param name="currentLayer">Vrstva, jejíž souřadnice řešíme. Každý prvek může mít souřadnice různé podle toho, o kterou vrstvu se jedná.
        /// To je důsledek procesu Drag and Drop, kdy ve standardní vrstvě se prvek nachází na výchozích souřadnicích Bounds,
        /// ale ve vrstvě <see cref="GInteractiveDrawLayer.Interactive"/> je na souřadnicích Drag.</param>
        /// <returns></returns>
        public static Rectangle GetAbsoluteBoundsInContainer(IInteractiveParent container, Rectangle relativeBounds, GInteractiveDrawLayer currentLayer)
        {
            if (container == null)
            {
                return(relativeBounds);
            }
            BoundsInfo boundsInfo = BoundsInfo.CreateForContainer(container, currentLayer);

            return(relativeBounds.Add(boundsInfo.AbsolutePhysicalOriginPoint));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Vrací <see cref="BoundsInfo"/> pro daného parenta a danou vrstvu souřadnic
        /// </summary>
        /// <param name="forItem"></param>
        /// <param name="asContainer"></param>
        /// <param name="layer">Vrstva, jejíž souřadnice řešíme. Každý prvek může mít souřadnice různé podle toho, o kterou vrstvu se jedná.
        /// To je důsledek procesu Drag and Drop, kdy ve standardní vrstvě se prvek nachází na výchozích souřadnicích Bounds,
        /// ale ve vrstvě <see cref="GInteractiveDrawLayer.Interactive"/> je na souřadnicích Drag = <see cref="IInteractiveItem.BoundsInteractive"/>.</param>
        /// <returns></returns>
        private static BoundsInfo _CreateForItem(IInteractiveParent forItem, bool asContainer, GInteractiveDrawLayer layer)
        {
            // Nejprve si nastřádám řadu prvků počínaje daným prvkem/nebo jeho parentem, přes jeho Parenty, až k nejspodnějšímu prvku (který nemá parenta):
            List <IInteractiveParent> parents = new List <IInteractiveParent>();
            Dictionary <uint, object> scanned = new Dictionary <uint, object>();
            IInteractiveParent        parent  = (asContainer ? forItem : forItem.Parent);

            while (parent != null)
            {
                if (scanned.ContainsKey(parent.Id))
                {
                    break;                                   // Zacyklení!
                }
                parents.Add(parent);
                parent = parent.Parent;                      // Krok na dalšího parenta
            }

            // Pak vytvořím postupně řadu BoundsInfo, počínaje od posledního v poli parents (=fyzický Control):
            int last = parents.Count - 1;

            // Pokud na vstupu byl předán container = fyzický Control, pak pole má 0 prvků a výstupní BoundsInfo je vytvořeno pro daný Control!
            if (last < 0)
            {
                return(BoundsInfo.CreateForParent(forItem));
            }
            // Poslední prvek pole = parents[last] = fyzický Control:
            BoundsInfo boundsInfo = BoundsInfo.CreateForParent(parents[last], layer);

            for (int i = last - 1; i >= 0; i--)
            {
                IInteractiveItem it = parents[i] as IInteractiveItem;
                if (it == null)
                {
                    continue;
                }
                boundsInfo = boundsInfo.GetChildsBoundsInfo(it, layer);
            }

            // Na závěr do výsledného boundsInfo vepíšu dodaný Child prvek (forItem) jako Current prvek:
            if (!asContainer && forItem is IInteractiveItem)
            {
                boundsInfo.CurrentItem = forItem as IInteractiveItem;
            }
            return(boundsInfo);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Pro daný prvek určí a vrátí jeho vlastní souřadný systém, který poskytuje svým Childs.
 /// Jde tedy o systém, do jehož <see cref="CurrentItem"/> lze vložit kterýkoli jeho Childs, a systém bude vracet jeho souřadnice.
 /// Vrácený prvek má property <see cref="BoundsInfo.CurrentItem"/> neobsazenou.
 /// </summary>
 /// <param name="currentContainer"></param>
 /// <param name="layer">Vrstva, jejíž souřadnice řešíme. Každý prvek může mít souřadnice různé podle toho, o kterou vrstvu se jedná.
 /// To je důsledek procesu Drag and Drop, kdy ve standardní vrstvě se prvek nachází na výchozích souřadnicích Bounds,
 /// ale ve vrstvě <see cref="GInteractiveDrawLayer.Interactive"/> je na souřadnicích Drag.</param>
 /// <returns></returns>
 public static BoundsInfo CreateForContainer(IInteractiveParent currentContainer, GInteractiveDrawLayer layer)
 {
     CheckItem(currentContainer, "CreateForContainer");
     return(_CreateForItem(currentContainer, true, layer));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Privátní konstruktor pro dané koordináty
 /// </summary>
 /// <param name="physicalCoordinates"></param>
 /// <param name="virtualCoordinates"></param>
 /// <param name="isVisible"></param>
 /// <param name="isEnabled"></param>
 /// <param name="layer">Vrstva grafiky. Ovlivňuje výběr Bounds z dodaného prvku: pro vrstvu <see cref="GInteractiveDrawLayer.Interactive"/>
 /// akceptuje souřadnice <see cref="IInteractiveItem.BoundsInteractive"/>, jinak bere standardně <see cref="IInteractiveItem.Bounds"/>.</param>
 private BoundsInfo(Coordinates physicalCoordinates, Coordinates virtualCoordinates, bool isVisible, bool isEnabled, GInteractiveDrawLayer layer)
 {
     this._PhysicalCoordinates = physicalCoordinates;
     this._VirtualCoordinates  = virtualCoordinates;
     this._IsVisible           = isVisible;
     this._IsEnabled           = isEnabled;
     this._CurrentLayer        = layer;
 }
Ejemplo n.º 11
0
        /*
         * 1. ÚČEL
         * POZICE
         * Kreslící systém ve třídách ControlBuffered a ControlLayered (a následně interaktivní control InteractiveControl)
         * je postaven na vykreslování jednotlivých prvků (child itemů) do globální grafiky celého WinForm Controlu.
         * K tomu vykreslování je třeba znát absolutní pozici konkrétního child itemu vzhledem k WinForm Controlu.
         * Přitom samozřejmě pozicování child itemů (=jejich Bounds) je relativní výhradně k jejich Parentu,
         * kterým je jiný child item (=standardní vnořená hierarchie).
         * Jinými slovy, pokud přemístím určitý item na jiné (relativní) souřadnice, pak nemusím měnit souřadnice jeho child itemů.
         * A tyto child itemy se budou nacházet na stejné relativní souřadnici Bounds, ale fyzicky jsou na jiné absolutní souřadnici v rámci WinForm Controlu.
         * (To samé, co platí o vykreslování, je platné i pro interaktivitu podmíněnou akcemi myši.)
         *
         * Účelem třídy BoundsInfo je tedy vypočítat absolutní souřadnice konkrétního child itemu vzhledem k fyzickému WinForm Controlu.
         *
         * VIDITELNOST
         * Dalším úkolem je určit, jaká část itemu je fyzicky viditelná.
         * Pokud určitý child item leží částečně mimo zobrazovanou oblast WinForm Controlu, anebo mimo souřadnice Bounds svého parent itemu,
         * pak child item může být částečně nebo zcela neviditelný.
         * To má vliv na vykreslování (nebudeme vykreslovat item, který je zcela mimo viditelnou oblast),
         * i na interaktivitu (prvek item nemůže zachytávat akce myši v oblasti, kde není viditelný třeba proto, že leží mimo prostor svého parenta).
         *
         * 2. DALŠÍ FUNKCIONALITA = AutoScroll prvky
         * Systém prvků dovoluje implementovat AutoScroll = postup, který detekuje rozmístění child itemů, určuje tak potřebný prostor,
         * porovnává jej s disponibilním prostorem v parent prvku (ať je to WinForm Control nebo běžný parent item);
         * a pokud je disponibilní prostor menší než je třeba, pak aktivuje AutoScroll režim (=zobrazí se ScrollBary).
         * Tím se stává prostor hostitelského prvku "virtuálním" = jeho souřadnice se posouvají vlivem scrollování.
         * I tuto věc řeší třída BoundsInfo.
         *
         * 3. POSTUP ŘEŠENÍ - pro směr Parent => Child
         * a) Vstupem do souřadného systému je WinForm Control
         * b) Souřadný systém zajišťuje přepočet relativní souřadnice určitého child itemu (jeho Bounds) do absolutní pozice v rámci WinForm Controlu
         * (fyzicky jde o pozici bodu počátku, který se přičte k souřadnici počátku child itemu Bounds.Location,
         * a výsledkem je fyzická souřadnice na Controlu)
         * c) Kvůli AutoScrollu máme dva souřadné systémy: Fyzický souřadný systém (FSS) a Virtuální (VSS)
         * d) Většina child itemů (běžné) má souřadnice vztažené k VSS, a tedy při AutoScrollu se pohybují ve svém Parentu
         * e) Některé child itemy (ScrollBary od AutoScrollu) mají svoje souřadnice vztažené k FSS, při provádění AutoScrollu se ve svém parentu nepohybují
         * f) Child itemy si tedy pro určení sých Absolute Bounds vyberou "svůj" souřadný systém, jeho bod počátku a podle něj určí svoje absolutní souřadnice;
         * a podle něj určí i své AbsoluteVisibleBounds
         * f) Při vytváření BoundsInfo pro vnořené child itemy se bude vycházet z aktuálních AbsoluteBounds prvku (containeru),
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         */
        #endregion
        #region Metody pro směr Parent to Child
        #region Konstruktory
        /// <summary>
        /// Vrátí instanci třídy <see cref="BoundsInfo"/> pro daný WinForm Control. Ten může být i <see cref="IAutoScrollContainer"/>!
        /// </summary>
        /// <param name="control"></param>
        /// <param name="layer">Vrstva grafiky. Ovlivňuje výběr Bounds z dodaného prvku: pro vrstvu <see cref="GInteractiveDrawLayer.Interactive"/>
        /// akceptuje souřadnice <see cref="IInteractiveItem.BoundsInteractive"/>, jinak bere standardně <see cref="IInteractiveItem.Bounds"/>.</param>
        /// <returns></returns>
        public static BoundsInfo CreateForControl(System.Windows.Forms.Control control, GInteractiveDrawLayer layer = GInteractiveDrawLayer.Standard)
        {
            Coordinates physicalCoordinates = Coordinates.FromSize(control.ClientSize);
            Coordinates virtualCoordinates  = physicalCoordinates;

            if (control is IAutoScrollContainer)
            {
                IAutoScrollContainer autoScrollContainer = control as IAutoScrollContainer;
                if (autoScrollContainer.AutoScrollActive)
                {
                    Point     virtualOrigin = autoScrollContainer.VirtualOrigin;
                    Rectangle virtualBounds = physicalCoordinates.GetVisibleBounds(autoScrollContainer.VirtualBounds);
                    virtualCoordinates = Coordinates.FromOrigin(virtualOrigin, virtualBounds);
                }
            }
            return(new BoundsInfo(physicalCoordinates, virtualCoordinates, true, true, layer));
        }