Exemple #1
0
        public FramelessPopupProvider(HTMLElement wrapsElement = null)
        {
            _container.ClassName = typeof(FramelessPopupProvider).FullName;

            if (wrapsElement != null)
            {
                _container.AppendChild(wrapsElement);
            }

            _popupContainer.AddClasses(Philadelphia.Web.Magics.CssClassPopupContainer);
            _container.AppendChild(_popupContainer);

            _popup.AddClasses(Philadelphia.Web.Magics.CssClassPopup);

            DocumentUtil.AddMouseClickListener(_container, ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                if (ev.HtmlTarget().GetElementOrItsAncestorMatchingOrNull(x => _container == x) != null)
                {
                    return;
                }

                HidePopup();
            });
        }
Exemple #2
0
        public static void AddActions(HTMLElement dst, IEnumerable <HTMLElement> src)
        {
            var leftAndRight = src.ToList().Partition(x => !x.HasAttribute(Magics.AttrAlignToRight));

            dst.ReplaceChildren(
                leftAndRight.Item1
                .ConcatElementIfTrue(
                    leftAndRight.Item2.Any(),
                    DocumentUtil.CreateElementHavingClassName("span", Magics.CssClassFlexSpacer))
                .Concat(leftAndRight.Item2));
        }
        public LabellessReadOnlyView(string elementType = "div", TextType inputType = TextType.TreatAsText, string defaultValue = null)
        {
            _inputType = inputType;

            _elem = DocumentUtil.CreateElementHavingClassName(elementType, GetType().FullName);
            if (_inputType == TextType.TreatAsPreformatted)
            {
                _elem.Style.WhiteSpace = WhiteSpace.Pre;
            }

            if (defaultValue != null)
            {
                Value = defaultValue;
            }
        }
        public LabeledReadOnlyView(TextType type, string label, string containerType = "div", string elementType = "div", string defaultValue = null)
        {
            _type = type;
            if (_type == TextType.TreatAsPreformatted)
            {
                _elem.Style.WhiteSpace = WhiteSpace.Pre;
            }

            _container = DocumentUtil.CreateElementHavingClassName(containerType, GetType().FullName);
            _label     = new HTMLLabelElement()
            {
                TextContent = label
            };
            _elem = new HTMLElement(elementType);
            if (defaultValue != null)
            {
                Value = defaultValue;
            }

            _container.AppendChild(_label);
            _container.AppendChild(_elem);
        }
        public ActionButtonsMenuBarView(
            Func <MenuItemModel, InputTypeButtonActionView> customButtonBuilder = null)
        {
            _buttonBuilder = customButtonBuilder ?? (x => {
                var res = new InputTypeButtonActionView(x.Label.Value);
                x.Label.Changed += (_, __, newValue, ___, ____) =>
                                   res.ProperLabelElem.TextContent = newValue;

                res.Widget.SetAttribute(Magics.AttrDataMenuItemId, x.Id.ToString());

                if (x.DescriptonOrNull != null)
                {
                    res.Widget.Title = x.DescriptonOrNull;
                }

                return(res);
            });

            _nav    = DocumentUtil.CreateElementHavingClassName("nav", GetType().FullName);
            _nav.Id = UniqueIdGenerator.GenerateAsString();

            _actionsCntnr = new HTMLDivElement();
            _nav.AppendChild(_actionsCntnr);
        }
        //TODO refactor this monster
        private static Tuple <HTMLElement, DataGridColumnControllerResult <InternalT> > Create <InternalT, OperT, ViewT>(
            Func <InternalT, OperT> toOper,
            ITransformationMediator listener,
            FilterDef <OperT>[] availableFilters,
            IEnumerable <AggregatorDef <OperT> > rawAvailableAggregators,
            IEnumerable <GrouperDef <OperT> > rawAvailableGroupers,
            Func <IReadWriteValue <OperT>, IReadWriteValueView <HTMLElement, ViewT> > paramEditor,
            OperT initialFilterValue,
            OperT invalidFilterValue,
            IComparer <OperT> sortingImpl)
        {
            var availableAggregators = rawAvailableAggregators.ToList();
            var availableGroupers    = rawAvailableGroupers.ToList();

            AssureUnique(availableFilters, x => x.Label);
            AssureUnique(availableAggregators, x => x.Label);
            AssureUnique(availableGroupers, x => x.Label);

            LocalValue <AggregatorDef <OperT> > aggregateFunc          = null;
            LocalValue <GrouperDef <OperT> >    groupingFunc           = null;
            LocalValue <GroupOrAggregate?>      groupOrAggregateChoice = null;

            FilterDef <OperT> currentFilterImplOrNull = null;
            var filterLabelToImpl = new Dictionary <string, FilterDef <OperT> >();

            availableFilters.ForEach(x => filterLabelToImpl.Add(x.Label, x));

            AggregatorDef <OperT> currentAggrImplOrNull = null;
            var aggregLabelToImpl = new Dictionary <string, AggregatorDef <OperT> >();

            availableAggregators.ForEach(x => aggregLabelToImpl.Add(x.Label, x));

            GrouperDef <OperT> currentGrouperImplOrNull = null;
            var grouperLabelToImpl = new Dictionary <string, GrouperDef <OperT> >();

            availableGroupers.ForEach(x => grouperLabelToImpl.Add(x.Label, x));

            var filterParam = new LocalValue <OperT>(initialFilterValue, invalidFilterValue);

            HTMLElement controllerElem = new HTMLSpanElement {
                ClassName = Magics.CssClassFilterMainContainer
            };
            var actionContainer = new HTMLSpanElement {
                ClassName = Magics.CssClassFilterActionContainer
            };

            controllerElem.AppendChild(actionContainer);

            var groupOrAggregateChoiceView = new RadioBasedSingleChoice();

            Element GetLabelTh()
            {
                var filterTh = controllerElem.ParentElement;
                var filterTr = filterTh.ParentElement;
                var thead    = filterTr.ParentElement;

                var iCol = filterTr.IndexOfChild(filterTh);

                var labelTr = thead.GetChildAtOrNull(0);
                var labelTh = labelTr.GetChildAtOrNull(iCol);

                return(labelTh);
            }

            void MarkAsGrouped(bool activated)
            {
                Logger.Debug(typeof(DataGridColumnController), "markAsGrouped({0})", activated);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassActive);
                GetLabelTh().AddOrRemoveClass(activated, Magics.CssClassWithGrouping);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassWithGrouping);
            }

            void MarkAsAggregated(bool activated)
            {
                Logger.Debug(typeof(DataGridColumnController), "markAsAggregated({0})", activated);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassActive);
                GetLabelTh().AddOrRemoveClass(activated, Magics.CssClassWithAggregation);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassWithAggregation);
            }

            void MarkAsFiltered(bool activated)
            {
                Logger.Debug(typeof(DataGridColumnController), "markAsFiltered({0})", activated);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassActive);
                GetLabelTh().AddOrRemoveClass(activated, Magics.CssClassWithFilter);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassWithFilter);
            }

            var removeFilter = new HTMLAnchorElement {
                Target = "#",
                Title  = I18n.Translate("Remove filter"),
                Text   = FontAwesomeSolid.IconFilter
            };

            removeFilter.AddClasses(Magics.CssClassFilterRemove, IconFontType.FontAwesomeSolid.ToCssClassName());
            actionContainer.AppendChild(removeFilter);

            var removeFilterActionView = new InputTypeButtonActionView(removeFilter);

            LocalActionBuilder.Build(removeFilterActionView, () => {
                currentFilterImplOrNull = null;
                MarkAsFiltered(false);
                listener.UserFilterChangedHandler(ChangeOrRemove.Removed);
            });

            var removeGrouping = new HTMLAnchorElement {
                Target = "#",
                Title  = I18n.Translate("Remove grouping"),
                Text   = FontAwesomeSolid.IconListUl
            };

            removeGrouping.AddClasses(Magics.CssClassGroupingRemove, IconFontType.FontAwesomeSolid.ToCssClassName());
            actionContainer.AppendChild(removeGrouping);

            var removeGroupingActionView = new InputTypeButtonActionView(removeGrouping);

            LocalActionBuilder.Build(removeGroupingActionView, async() => {
                currentGrouperImplOrNull = null;
                MarkAsGrouped(false);
                await groupOrAggregateChoice.DoChange(null, false, null, false);
                listener.UserGroupingChangedHandler(ChangeOrRemove.Removed);
            });

            var removeAggregation = new HTMLAnchorElement {
                ClassName = Magics.CssClassAggregationRemove,
                Target    = "#",
                Title     = I18n.Translate("Remove aggregation"),
                Text      = "Σ"
            };

            actionContainer.AppendChild(removeAggregation);

            var removeAggregationActionView = new InputTypeButtonActionView(removeAggregation);

            LocalActionBuilder.Build(removeAggregationActionView, async() => {
                currentAggrImplOrNull = null;
                await groupOrAggregateChoice.DoChange(null, false, null, false);
                MarkAsAggregated(false);
                listener.UserAggregationChangedHandler(ChangeOrRemove.Removed);
            });



            Action <string> groupingChangedHandler = async labelOrNull => {
                Logger.Debug(typeof(DataGridColumnController), "Setting grouping programmatically to {0}", labelOrNull);

                if (labelOrNull == null)
                {
                    currentGrouperImplOrNull = null;
                    MarkAsGrouped(false);
                    await groupOrAggregateChoice.DoChange(null, false, null, false);

                    return;
                }

                GrouperDef <OperT> grouper;

                if (!grouperLabelToImpl.TryGetValue(labelOrNull, out grouper))
                {
                    Logger.Debug(typeof(DataGridColumnController), "No such grouping func when looking by label");
                    return;
                }

                await groupingFunc.DoChange(grouper, false, null, false);

                currentGrouperImplOrNull = grouper;
                MarkAsGrouped(true);
            };

            Action <string> aggregationChangedHandler = async labelOrNull => {
                Logger.Debug(typeof(DataGridColumnController), "Setting aggregation programmatically to {0}", labelOrNull);

                if (labelOrNull == null)
                {
                    currentAggrImplOrNull = null;
                    MarkAsAggregated(false);
                    await groupOrAggregateChoice.DoChange(null, false, null, false);

                    listener.UserAggregationChangedHandler(ChangeOrRemove.Removed);
                    return;
                }

                if (!aggregLabelToImpl.TryGetValue(labelOrNull, out var aggr))
                {
                    Logger.Debug(typeof(DataGridColumnController), "No such aggregation func when looking by label");
                    return;
                }

                await aggregateFunc.DoChange(aggr, false, null, false);

                currentAggrImplOrNull = aggr;
                MarkAsAggregated(true);
            };

            listener.InitUserSide(groupingChangedHandler, aggregationChangedHandler);



            var filterOper     = new LocalValue <FilterDef <OperT> >(availableFilters.FirstOrDefault());
            var filterOperView = new DropDownSelectBox("")
            {
                PermittedValues = filterLabelToImpl.Select(x => Tuple.Create(x.Key, x.Key))
            };

            filterOperView.BindReadWriteAndInitialize(filterOper,
                                                      x => x != null ? Tuple.Create(x.Label, x.Label) : Tuple.Create("", ""),
                                                      x => !string.IsNullOrEmpty(x.Item1) ? filterLabelToImpl[x.Item1] : null);

            controllerElem.AppendChild(filterOperView.Widget);

            var val = paramEditor(filterParam);

            controllerElem.AppendChild(val.Widget);

            filterParam.Changed += (_, __, newValue, ___, isUserChange) => {
                if (!isUserChange)
                {
                    return;
                }
                currentFilterImplOrNull = filterOper.Value;
                MarkAsFiltered(true);
                listener.UserFilterChangedHandler(ChangeOrRemove.Changed);
            };

            filterOper.Changed += (_, __, newValue, ___, isUserChange) => {
                if (!isUserChange)
                {
                    return;
                }

                currentFilterImplOrNull = newValue;
                MarkAsFiltered(true);
                listener.UserFilterChangedHandler(ChangeOrRemove.Changed);
            };

            {
                groupOrAggregateChoice = new LocalValue <GroupOrAggregate?>(null);
                groupOrAggregateChoiceView.Widget.ClassList.Add(Magics.CssClassGroupOrAggregate);
                groupOrAggregateChoiceView.PermittedValues =
                    EnumExtensions.GetEnumValues <GroupOrAggregate>().Select(x =>
                                                                             Tuple.Create(((int)x).ToString(), x.GetUserFriendlyName()));

                groupOrAggregateChoiceView.BindReadWriteAndInitialize(groupOrAggregateChoice,
                                                                      x => !x.HasValue ? null : Tuple.Create(((int)x).ToString(), x.Value.GetUserFriendlyName()),
                                                                      x => (x == null || string.IsNullOrEmpty(x.Item1)) ?
                                                                      null
                        :
                                                                      (GroupOrAggregate?)Convert.ToInt32(x.Item1));

                groupingFunc = new LocalValue <GrouperDef <OperT> >(availableGroupers.FirstOrDefault());
                var groupingFuncView = new DropDownSelectBox(I18n.Translate("group by:"));

                groupingFuncView.Widget.ClassList.Add(Magics.CssClassGroupingFunc);
                groupingFuncView.PermittedValues = grouperLabelToImpl.Select(x => Tuple.Create(x.Key, x.Key));
                groupingFuncView.BindReadWriteAndInitialize(groupingFunc,
                                                            x => x != null ? Tuple.Create(x.Label, x.Label) : Tuple.Create("", ""),
                                                            x => !string.IsNullOrEmpty(x.Item1) ? grouperLabelToImpl[x.Item1] : null);

                aggregateFunc = new LocalValue <AggregatorDef <OperT> >(availableAggregators.FirstOrDefault());
                var aggregateFuncView = new DropDownSelectBox(I18n.Translate("aggregate by:"));

                aggregateFuncView.Widget.ClassList.Add(Magics.CssClassAggregateFunc);
                aggregateFuncView.PermittedValues = aggregLabelToImpl.Select(x => Tuple.Create(x.Key, x.Key));
                aggregateFuncView.BindReadWriteAndInitialize(aggregateFunc,
                                                             x => x != null ? Tuple.Create(x.Label, x.Label) : Tuple.Create("", ""),
                                                             x => !string.IsNullOrEmpty(x.Item1) ? aggregLabelToImpl[x.Item1] : null);

                groupingFunc.Changed += (_, __, newValue, errors, isUserChange) => {
                    if (!isUserChange)
                    {
                        return;
                    }
                    currentGrouperImplOrNull = newValue;
                    MarkAsGrouped(newValue != null);
                    listener.UserGroupingChangedHandler(newValue != null ? ChangeOrRemove.Changed : ChangeOrRemove.Removed);
                };

                aggregateFunc.Changed += (_, __, newValue, errors, isUserChange) => {
                    if (!isUserChange)
                    {
                        return;
                    }
                    currentAggrImplOrNull = newValue;
                    MarkAsAggregated(newValue != null);
                    listener.UserAggregationChangedHandler(newValue != null ? ChangeOrRemove.Changed : ChangeOrRemove.Removed);
                };

                groupOrAggregateChoice.Changed += (_, __, newValue, ___, isUserChange) => {
                    Logger.Debug(typeof(DataGridColumnController), "groupOrAggregateChoice changed to {0} by {1}", newValue, isUserChange);

                    //if (!isUserChange) {
                    //    return;
                    //}

                    if (!newValue.HasValue)
                    {
                        return;
                    }

                    switch (newValue.Value)
                    {
                    case GroupOrAggregate.Aggregate:
                        currentAggrImplOrNull = aggregateFunc.Value;
                        MarkAsAggregated(true);
                        listener.UserAggregationChangedHandler(ChangeOrRemove.Changed);
                        break;

                    case GroupOrAggregate.Group:
                        currentGrouperImplOrNull = groupingFunc.Value;
                        MarkAsGrouped(true);
                        listener.UserGroupingChangedHandler(ChangeOrRemove.Changed);
                        break;

                    default: throw new Exception("unsupported GroupOrAggregate");
                    }
                };

                controllerElem.AppendChild(groupOrAggregateChoiceView.Widget);
                controllerElem.AppendChild(groupingFuncView.Widget);
                controllerElem.AppendChild(aggregateFuncView.Widget);
            }

            DocumentUtil.AddMouseClickListener(controllerElem, ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                //find out if clicked item is a descendant of th
                if (ev.HtmlTarget().IsDescendantOf(controllerElem.ParentElement))
                {
                    controllerElem.ParentElement.ClassList.Add(Magics.CssClassActive);
                    return;
                }

                controllerElem.ParentElement?.ClassList.Remove(Magics.CssClassActive);
            });

            return(Tuple.Create(controllerElem, new DataGridColumnControllerResult <InternalT> {
                FilterImpl = x =>
                             currentFilterImplOrNull == null || currentFilterImplOrNull.FilterFunc(filterParam.Value, toOper(x)),
                AggregationImpl = x => currentAggrImplOrNull?.AggregatorFunc(x.Select(toOper)),
                GroupingImpl = x => currentGrouperImplOrNull?.GroupingFunc(x.Select(toOper)),
                SortingImpl = new CompareImpl <InternalT>((x, y) => sortingImpl.Compare(toOper(x), toOper(y))),
                IsGroupingActive = () => currentGrouperImplOrNull != null
            }));
        }
        private HorizontalTabbedView(Action <HorizontalTabbedView> addTabs)
        {
            _container = new HTMLDivElement {
                Id        = UniqueIdGenerator.GenerateAsString(),
                ClassName = GetType().FullName
            };

            _tabHandleContainer = new HTMLDivElement {
                ClassName = Magics.CssClassTabHandleContainer
            };

            _tabContentContainer = new HTMLDivElement {
                ClassName = Magics.CssClassTabContentContainer
            };

            _container.AppendChild(_tabHandleContainer);
            _container.AppendChild(_tabContentContainer);

            _tabHandleContainer.OnClick += ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                var target = ev.HtmlTarget();

                if (target == _tabHandleContainer)
                {
                    return;
                }

                var newActiveTabHandle = target.GetParentElementHavingParent(_tabHandleContainer);
                var newActiveTabIdx    = _tabHandleContainer.Children.IndexOfUsingEquals(newActiveTabHandle);

                if (_activeTab == newActiveTabIdx)
                {
                    Logger.Debug(GetType(), "already active tab selected {0}", _activeTab);
                    return;
                }

                Logger.Debug(GetType(), "switching tab from {0} to {1}", _activeTab, newActiveTabIdx);

                if (newActiveTabIdx < 0 || newActiveTabIdx >= _tabContents.Count)
                {
                    Logger.Error(GetType(), "there's no tab at index {0}. ignoring tab switch", newActiveTabIdx);
                    return;
                }

                if (_activeTab >= 0)
                {
                    _tabHandleContainer.Children[_activeTab].ClassList.Remove(Magics.CssClassActive);
                    _tabContentContainer.RemoveAllChildren();
                }

                ActivateTab(newActiveTabIdx);
            };

            addTabs(this);

            DocumentUtil.AddElementAttachedToDocumentListener(_container, () => {
                if (_measured)
                {
                    return;
                }

                var formerlyFocused = Document.ActiveElement;
                Logger.Debug(GetType(), "Measuring tab heights in onAttached");

                // measure tab content
                var oldVis = _tabContentContainer.Style.Visibility;
                _tabContentContainer.Style.Visibility = Visibility.Hidden;

                _tabContents.ForEachI((i, tab) => {
                    _tabContentContainer.RemoveAllChildren();
                    _tabContentContainer.AppendChild(tab);
                });

                _tabContentContainer.RemoveAllChildren();
                _tabContentContainer.Style.Visibility = oldVis;
                _measured = true;

                //assure that focused element within tab stays focused(it may have been lost during measurement process above)
                if (_tabContents.Any())
                {
                    ActivateTab(_activeTab);
                    if (formerlyFocused != Document.ActiveElement)
                    {
                        formerlyFocused.TryFocusElement();
                    }
                }
            });

            //activate first tab
            if (_tabContents.Any())
            {
                ActivateTab(0);
            }
        }
        public TooltipManager()
        {
            //when visible element's ERROR tooltip is changed then -show or hide
            DocumentUtil.AddAttributeChangedListener(Magics.AttrDataErrorsTooltip, el => {
                var content = GetTooltipsOfElementOrNull(el);

                Logger.Debug(GetType(), "dom attr errors changed tooltip to content={0}", content);
                if (content == null)
                {
                    HideTooltipOn(el); //no errors anymore so can delete tooltip
                }
                else
                {
                    ShowTooltipOn(el, TooltipMode.PeekIntoErrors);
                }
            });

            //when visible element's DISABLED tooltip is changed then -show or hide
            DocumentUtil.AddAttributeChangedListener(Magics.AttrDataDisabledTooltip, el => {
                var content = GetTooltipsOfElementOrNull(el);

                Logger.Debug(GetType(), "dom attr errors changed tooltip to content={0}", content);
                if (content == null)
                {
                    HideTooltipOn(el); //no errors anymore so can delete tooltip
                }
                else
                {
                    ShowTooltipOn(el, TooltipMode.PeekIntoErrors);
                }
            });

            //when formerly detached element with ERROR tooltip is attached - show
            DocumentUtil.AddGeneralElementAttachedToDocumentListener(el => {
                if (!HasTooltips(el))
                {
                    return;
                }

                var content = GetTooltipsOfElementOrNull(el);
                Logger.Debug(GetType(), "dom attached changed tooltip to content={0}", content);

                if (content == null)
                {
                    HideTooltipOn(el); //no errors anymore so can delete tooltip
                }
                else
                {
                    ShowTooltipOn(el, TooltipMode.PeekIntoErrors, true);
                }
            });

            //mouse hover should show both DISABLED REASONS and ERRORS
            Document.AddEventListener("mouseover", ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                var htmlTarget = ev.HtmlTarget();

                var elemAndContent = GetTooltipsOfElementOrAncestOrNull(htmlTarget);
                Logger.Debug(GetType(), "mouseover tooltip to-be-hidden?={0}", elemAndContent);

                if (elemAndContent != null)
                {
                    ShowTooltipOn(elemAndContent.Item1, TooltipMode.PermanentErrorsAndDisable);
                }
            });
            Document.AddEventListener("mouseout", ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                var htmlTarget = ev.HtmlTarget();

                var elemAndContent = GetTooltipsOfElementOrAncestOrNull(htmlTarget);
                Logger.Debug(GetType(), "mouseout tooltip hidding content={0}", elemAndContent);

                if (elemAndContent != null)
                {
                    HideTooltipOn(elemAndContent.Item1);
                }
            });
        }
        public AutocompleteDropdown(
            string label,
            TextType textType = TextType.TreatAsText,
            int delayMilisec  = Magics.AutocompleteDefaultDelay)
        {
            _cnt.ClassName = GetType().FullNameWithoutGenerics();

            var lbl = new HTMLLabelElement {
                HtmlFor = _input.Id, TextContent = label
            };

            _cnt.AppendChild(lbl);

            _cnt.AppendChild(_input);
            _cnt.AppendChild(_options);
            HideOptions();

            DocumentUtil.AddMouseDownListener(_cnt, x => {
                if (!x.HasHtmlTarget())
                {
                    return;
                }
                var htmlTarget = x.HtmlTarget();

                if (htmlTarget.IsElementOrItsDescendant(_cnt))
                {
                    //clicked inside control (focus stays within logical control) thus do nothing
                    return;
                }

                HideOptions();
            });

            _input.OnFocus += ev => {
                if (_ignoreNextFocus)
                {
                    _ignoreNextFocus = false;
                    return;
                }

                ShowOptions();

                if (!_input.HasFocus())
                {
                    //non user generated (isTrusted == false) events don't invoke default action in Chrome
                    _ignoreNextFocus = true;
                    _input.Focus();
                }
            };
            _input.OnKeyDown += ev => {
                switch (ev.KeyCode)
                {
                case Magics.KeyCodeEscape:
                    if (OptionsVisible)
                    {
                        ev.PreventDefault();
                        ev.StopPropagation();
                        HideOptions();
                    }
                    break;

                case Magics.KeyCodeEnter:
                case Magics.KeyCodeArrowUp:
                case Magics.KeyCodeArrowDown:
                    ev.PreventDefault();
                    OnKeyboardEvent(AutocompleteSrcType.KeyDown, ev);
                    break;

                case Magics.KeyCodeBackspace:
                    OnKeyboardEvent(AutocompleteSrcType.KeyDown, ev);     //it is not called onkeypress
                    break;

                case Magics.KeyCodeTab:
                    HideOptions();
                    break;

                default: break;
                }
            };
            _input.OnKeyPress += ev => {
                switch (ev.KeyCode)
                {
                case Magics.KeyCodeBackspace:
                case Magics.KeyCodeEnter:
                case Magics.KeyCodeArrowUp:
                case Magics.KeyCodeArrowDown:
                    ev.PreventDefault();
                    break;

                default:
                    OnKeyboardEvent(AutocompleteSrcType.KeyPressed, ev);
                    break;
                }
            };

            _textType     = textType;
            _delayMilisec = delayMilisec;
        }
Exemple #10
0
        public static void InitializeToolkit(
            ILoggerImplementation customLogger = null,
            Func <DatagridContent, Task <FileModel> > spreadsheetBuilder = null,
            bool?clickingOutsideOfDialogDismissesIt = null)
        {
            ExecOnUiThread.SetImplementation(
                async x => {
                x();
                await Task.Run(() => {});     //NOP
            },
                async x => {
                await x();
            });

            if (customLogger != null)
            {
                Logger.ConfigureImplementation(customLogger);
            }
            else if (DocumentUtil.HasQueryParameter("debug") && DocumentUtil.GetQueryParameter("debug") == "lite")
            {
                var toIgnoreByType = new [] {
                    typeof(Philadelphia.Web.GeneralAttrChangedObserver),
                    typeof(Philadelphia.Web.GeneralChildListChangedObserver),
                    typeof(Philadelphia.Web.SpecificChildListChangedObserver),
                    typeof(Philadelphia.Web.TooltipManager),
                    typeof(Philadelphia.Web.MouseObserver),
                    typeof(Philadelphia.Web.FormCanvasExtensions),
                    typeof(Philadelphia.Web.SpecificResizeObserver)
                };

                var toIgnoreByBaseName = new [] {
                    typeof(Philadelphia.Web.DataGridColumn <string, Unit>).FullNameWithoutGenerics()
                };

                Logger.ConfigureImplementation(new ForwardMatchingToConsoleLogLoggerImplementation(
                                                   x => !toIgnoreByType.Contains(x) && !toIgnoreByBaseName.Contains(x.FullNameWithoutGenerics())));
            }
            else if (DocumentUtil.HasQueryParameter("debug"))
            {
                Logger.ConfigureImplementation(new ForwardEverythingToConsoleLogLoggerImplementation());
            }
            else
            {
                Logger.ConfigureImplementation(new ForwardErrorsToConsoleLogLoggerImplementation());
            }

            DocumentUtil.Initialize(); //initialize tooltips, esc handler etc

            var env = EnvironmentTypeUtil.GetInstanceFromWindow(Window.Instance);

            Document.Body.SetAttribute(Magics.AttrDataEnvironment, env.AsDataEnvironmentAttributeValue());

            Func <DatagridContent, Task <FileModel> > noExportImpl =
                _ => {
                throw new Exception("spreadsheet builder not provided via DataGridSettings.Init()");
            };

            DataGridSettings.Init(spreadsheetBuilder ?? noExportImpl);

            Document.OnDragEnter += ev => {
                Document.Body.SetAttribute(Magics.AttrDataDraggingFile, "x");
                ev.PreventDefault();
            };
            //detect real end of dragging (leaving outside of browser)
            //https://stackoverflow.com/questions/3144881/how-do-i-detect-a-html5-drag-event-entering-and-leaving-the-window-like-gmail-d#14248483
            Document.OnDragLeave += ev => {
                var clientX = (int)ev.GetFieldValue("clientX");
                var clientY = (int)ev.GetFieldValue("clientY");

                if (clientX <= 0 || clientY <= 0)
                {
                    Document.Body.RemoveAttribute(Magics.AttrDataDraggingFile);
                }

                Logger.Debug(typeof(Toolkit), "Document dragleave {0}", ev.Target);
            };

            switch (env)
            {
            case EnvironmentType.Desktop:
                BaseFormCanvasTitleStrategy           = x => new RegularDomElementTitleFormCanvasStrategy(x);
                BaseFormCanvasExitButtonBuilderOrNull = DefaultExitButtonBuilder;
                ClickingOutsideOfDialogDismissesIt    = clickingOutsideOfDialogDismissesIt ?? false;
                break;

            case EnvironmentType.IndustrialAndroidWebApp:
                BaseFormCanvasTitleStrategy           = x => new BodyBasedPropagatesToAppBatTitleFormCanvasStrategy(x);
                BaseFormCanvasExitButtonBuilderOrNull = null;
                ClickingOutsideOfDialogDismissesIt    = clickingOutsideOfDialogDismissesIt ?? true;

                IawAppApi.SetOnBackPressed(() => {
                    Logger.Debug(typeof(Toolkit), "backbutton pressed");
                    var consumed = DocumentUtil.TryCloseTopMostForm();
                    Logger.Debug(typeof(Toolkit), "backbutton consumed?={0}", consumed);
                    return(consumed);
                });
                break;

            default: throw new Exception("unsupported environment");
            }
        }
        protected TwoPanelsWithResizer(
            Hideability hideable, int minPanelSizePx, Tuple <int?, int?> fixedSize, SpacingPolicy?spacingPolicy)
        {
            MinPanelSizePx = minPanelSizePx;

            if (fixedSize == null && !spacingPolicy.HasValue ||
                fixedSize != null && spacingPolicy.HasValue ||
                fixedSize != null && fixedSize.Item1.HasValue && fixedSize.Item2.HasValue ||
                fixedSize != null && !fixedSize.Item1.HasValue && !fixedSize.Item2.HasValue)
            {
                throw new Exception("Either spacing policy needs to be provided OR exactly one fixedSize dimension");
            }

            Hideable             = hideable;
            _fixedSize           = fixedSize;
            _spacingPolicy       = spacingPolicy;
            _container.ClassName = GetType().FullName;
            _container.Id        = UniqueIdGenerator.GenerateAsString();
            _splitter.ClassName  = Magics.CssClassSplitter;

            _container.AppendChild(FirstPanel);
            _container.AppendChild(_splitter);
            _container.AppendChild(SecondPanel);

            _splitter.OnTouchStart += x => {
                if (!x.HasHtmlTarget())
                {
                    return;
                }

                var htmlTarget = x.HtmlTarget();

                if (!htmlTarget.IsElementOrItsDescendant(_splitter))
                {
                    return;
                }

                _isDragging = true;
                _touchId    = x.TargetTouches[0].Identifier;
                Logger.Debug(GetType(), "TouchStart {0}", _touchId);
            };

            _splitter.OnTouchEnd += ev => {
                _isDragging = false;
                _touchId    = 0;
                Logger.Debug(GetType(), "TouchEnd {0}", _touchId);
            };

            _splitter.OnTouchMove += ev => {
                if (!_isDragging)
                {
                    return;
                }

                var touch = ev.Touches.FirstOrDefault(x => x.Identifier == _touchId);

                Logger.Debug(GetType(), "TouchMove {0} present?={1}", _touchId, touch != null);

                if (touch == null)
                {
                    return;
                }

                var sizes = CalculateSizesOnUserResize(touch.PageX, touch.PageY);

                if (sizes.Item1 < minPanelSizePx || sizes.Item2 < minPanelSizePx)
                {
                    return;
                }
                Logger.Debug(GetType(), "updating sizes for panelType={0} id={1} to ({2}; {3})", GetType().FullName, _container.Id, sizes.Item1, sizes.Item2);

                _container.AddClasses(Magics.CssClassActive);
                ev.PreventDefault();
                Sizes = sizes;
                SetPanelsSize(sizes);
            };

            DocumentUtil.AddMouseDownListener(_splitter, x => {
                if (!x.HasHtmlTarget())
                {
                    return;
                }

                var htmlTarget = x.HtmlTarget();

                if (!htmlTarget.IsElementOrItsDescendant(_splitter))
                {
                    return;
                }

                _isDragging = true;
                x.PreventDefault();
            });

            DocumentUtil.AddMouseUpListener(_splitter, x => {
                _isDragging = false;
            });

            DocumentUtil.AddMouseMoveListener(_splitter, ev => {
                if (!_isDragging)
                {
                    return;
                }
                ev.PreventDefault();

                var sizes = CalculateSizesOnUserResize(ev.PageX, ev.PageY);

                if (sizes.Item1 < minPanelSizePx || sizes.Item2 < minPanelSizePx)
                {
                    return;
                }
                Logger.Debug(GetType(), "updating sizes for panelType={0} id={1} to ({2}; {3})", GetType().FullName, _container.Id, sizes.Item1, sizes.Item2);

                _container.AddClasses(Magics.CssClassActive);

                Sizes = sizes;
                SetPanelsSize(sizes);
            });

            DocumentUtil.AddElementAttachedToDocumentListener(_container, InitializeWidthsOnAttachOrResize);
            DocumentUtil.AddElementResizeListener(_container, InitializeWidthsOnAttachOrResize);
        }
        public HorizontalMenuBarView(
            Func <MenuItemModel, Tuple <HTMLElement, Action <string> > > customItemBuilder = null)
        {
            _itemBuilder = customItemBuilder ?? (x => {
                var el = new HTMLAnchorElement {
                    Href = "#"
                };
                return(Tuple.Create <HTMLElement, Action <string> >(el, y => el.TextContent = y));
            });

            _nav    = DocumentUtil.CreateElementHavingClassName("nav", GetType().FullNameWithoutGenerics());
            _nav.Id = UniqueIdGenerator.GenerateAsString();

            _root = new HTMLElement("ul")
            {
                Id = UniqueIdGenerator.GenerateAsString()
            };
            _nav.AppendChild(_root);

            _onItemClicked = ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                ev.PreventDefault();

                var htmlTarget = ev.HtmlTarget();
                var menuItemId = htmlTarget.GetAttribute(Magics.AttrDataMenuItemId);
                Logger.Debug(GetType(), "user activated menuItemId {0} in view", menuItemId);
                ActivateAllBut(_root, new List <HTMLElement>());
                ItemActivated?.Invoke(Convert.ToInt32(menuItemId));
            };
            _onMouseOver = ev => {
                if (!ev.HasHtmlCurrentTarget())
                {
                    return;
                }

                var hoverOn = ev.HtmlCurrentTarget();
                var active  = new List <HTMLElement> {
                    hoverOn
                };

                var parent = hoverOn.ParentElement;
                while (parent != _root)
                {
                    active.Add(parent);
                    parent = parent.ParentElement;
                }

                ActivateAllBut(_root, active);
                hoverOn.Focus();
            };

            Document.Body.AddEventListener("click", ev => {
                //find out if clicked item is a descendant of menu - if not fold whole menu

                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                if (ev.HtmlTarget().IsDescendantOf(_nav))
                {
                    return;
                }

                ActivateAllBut(_root, new List <HTMLElement>());
            });
        }
Exemple #13
0
 public static void AddResizeEventListener(this Element self, Action action)
 {
     DocumentUtil.AddElementResizeListener(self, action);
 }
Exemple #14
0
 public static void AddAttachedToDocumentEventListener(this Element self, Action action)
 {
     DocumentUtil.AddElementAttachedToDocumentListener(self, action);
 }