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(); }); }
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; }
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>()); }); }
public static void AddResizeEventListener(this Element self, Action action) { DocumentUtil.AddElementResizeListener(self, action); }
public static void AddAttachedToDocumentEventListener(this Element self, Action action) { DocumentUtil.AddElementAttachedToDocumentListener(self, action); }