public DpiScalableAttribute GetDpiScalableAttribute(PropertyInfo prop)
        {
            // we have to iterate through all BaseTypes.
            // System.Reflection wouldn't do that for us (which is quite unexpected behavior)

            DpiScalableAttribute attr = null;

            while (prop != null)
            {
                attr = prop.GetAttribute <DpiScalableAttribute> ();
                if (attr != null)
                {
                    return(attr);
                }
                prop = prop.ReflectedType.BaseType.GetProperty(prop.Name);
            }

            return(null);
        }
        public void ScaleGUI(Widget root = null)
        {
            if (Owner == null)
            {
                this.LogError("ScaleGUI: Owner must not be null");
                return;
            }

            if (root == null && Owner as SummerGUIWindow != null)
            {
                root = (Owner as SummerGUIWindow).Controls;
            }

            float absFactor = Owner.ScaleFactor;

            SummerGUI.Scrolling.ScrollBar.ScrollBarWidth = 17.Scale(absFactor);

            Stopwatch sw = Stopwatch.StartNew();

            int widgetCount   = 0;
            int propertyCount = 0;

            root.EnumerateWidgets().Where(w => Math.Abs(w.ScaleFactor - absFactor) > float.Epsilon).Reverse().ForEach(w => {
                widgetCount++;
                float relFactor = absFactor / w.ScaleFactor;

                Type wType = w.GetType();
                wType.GetProperties().ForEach(prop => {
                    DpiScalableAttribute attr = GetDpiScalableAttribute(prop);
                    if (attr != null)
                    {
                        try {
                            object originalValue = ReflectionUtils.GetPropertyValue(w, prop.Name);
                            prop.SetValue(w, ScaleValue(originalValue, relFactor));
                            propertyCount++;
                        } catch (Exception ex) {
                            ex.LogError("ScaleGUI, set value for property '{0}.{1}'", wType.Name, prop.Name);
                        }
                    }
                });

                if (w.Styles != null)
                {
                    int styleID = 0;
                    w.Styles.ForEach(style => {
                        styleID++;
                        if (style != null)
                        {
                            Type styleType = style.GetType();
                            styleType.GetProperties().ForEach(prop => {
                                DpiScalableAttribute attr = GetDpiScalableAttribute(prop);
                                if (attr != null)
                                {
                                    try {
                                        object originalValue = ReflectionUtils.GetPropertyValue(style, prop.Name);
                                        prop.SetValue(style, ScaleValue(originalValue, relFactor));
                                        propertyCount++;
                                    } catch (Exception ex) {
                                        ex.LogError("ScaleGUI, set value for style-property '{0}.{1}'", styleType.Name, prop.Name);
                                    }
                                }
                            });
                        }
                    });
                }

                try {
                    w.OnScaleWidget(Owner, absFactor);
                } catch (Exception ex) {
                    ex.LogError("OnScaleWidget");
                }
            });

            this.LogVerbose("Scaling successfully applied to {0} properties of {1} widgets in {2} ms.", propertyCount.ToString("n0"), widgetCount.ToString("n0"), sw.ElapsedMilliseconds.ToString("n0"));

            Owner.Invalidate();
            //root.Invalidate ();
            // ToDo:
        }