public UploaderDemoForm(IHttpRequester httpRequester) { _view = new UploaderDemoFormView(); _view.Attachments.SetImplementation(new ISomeService_OrderAttachment(httpRequester, () => 124, () => true)); _attachments = LocalValueFieldBuilder.Build(new List <RemoteFileDescr>(), _view.Attachments, (newValue, errors) => { errors.IfTrueAdd(newValue.Count > 10, "Maximum 10 files allowed"); }); //TODO this is experimental feature. It should be added by the above statement (if BeforeChange is supported in IView) _view.Attachments.BeforeChange += (newValue, isUser, preventProp) => { if (newValue.Count > 10) { preventProp(new HashSet <string> { "Maximum 10 files allowed" }); } }; var mayConfirm = new AggregatedErrorsValue <bool>( false, self => !self.Errors.Any(), x => x.Observes(_attachments)); var confirm = LocalActionBuilder.Build(_view.Confirm, () => Ended?.Invoke(this, Unit.Instance)); confirm.BindEnableAndInitialize(mayConfirm); }
public QrScannerForm( QrScannerFormView view, string title, string label, Func <string, Task <T> > getItemByCode, int scannerPopupMmFromTop = 15, int scannerPopupHeightMm = 40) { _view = view; _view.Label = label; _view.PadMmFromTop = scannerPopupMmFromTop; _scannerPopupMmFromTop = scannerPopupMmFromTop; _view.HeightMm = scannerPopupHeightMm; _scannerPopupHeightMm = scannerPopupHeightMm; _title = title; _getItemByCode = getItemByCode; LocalActionBuilder.Build(_view.Unpause, async() => { _view.Unpause.Widget.Style.Display = Display.None; await _errorLbl.DoChange("", false, this, false); _hndl?.ResumeScanning(); }); LocalActionBuilder.Build(_view.Cancel, () => _hndl?.CancelScanning()); _errorLbl = LocalValueFieldBuilder.Build(_view.Error); }
public LocalValue AddLocalName(string name) { LocalValue val = new LocalValue(); this.cur_block.values[name] = val; return(val); }
public void Setup() { m_IsCloseBGSound = LocalValue.GetValue <int>(SoundID.LOCAL_BG_SOUND_CLOSE, 0) == 1 ? true : false; m_IsCloseEffectSound = LocalValue.GetValue <int>(SoundID.LOCAL_EFFECT_SOUND_CLOSE, 0) == 1 ? true : false; m_BGSoundVolume = LocalValue.GetValue <float>(SoundID.LOCAL_BGSOUND_VOLUME, 1); m_EffectSoundVolume = LocalValue.GetValue <float>(SoundID.LOCAL_EFFECT_SOUND_VOLUME, 1); RegisterEvent(); }
public static LocalValue <DataT> Build <WidgetT, DataT>( IReadOnlyValueView <WidgetT, DataT> view, params Validate <DataT>[] validators) { var result = new LocalValue <DataT>(default(DataT)); view.BindReadOnlyAndInitialize(result, x => x); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <T> Build <WidgetT, T>( IReadWriteValueView <WidgetT, T> view, params Validate <T>[] validators) { var result = new LocalValue <T>(default(T), default(T)); view.BindReadWriteAndInitialize(result); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public void Unsubscribe(EventHandler <EventArgType> subscriber) { if (GlobalVariable != null) { GlobalVariable.Unsubscribe(subscriber); } LocalValue.Unsubscribe(subscriber); }
public static LocalValue <int> BuildInt <WidgetT>( IReadOnlyValueView <WidgetT, string> view, params Validate <int>[] validators) { var result = new LocalValue <int>(0); view.BindReadOnlyAndInitialize(result, x => I18n.Localize(x)); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <ModelT> Build <WidgetT, ModelT, ViewT>( IReadOnlyValueView <WidgetT, ViewT> view, Func <ModelT, ViewT> convertFromDomain, params Validate <ModelT>[] validators) { var result = new LocalValue <ModelT>(default(ModelT)); view.BindReadOnlyAndInitialize(result, convertFromDomain); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <DateTime?> BuildDateTimePicker( DateTimePickerView view, DateTime?defaultValue = null, params Validate <DateTime?>[] validators) { var result = new LocalValue <DateTime?>(defaultValue); view.BindReadWriteAndInitialize(result); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <decimal> BuildDecimal <WidgetT>( IReadOnlyValueView <WidgetT, string> view, DecimalFormat format, params Validate <decimal>[] validators) { var result = new LocalValue <decimal>(0); view.BindReadOnlyAndInitialize(result, x => I18n.Localize(x, format)); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public InformationalMessageForm(InformationalMessageFormView view, string messageOrNull = null, string titleOrNull = null, bool cancellable = true) { _cancellable = cancellable; Title = titleOrNull ?? I18n.Translate("Confirmation"); View = view; _message = new LocalValue <string>(messageOrNull ?? I18n.Translate("Without message")); view.Message.BindReadOnlyAndInitialize(_message); LocalActionBuilder.Build(view.Confirm, () => Ended?.Invoke(this, Unit.Instance)); }
public static LocalValue <decimal> BuildDecimalWithPrecision <WidgetT>( IReadOnlyValueView <WidgetT, string> view, decimal defaultValue, Func <int> getPrecision, params Validate <decimal>[] validators) { var result = new LocalValue <decimal>(defaultValue); view.BindReadOnlyAndInitialize(result, x => I18n.Localize(x, DecimalFormatExtensions.GetWithPrecision(getPrecision()))); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <int?> BuildNullableInt <WidgetT>( int?defaultValue, IReadWriteValueView <WidgetT, string> view, params Validate <int?>[] validators) { var result = new LocalValue <int?>(defaultValue); view.BindReadWriteAndInitialize(result, x => !x.HasValue ? "" : I18n.Localize(x.Value), x => string.IsNullOrEmpty(x) ? (int?)null : I18n.ParseInt(x)); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public EnumChoiceForm( string title, bool isCancelable, T defaultValue, Func <T, string> getLabel, Action <EnumChoiceFormView <T> > postInitialization = null) { Title = title; _isCancelable = isCancelable; _view = new EnumChoiceFormView <T>(defaultValue, getLabel, postInitialization); _chosen = LocalValueFieldBuilder.BuildEnumBasedChoice(defaultValue, _view.Choice); LocalActionBuilder.Build(_view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed)); }
public static LocalValue <decimal> BuildDecimal( InputView view, DecimalFormat format, params Validate <decimal>[] validators) { view.RaisesChangedOnKeyPressed = false; var result = new LocalValue <decimal>(0); view.BindReadWriteAndInitialize(result, x => I18n.Localize(x, format), x => I18n.ParseDecimal(x)); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <decimal?> BuildNullableDecimal( InputView view, DecimalFormat format, params Validate <decimal?>[] validators) { view.RaisesChangedOnKeyPressed = false; var result = new LocalValue <decimal?>(null); view.BindReadWriteAndInitialize(result, x => !x.HasValue ? "" : I18n.Localize(x.Value, format), x => string.IsNullOrEmpty(x) ? (decimal?)null : I18n.ParseDecimal(x)); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public FlexibleLayoutContentForm() { _view = new FlexibleLayoutContentFormView(); _layoutMode = LocalValueFieldBuilder.BuildEnumBasedChoice( LayoutModeType.TitleExtra_Actions_Body, _view.LeftPanelLayout); _layoutMode.Changed += (sender, oldValue, newValue, errors, isUserChange) => { if (!isUserChange) { return; } Ended?.Invoke(this, Outcome.LeftPanelLayoutChanged); }; }
public static LocalValue <decimal> BuildDecimalWithPrecision( InputView view, decimal defaultValue, Func <int> getPrecision, params Validate <decimal>[] validators) { var result = new LocalValue <decimal>(defaultValue); view.RaisesChangedOnKeyPressed = false; view.BindReadWriteAndInitialize(result, x => I18n.Localize(x, DecimalFormatExtensions.GetWithPrecision(getPrecision())), x => I18n.ParseDecimalWithoutLoss(x, getPrecision())); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public TextInputForm( TextInputFormView view, string label, string titleOrNull = null, string defaultValue = null, params Validate <string>[] validators) { Title = titleOrNull ?? I18n.Translate("Input"); _view = view; _msg = new LocalValue <string>(label ?? ""); view.Label.BindReadOnlyAndInitialize(_msg); _input = LocalValueFieldBuilder.Build(defaultValue, view.Input, validators); var isFormValid = new AggregatedErrorsValue <bool>(false, x => !x.Errors.Any(), x => x.Observes(_input)); var confirmInput = LocalActionBuilder.Build(view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed)); confirmInput.BindEnableAndInitialize(isFormValid); }
public SingleRadioBasedChoiceForm( string title, bool isCancelable, T defaultValue, Func <T, string> getLabel, Func <int, T> intToItem, Func <T, int> itemToInt, Action <SingleRadioBasedChoiceFormView <T> > postInitialization = null) { Title = title; _isCancelable = isCancelable; _getLabel = getLabel; _itemToInt = itemToInt; _view = new SingleRadioBasedChoiceFormView <T>( defaultValue, getLabel, intToItem, itemToInt, postInitialization); _chosen = LocalValueFieldBuilder.BuildGeneralChoice( defaultValue, intToItem, itemToInt, _view.Choice); LocalActionBuilder.Build(_view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed)); }
public static LocalValue <int> BuildInt <WidgetT>( int defaultvalue, IReadWriteValueView <WidgetT, string> view, params Validate <int>[] validators) { var result = new LocalValue <int>(defaultvalue); view.BindReadWriteAndInitialize(result, x => I18n.Localize(x), x => { try { var val = I18n.ParseInt(x); return(val); } catch (Exception ex) { Logger.Error(typeof(LocalValueFieldBuilder), "BuildInt converter got exception {0}", ex); throw new Exception( I18n.Translate("Wrong integer format entered. Remove letters or special characters")); } }); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public static LocalValue <decimal?> BuildNullableDecimalWithPrecision( InputView view, Func <int> getPrecision, params Validate <decimal?>[] validators) { view.RaisesChangedOnKeyPressed = false; var result = new LocalValue <decimal?>(null); view.BindReadWriteAndInitialize(result, x => !x.HasValue ? "" : I18n.Localize(x.Value, DecimalFormatExtensions.GetWithPrecision(getPrecision())), x => string.IsNullOrEmpty(x) ? (decimal?)null : I18n.ParseDecimalWithoutLoss(x, getPrecision())); validators.ForEach(y => result.AddValidatorAndRevalidate(y)); return(result); }
public LoginForm(LoginFormView view, Func <string, string, Task <Tuple <string, UserT> > > service, Action <string, UserT> storeResult) { View = view; var login = new LocalValue <string>("", ""); login.AddValidatorAndRevalidate( (x, errors) => errors.IfTrueAdd(string.IsNullOrWhiteSpace(x), I18n.Translate("Field cannot be empty")) ); view.Login.BindReadWriteAndInitialize(login); var passwd = new LocalValue <string>("", ""); passwd.AddValidatorAndRevalidate( (x, errors) => errors.IfTrueAdd(string.IsNullOrWhiteSpace(x), I18n.Translate("Field cannot be empty")) ); view.Password.BindReadWriteAndInitialize(passwd); var mayAttemptLogin = new AggregatedErrorsValue <bool>(false, self => !self.Errors.Any(), x => { x.Observes(login); x.Observes(passwd); }); var attemptLogin = RemoteActionBuilder.Build(view.AttemptLogin, () => service(login.Value, passwd.Value), x => { storeResult(x.Item1, x.Item2); LoggedUserName = login.Value; ErrorMessageOrNull = null; Ended?.Invoke(this, CompletedOrCanceled.Completed); }, x => { LoggedUserName = null; ErrorMessageOrNull = x.ErrorMessage; Ended?.Invoke(this, CompletedOrCanceled.Canceled); }); attemptLogin.BindEnableAndInitialize(mayAttemptLogin); }
public IntroduceItemForm() { _view = new IntroduceItemFormView(); _someText = LocalValueFieldBuilder.Build(_view.SomeText, Validator.IsNotEmptyOrWhitespaceOnly); _someNumber = LocalValueFieldBuilder.BuildInt(_view.SomeNumber, Validator.MustBePositive); _someBool = LocalValueFieldBuilder.Build(_view.SomeBool); _view.SomeTrait.PermittedValues = EnumExtensions.GetEnumValues <SomeTraitType>().Select(x => (SomeTraitType?)x); _someTrait = LocalValueFieldBuilder.Build(_view.SomeTrait, Validator.IsNotNull); var isFormValid = new AggregatedErrorsValue <bool>(false, self => !self.Errors.Any(), x => { x.Observes(_someText); x.Observes(_someNumber); x.Observes(_someBool); x.Observes(_someTrait); }); LocalActionBuilder .Build(_view.Create, () => Ended?.Invoke(this, Outcome.Saved)) .With(x => x.BindEnableAndInitialize(isFormValid)); }
public RemoteValueChangeByChoiceForm( Func <string> titleProv, Func <T, Task <T> > saveChange, RemoteValueChangeByChoiceFormView <T> view, params Validate <T>[] validators) { _titleProv = titleProv; _view = view; _localValue = LocalValueFieldBuilder.Build(default(T), view.Choosen, validators); var remoteActionModel = RemoteActionBuilder.Build(view.Confirm, () => saveChange(_localValue.Value), x => { SavedValue = x; Ended?.Invoke(this, CompletedOrCanceled.Completed); }); var isFormValid = new AggregatedErrorsValue <bool>(false, self => !self.Errors.Any(), x => { x.Observes(_localValue); }); remoteActionModel.BindEnableAndInitialize(isFormValid); }
public RemoteValueChangeByEntryForm( Func <DomainT, Task <RemoteT> > remoteChanger, IReadWriteValueView <HTMLElement, ViewT> input, Action <string> inputLabelChanger, Func <DomainT, ViewT> domainToViewConverter, Func <ViewT, DomainT> viewToDomainConverter, string label, string titleOrNull = null, DomainT defaultValue = default(DomainT), TextType labelTextType = TextType.TreatAsText, params Validate <DomainT>[] validators) { _inputLabelChanger = inputLabelChanger; Title = titleOrNull ?? I18n.Translate("Input"); _view = new RemoteValueChangeByEntryFormView <ViewT>(input, labelTextType); _inputLabelChanger(label); _msg = new LocalValue <string>(""); _view.Message.BindReadOnlyAndInitialize(_msg); _input = LocalValueFieldBuilder.Build( defaultValue, _view.Input, domainToViewConverter, viewToDomainConverter, validators); var isFormValid = new AggregatedErrorsValue <bool>( false, x => !x.Errors.Any(), x => x.Observes(_input)); var confirmInput = RemoteActionBuilder.Build( _view.Confirm, () => remoteChanger(_input.Value), x => { SavedValue = x; Ended?.Invoke(this, CompletedOrCanceled.Completed); }); confirmInput.BindEnableAndInitialize(isFormValid); }
// Would like to use <inheritdoc/> however DocFX cannot resolve to references outside Material.Blazor protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); if (ValueMax <= ValueMin) { throw new ArgumentException($"{GetType()} must have ValueMax ({ValueMax}) greater than ValueMin ({ValueMin})"); } if (Value < ValueMin || Value > ValueMax) { throw new ArgumentException($"{GetType()} must have Value ({Value}) between ValueMin ({ValueMin}) and ValueMax ({ValueMax})"); } // Reinstate these 4 lines once https://github.com/material-components/material-components-web/issues/7404 is fixed //Value = Math.Round(Value, (int)DecimalPlaces); //ValueMin = Math.Round(ValueMin, (int)DecimalPlaces); //ValueMax = Math.Round(ValueMax, (int)DecimalPlaces); //Format = $"F{DecimalPlaces}"; // Delete once https://github.com/material-components/material-components-web/issues/7404 is fixed if (SliderType == MBSliderType.Continuous) { Mult = Convert.ToDecimal(Math.Pow(10, DecimalPlaces)); } else { Mult = NumSteps / (ValueMax - ValueMin); } LocalValue = Math.Round(Value * Mult, (int)DecimalPlaces); LocalValueMin = Math.Round(ValueMin * Mult, (int)DecimalPlaces); LocalValueMax = Math.Round(ValueMax * Mult, (int)DecimalPlaces); Format = $"F0"; ValueStepIncrement = 1; // End delete TabIndex = AppliedDisabled ? -1 : 0; RangePercentDecimal = (Value - ValueMin) / (ValueMax - ValueMin); // Reinstate once https://github.com/material-components/material-components-web/issues/7404 is fixed //if (SliderType == MBSliderType.Continuous) //{ // ValueStepIncrement = Convert.ToDecimal(Math.Pow(10, -DecimalPlaces)); //} //else //{ // ValueStepIncrement = (ValueMax - ValueMin) / NumSteps; //} ConditionalCssClasses .AddIf("mdc-slider--discrete", () => SliderType != MBSliderType.Continuous) .AddIf("mdc-slider--tick-marks", () => SliderType == MBSliderType.DiscreteWithTickmarks) .AddIf("mdc-slider--disabled", () => AppliedDisabled); InputMarkup = new($"<input class=\"mdc-slider__input\" type=\"range\" value=\"{LocalValue.ToString(Format)}\" step=\"{ValueStepIncrement}\" min=\"{LocalValueMin.ToString(Format)}\" max=\"{LocalValueMax.ToString(Format)}\" name=\"volume\" aria-label=\"{AriaLabel}\">"); SetComponentValue += OnValueSetCallback; OnDisabledSet += OnDisabledSetCallback; ObjectReference = DotNetObjectReference.Create(this); }
//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 })); }
/// <summary> /// Creates a new RuntimeScope instance. /// </summary> /// <param name="engine"> The script engine this scope is associated with. </param> /// <param name="parent"> The parent scope, or <c>null</c> if this is the root scope. </param> /// <param name="scopeType"></param> /// <param name="varNames"></param> /// <param name="letNames"></param> /// <param name="constNames"></param> internal RuntimeScope(ScriptEngine engine, RuntimeScope parent, ScopeType scopeType, string[] varNames, string[] letNames, string[] constNames) { this.Engine = engine ?? throw new ArgumentNullException(nameof(engine)); this.Parent = parent; this.ScopeType = scopeType; if (varNames != null && scopeType != ScopeType.TopLevelFunction && scopeType != ScopeType.EvalStrict) { var scope = this; while (scope != null && scope.ScopeObject == null && scope.ScopeType != ScopeType.TopLevelFunction && scopeType != ScopeType.EvalStrict) { scope = scope.Parent; } if (scope != null) { if (scope.ScopeType == ScopeType.TopLevelFunction || scopeType == ScopeType.EvalStrict) { foreach (var name in varNames) { if (!scope.values.ContainsKey(name)) { scope.values[name] = new LocalValue { Value = Undefined.Value, Flags = LocalFlags.Deletable } } } ; } else { var attributes = scopeType == ScopeType.Eval ? PropertyAttributes.FullAccess : PropertyAttributes.Enumerable | PropertyAttributes.Writable; foreach (var name in varNames) { scope.ScopeObject.InitializeMissingProperty(name, attributes); } } } varNames = null; } if (varNames != null || letNames != null || constNames != null) { values = new Dictionary <string, LocalValue>( (varNames != null ? varNames.Length : 0) + (letNames != null ? letNames.Length : 0) + (constNames != null ? constNames.Length : 0)); } if (varNames != null) { foreach (string variableName in varNames) { values[variableName] = new LocalValue { Value = Undefined.Value } } ; } if (letNames != null) { foreach (string variableName in letNames) { values[variableName] = new LocalValue(); } } if (constNames != null) { foreach (string variableName in constNames) { values[variableName] = new LocalValue { Flags = LocalFlags.ReadOnly } } ; } }