/// <summary> returns tooltipcontainer and tooltip</summary> private Tuple <HTMLElement, HTMLElement> GetOrCreateTooltipOn(HTMLElement tooltipOn, string content, TooltipMode mode) { if (_tooltips.ContainsKey(tooltipOn)) { var oldTt = _tooltips.Get(tooltipOn).Item1; oldTt.TextContent = content; return(Tuple.Create(oldTt.ParentElement, oldTt)); } //tooltips need to be in container so that relative positioning works in both: //inline scenario: <label><input><tooltip> and in //'display:table' scenario those three have "display: table-cell" var ttCont = Document.CreateElement("span"); ttCont.ClassName = Magics.CssClassTooltipContainer; var tt = Document.CreateElement("span"); tt.Id = UniqueIdGenerator.GenerateAsString(); tt.TextContent = content; tt.ClassName = Magics.CssClassTooltip; tt.ClassList.Add(Magics.CssClassDisabled); ttCont.AppendChild(tt); Logger.Debug(GetType(), "created tooltip to show it {0}", tt.Id); _tooltips[tooltipOn] = Tuple.Create(tt, mode); return(Tuple.Create(ttCont, tt)); }
public static Task <string> RegisterMediaAsset(string fileContent) { var requestId = UniqueIdGenerator.GenerateAsString(); var impl = GetImpl(); if (impl == null) { Logger.Debug(typeof(IawAppApi), "has no proper IAWApp API"); return(Task.FromResult(fileContent.Length.ToString())); } //androidPostMediaAssetReady(webRequestIdUriEncoded : string, properMediaFileId : string) : void; return(Task.FromPromise <string>( new TypeSafePromise <string>((onSucc, onFail) => { IAWAppHostApi.RegisterPostMediaAssetReady(requestId, x => onSucc(x)); try { impl.registerMediaAsset(requestId, fileContent); } catch (Exception ex) { Logger.Error(typeof(IawAppApi), "registerMediaAsset got exception {0}", ex); IAWAppHostApi.UnregisterPostMediaAssetReady(requestId); onFail(ex); } }), (Func <string, string>)(x => x))); }
public RadioBasedSingleChoice(string labelOrNull = null, RadioBasedSingleChoiceItemAdder customItemAdder = null) { BeforeAddItems = (element, i) => null; ItemAdder = customItemAdder ?? ((ctx, cntnr, rawItem, itemElem, lblElem, itemNo) => { cntnr.AppendChild(itemElem); cntnr.AppendChild(lblElem); }); _uniqueNumberAsName = UniqueIdGenerator.GenerateAsString(); _container = new HTMLDivElement(); _container.ClassName = GetType().FullNameWithoutGenerics(); if (labelOrNull != null) { _genericLabelOrNull = new HTMLLabelElement { TextContent = labelOrNull }; _container.AppendChild(_genericLabelOrNull); } _logic = new ControlWithValueLogic <Tuple <string, string> >( (newVal, isUser) => Changed?.Invoke(newVal, isUser), () => { var active = _valueToItem.Values.FirstOrDefault(x => x.Checked); return(active == null ? Tuple.Create("", "") : Tuple.Create(active.Value, _valueToLabel[active.Value])); }, v => { var emptying = v == null || string.IsNullOrEmpty(v.Item1); Logger.Debug(GetType(), "setPhysicalValue emptying?={0} value=({1};{2})", emptying, v?.Item1, v?.Item2); if (emptying) { foreach (var x in _valueToItem.Values) { if (x.Checked) { x.Checked = false; break; } } return; } _valueToItem[v.Item1].Checked = true; }, () => _valueToItem.Any() && !_valueToItem.First().Value.Disabled, v => _valueToItem.Values.ForEach(x => _valueToItem.First().Value.Disabled = !v), () => _container.ClassList.Contains(Magics.CssClassIsValidating), v => _container.AddOrRemoveClass(v, Magics.CssClassIsValidating) ); _logic.ValueToString = x => x == null ? "<Tuple null>" : $"<Tuple fst={x.Item1} snd={x.Item2}>"; }
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); }
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); } }
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>()); }); }