Ejemplo n.º 1
0
        private LayoutChoice_Set newTextBlock(string prefix, string indexString, string text, int indent)
        {
            Horizontal_GridLayout_Builder builder = new Horizontal_GridLayout_Builder();

            if (prefix.Length > 0)
            {
                TextblockLayout prefixBlock = new TextblockLayout(prefix, this.maxFontSize, false, false);
                prefixBlock.setTextColor(Color.FromRgba(0, 0, 0, 0));
                builder.AddLayout(prefixBlock);
            }

            double fontSize = this.maxFontSize;

            for (int i = 0; i < indent; i++)
            {
                fontSize = Math.Ceiling(fontSize * 4 / 5);
            }
            TextblockLayout indexLayout = new TextblockLayout(indexString, fontSize);

            indexLayout.AlignVertically(TextAlignment.Start);
            builder.AddLayout(indexLayout);

            TextblockLayout contentBlock = new TextblockLayout(text, fontSize);

            contentBlock.AlignVertically(TextAlignment.Start);
            builder.AddLayout(contentBlock);

            return(builder.BuildAnyLayout());
        }
        private LayoutChoice_Set makeControls()
        {
            Button openParenButton = new Button();

            openParenButton.Clicked += OpenParenButton_Clicked;
            Button closeParenButton = new Button();

            closeParenButton.Clicked += CloseParenButton_Clicked;

            LayoutChoice_Set parensLayout = new Horizontal_GridLayout_Builder().Uniform()
                                            .AddLayout(new ButtonLayout(openParenButton, "("))
                                            .AddLayout(new ButtonLayout(closeParenButton, ")")).BuildAnyLayout();

            Button textButton = new Button();

            textButton.Clicked += TextButton_Clicked;
            this.newWord_box    = new Editor();

            LayoutChoice_Set wordLayout = new Horizontal_GridLayout_Builder().Uniform()
                                          .AddLayout(new ButtonLayout(textButton, "Contains Phrase"))
                                          .AddLayout(new TextboxLayout(this.newWord_box)).BuildAnyLayout();

            Button notButton = new Button();

            notButton.Clicked += NotButton_Clicked;
            Button andButton = new Button();

            andButton.Clicked += AndButton_Clicked;
            Button orButton = new Button();

            orButton.Clicked += OrButton_Clicked;

            LayoutChoice_Set joinsLayout = new Horizontal_GridLayout_Builder().Uniform()
                                           .AddLayout(new ButtonLayout(andButton, ") And"))
                                           .AddLayout(new ButtonLayout(orButton, ") Or"))
                                           .AddLayout(new ButtonLayout(notButton, "Not (")).BuildAnyLayout();

            this.scoreBox                 = new Editor();
            this.scoreBox.TextColor       = Color.White;
            this.scoreBox.BackgroundColor = Color.Black;
            TextboxLayout scoreBoxLayout = new TextboxLayout(this.scoreBox);

            scoreBoxLayout.SetBackgroundColor(Color.White);
            LayoutChoice_Set scoreLayout = new Horizontal_GridLayout_Builder().Uniform()
                                           .AddLayout(new TextblockLayout("Score:"))
                                           .AddLayout(scoreBoxLayout).BuildAnyLayout();

            return(new Vertical_GridLayout_Builder().Uniform()
                   .AddLayout(parensLayout).AddLayout(wordLayout).AddLayout(joinsLayout).AddLayout(scoreLayout)
                   .BuildAnyLayout());
        }
Ejemplo n.º 3
0
        private LayoutChoice_Set make_otherActivities_layout(double fontSize)
        {
            Button createNewActivity_button = new Button();

            createNewActivity_button.Clicked += CreateNewActivity_button_Clicked;
            Button brainstormNewActivities_button = new Button();

            brainstormNewActivities_button.Clicked += BrainstormNewActivities_button_Clicked;

            GridLayout_Builder builder = new Horizontal_GridLayout_Builder().Uniform();

            builder.AddLayout(new ButtonLayout(brainstormNewActivities_button, "Brainstorm", fontSize));
            builder.AddLayout(new ButtonLayout(createNewActivity_button, "New activity", fontSize));

            return(builder.BuildAnyLayout());
        }
Ejemplo n.º 4
0
        public RequestSuggestion_Layout(ActivityDatabase activityDatabase, bool allowRequestingActivitiesDirectly, bool allowMultipleSuggestionTypes, bool vertical,
                                        int numChoicesPerSuggestion, Engine engine, LayoutStack layoutStack)
        {
            this.activityDatabase = activityDatabase;
            this.allowRequestingActivitiesDirectly = allowRequestingActivitiesDirectly;
            this.allowMultipleSuggestionTypes      = allowMultipleSuggestionTypes;
            this.vertical                = vertical;
            this.engine                  = engine;
            this.layoutStack             = layoutStack;
            this.numChoicesPerSuggestion = numChoicesPerSuggestion;

            GridLayout_Builder gridBuilder;

            if (vertical)
            {
                gridBuilder = new Vertical_GridLayout_Builder();
            }
            else
            {
                gridBuilder = new Horizontal_GridLayout_Builder();
            }
            gridBuilder.Uniform();

            Full_RequestSuggestion_Layout child = new Full_RequestSuggestion_Layout(this.activityDatabase, false, false, this.vertical, numChoicesPerSuggestion, this.engine, this.layoutStack);

            this.impl = child;
            child.RequestSuggestion += Child_RequestSuggestion;
            gridBuilder.AddLayout(this.impl);

            bool expandable = allowRequestingActivitiesDirectly || allowMultipleSuggestionTypes;

            if (expandable)
            {
                Button expandButton = new Button();
                expandButton.Clicked += ExpandButton_Clicked;
                gridBuilder.AddLayout(new ButtonLayout(expandButton, "Customize"));
            }

            this.SubLayout = gridBuilder.BuildAnyLayout();
        }
        public RelativeRatingEntryView() : base("")
        {
            this.TitleLayout.AlignVertically(TextAlignment.Center);
            this.mainDisplayGrid = GridLayout.New(new BoundProperty_List(2), new BoundProperty_List(1), LayoutScore.Zero);

            this.scaleBox              = new Editor();
            this.scaleBox.Keyboard     = Keyboard.Numeric;
            this.scaleBox.TextChanged += this.ScaleBlock_TextChanged;
            this.scaleBoxLayout        = new TextboxLayout(this.scaleBox);
            ContainerLayout scaleBoxHolder = new ContainerLayout(null, this.scaleBoxLayout, false);
            // The fact that the rating is relative to the previous participation is really important, so we put this text into its own text block.
            // Additionally, the timesBlock might be able to fit into the same line as the text box into which the user types the rating ratio.
            // Also, if there's enough space then we spell out the exact meaning more clearly
            LayoutChoice_Set conciseTimesBlock = new ScoreShifted_Layout(new TextblockLayout("x prev:").AlignVertically(TextAlignment.Center).AlignHorizontally(TextAlignment.Center), LayoutScore.Get_ReducedContent_Score(1));
            LayoutChoice_Set fullTimesBlock    = new TextblockLayout("times previous:").AlignVertically(TextAlignment.Center).AlignHorizontally(TextAlignment.Center);
            LayoutChoice_Set timesBlock        = new LayoutUnion(fullTimesBlock, conciseTimesBlock);

            LayoutChoice_Set horizontalBox = new Horizontal_GridLayout_Builder()
                                             .AddLayout(scaleBoxHolder)
                                             .AddLayout(timesBlock)
                                             .BuildAnyLayout();

            LayoutChoice_Set verticalBox = new Vertical_GridLayout_Builder()
                                           .AddLayout(scaleBoxHolder)
                                           .AddLayout(timesBlock)
                                           .BuildAnyLayout();

            this.Clear();
            this.mainDisplayGrid.AddLayout(new LayoutUnion(horizontalBox, verticalBox));

            // We try to use large font for the name layout and we also try to use as many clarifying words as possible
            this.fullNameLayout = new TextblockLayout();
            this.mainDisplayGrid.AddLayout(
                this.fullNameLayout
                );

            this.Placeholder("(Optional)");
        }
Ejemplo n.º 6
0
        private LayoutChoice_Set makeBackButtons(List <StackEntry> layouts)
        {
            List <StackEntry> prevLayouts = layouts.GetRange(0, layouts.Count - 1);

            int maxPriority = -1000;

            foreach (StackEntry entry in prevLayouts)
            {
                maxPriority = Math.Max(maxPriority, entry.BackPriority);
            }
            List <StackEntry> interestingPrevLayouts = new List <StackEntry>();

            foreach (StackEntry entry in prevLayouts)
            {
                if (entry.BackPriority == maxPriority)
                {
                    interestingPrevLayouts.Add(entry);
                }
            }

            Horizontal_GridLayout_Builder fullBuilder = new Horizontal_GridLayout_Builder().Uniform();

            foreach (StackEntry entry in interestingPrevLayouts)
            {
                fullBuilder.AddLayout(this.JumpBack_ButtonLayout(entry));
            }
            if (interestingPrevLayouts.Count <= 2)
            {
                // If there are 2 or fewer previous layouts, then we show all of them
                return(fullBuilder.BuildAnyLayout());
            }
            Horizontal_GridLayout_Builder abbreviatedBuilder = new Horizontal_GridLayout_Builder().Uniform();

            abbreviatedBuilder.AddLayout(this.JumpBack_ButtonLayout(interestingPrevLayouts[interestingPrevLayouts.Count - 2]));
            abbreviatedBuilder.AddLayout(this.JumpBack_ButtonLayout(interestingPrevLayouts[interestingPrevLayouts.Count - 1]));
            return(new LayoutUnion(abbreviatedBuilder.BuildAnyLayout(), fullBuilder.BuildAnyLayout()));
        }
        public Import_SpecificActivities_Layout(Inheritance inheritance, int numDescendants)
        {
            this.inheritance = inheritance;

            TextblockLayout title = new TextblockLayout(inheritance.ChildDescriptor.ActivityName + " (" + inheritance.ParentDescriptor.ActivityName + ")", 30);

            title.AlignVertically(TextAlignment.Center);

            Button selectAll_button = new Button();

            selectAll_button.Clicked += SelectAll_button_Clicked;
            Button customizeButton = new Button();

            customizeButton.Clicked += CustomizeButton_Clicked;
            Button dismissButton = new Button();

            dismissButton.Clicked += DismissButton_Clicked;
            GridLayout_Builder buttonsBuilder = new Horizontal_GridLayout_Builder().Uniform();

            if (numDescendants > 1)
            {
                buttonsBuilder.AddLayout(new ButtonLayout(selectAll_button, "I like all kinds! (" + numDescendants + " ideas)", 16));
                buttonsBuilder.AddLayout(new ButtonLayout(customizeButton, "I like this. Show me more!", 16));
            }
            else
            {
                buttonsBuilder.AddLayout(new ButtonLayout(customizeButton, "I like this!", 16));
            }

            buttonsBuilder.AddLayout(new ButtonLayout(dismissButton, "Not interested", 16));

            this.SubLayout = new Vertical_GridLayout_Builder()
                             .AddLayout(title)
                             .AddLayout(buttonsBuilder.Build())
                             .Build();
        }
        public ExperimentInitializationLayout(LayoutStack layoutStack, ActivityRecommender activityRecommender, ActivityDatabase activityDatabase, ProtoActivity_Database protoActivity_database, Engine engine, int numActivitiesThatMayBeRequestedDirectly)
        {
            this.SetTitle("Efficiency Experiment");
            this.activityRecommender = activityRecommender;

            Button okbutton = new Button();

            this.okButtonLayout = new ButtonLayout(okbutton, "Next");
            okbutton.Clicked   += Okbutton_Clicked;

            LayoutChoice_Set helpButton = this.make_helpButton(layoutStack);

            SuggestedMetric_Metadata experimentsStatus = activityRecommender.Test_ChooseExperimentOption();

            if (experimentsStatus.Error != "")
            {
                this.SetContent(new TextblockLayout(experimentsStatus.Error));
                return;
            }

            this.statusHolder = new ContainerLayout();
            GridLayout topGrid = new Horizontal_GridLayout_Builder()
                                 .AddLayout(helpButton)
                                 .AddLayout(new HelpButtonLayout("Browse Activities", new ActivitySearchView(activityDatabase, protoActivity_database, layoutStack), layoutStack))
                                 .Uniform()
                                 .Build();

            GridLayout_Builder childrenBuilder = new Horizontal_GridLayout_Builder().Uniform();

            for (int i = 0; i < this.numChoices; i++)
            {
                bool allowRequestingActivityDirectly = (i < numActivitiesThatMayBeRequestedDirectly);
                ExperimentOptionLayout child         = new ExperimentOptionLayout(this, activityDatabase, allowRequestingActivityDirectly, engine, layoutStack);
                this.children.Add(child);
                childrenBuilder.AddLayout(child);
                child.SuggestionDismissed += Child_SuggestionDismissed;
                child.JustifySuggestion   += Child_JustifySuggestion;
            }
            GridLayout bottomGrid = childrenBuilder.Build();

            BoundProperty_List rowHeights = new BoundProperty_List(3);

            rowHeights.BindIndices(0, 1);
            rowHeights.BindIndices(0, 2);
            rowHeights.SetPropertyScale(0, 2);
            rowHeights.SetPropertyScale(1, 1);
            rowHeights.SetPropertyScale(2, 6);

            GridLayout mainGrid = GridLayout.New(rowHeights, new BoundProperty_List(1), LayoutScore.Zero);

            mainGrid.AddLayout(topGrid);
            mainGrid.AddLayout(this.statusHolder);
            mainGrid.AddLayout(bottomGrid);

            string statusMessage = "(" + experimentsStatus.NumExperimentParticipationsRemaining + " experiment";

            if (experimentsStatus.NumExperimentParticipationsRemaining != 1)
            {
                statusMessage += "s";
            }
            statusMessage += " remaining before another ToDo must be entered!)";
            this.UpdateStatus(statusMessage);

            this.SetContent(mainGrid);
        }
        public ParticipationEntryView(ActivityDatabase activityDatabase, LayoutStack layoutStack)
        {
            this.activityDatabase           = activityDatabase;
            activityDatabase.ActivityAdded += ActivityDatabase_ActivityAdded;
            this.layoutStack = layoutStack;

            BoundProperty_List rowHeights = new BoundProperty_List(6);

            rowHeights.BindIndices(0, 1);
            rowHeights.BindIndices(0, 2);
            rowHeights.BindIndices(0, 3);
            rowHeights.SetPropertyScale(0, 5);   // activity name and feedback
            rowHeights.SetPropertyScale(1, 5);   // rating, comments, and metrics
            rowHeights.SetPropertyScale(2, 2.3); // start and end times
            rowHeights.SetPropertyScale(3, 2);   // buttons

            // activity name and feedback
            Vertical_GridLayout_Builder nameAndFeedback_builder = new Vertical_GridLayout_Builder();

            GridLayout contents = GridLayout.New(rowHeights, BoundProperty_List.Uniform(1), LayoutScore.Zero);

            this.nameBox = new ActivityNameEntryBox("What Have You Been Doing?", activityDatabase, layoutStack);
            this.nameBox.AutoAcceptAutocomplete      = false;
            this.nameBox.PreferSuggestibleActivities = true;
            this.nameBox.NameTextChanged            += this.ActivityNameText_Changed;
            nameAndFeedback_builder.AddLayout(this.nameBox);

            this.promptHolder = new ContainerLayout();
            nameAndFeedback_builder.AddLayout(this.promptHolder);

            Button responseButton = new Button();

            responseButton.Clicked += ResponseButton_Clicked;
            this.participationFeedbackButtonLayout = new ButtonLayout(responseButton);
            contents.AddLayout(nameAndFeedback_builder.BuildAnyLayout());

            Button acceptSuggestion_button = new Button();

            acceptSuggestion_button.Clicked += AcceptSuggestions_button_Clicked;

            Button visitSuggestions_button = new Button();

            visitSuggestions_button.Clicked += VisitSuggestions_button_Clicked;
            this.suggestionLayout            = new TextblockLayout();

            this.suggestionsLayout = new Vertical_GridLayout_Builder()
                                     .AddLayout(suggestionLayout)
                                     .AddLayout(new Horizontal_GridLayout_Builder().Uniform()
                                                .AddLayout(new ButtonLayout(acceptSuggestion_button, "Yes"))
                                                .AddLayout(new ButtonLayout(visitSuggestions_button, "More ideas"))
                                                .BuildAnyLayout()
                                                )
                                     .BuildAnyLayout();

            Button experimentFeedbackButton = new Button();

            experimentFeedbackButton.Clicked += ExperimentFeedbackButton_Clicked;
            this.experimentFeedbackLayout     = new ButtonLayout(experimentFeedbackButton, "Experiment Complete!");

            Vertical_GridLayout_Builder detailsBuilder = new Vertical_GridLayout_Builder();

            GridLayout commentAndRating_grid = GridLayout.New(BoundProperty_List.Uniform(1), BoundProperty_List.Uniform(2), LayoutScore.Zero);

            this.ratingBox = new RelativeRatingEntryView();
            this.ratingBox.RatingRatioChanged += RatingBox_RatingRatioChanged;
            commentAndRating_grid.AddLayout(this.ratingBox);
            this.commentBox = new PopoutTextbox("Comment", layoutStack);
            this.commentBox.Placeholder("(Optional)");
            commentAndRating_grid.AddLayout(this.commentBox);

            detailsBuilder.AddLayout(commentAndRating_grid);
            this.todoCompletionStatusHolder = new ContainerLayout();
            this.metricChooser = new ChooseMetric_View(true);
            this.metricChooser.ChoseNewMetric += TodoCompletionLabel_ChoseNewMetric;

            LayoutChoice_Set metricLayout = new Vertical_GridLayout_Builder().Uniform()
                                            .AddLayout(this.metricChooser)
                                            .AddLayout(this.todoCompletionStatusHolder)
                                            .Build();

            this.helpStatusHolder = new ContainerLayout();
            GridLayout_Builder centered_todoInfo_builder = new Horizontal_GridLayout_Builder().Uniform();

            centered_todoInfo_builder.AddLayout(metricLayout);
            centered_todoInfo_builder.AddLayout(this.helpStatusHolder);
            GridLayout_Builder offset_todoInfo_builder = new Horizontal_GridLayout_Builder();

            offset_todoInfo_builder.AddLayout(metricLayout);
            offset_todoInfo_builder.AddLayout(this.helpStatusHolder);

            LayoutChoice_Set metricStatusLayout = new LayoutUnion(
                centered_todoInfo_builder.Build(),
                new ScoreShifted_Layout(
                    offset_todoInfo_builder.Build(),
                    LayoutScore.Get_UnCentered_LayoutScore(1)
                    )
                );

            this.helpStatusPicker = new HelpDurationInput_Layout(this.layoutStack);
            detailsBuilder.AddLayout(metricStatusLayout);
            contents.AddLayout(detailsBuilder.BuildAnyLayout());

            GridLayout grid3 = GridLayout.New(BoundProperty_List.Uniform(1), BoundProperty_List.Uniform(2), LayoutScore.Zero);

            this.startDateBox = new DateEntryView("Start Time", this.layoutStack);
            this.startDateBox.Add_TextChanged_Handler(new EventHandler <TextChangedEventArgs>(this.DateText_Changed));
            grid3.AddLayout(this.startDateBox);
            this.endDateBox = new DateEntryView("End Time", this.layoutStack);
            this.endDateBox.Add_TextChanged_Handler(new EventHandler <TextChangedEventArgs>(this.DateText_Changed));
            grid3.AddLayout(this.endDateBox);
            contents.AddLayout(grid3);
            this.setStartdateButton = new Button();
            this.setEnddateButton   = new Button();

            this.okButton = new Button();

            LayoutChoice_Set helpWindow = (new HelpWindowBuilder()).AddMessage("Use this screen to record participations.")
                                          .AddMessage("1. Type the name of the activity that you participated in, and press Enter if you want to take the autocomplete suggestion.")
                                          .AddMessage("You must have entered some activities in the activity name entry screen in order to enter them here.")
                                          .AddMessage("Notice that once you enter an activity name, ActivityRecommender will tell you how it estimates this will affect your longterm happiness.")
                                          .AddMessage("2. You may enter a rating (this is strongly recommended). The rating is a measurement of how much happiness you received per unit time from "
                                                      + "this participation divided by the amount of happiness you received per unit time for the previous. "
                                                      + "(The ratio that you enter will be combined with ActivityRecommender's previous expectations of how much you would enjoy these two "
                                                      + "participations, and will be used to create an appropriate absolute rating from 0 to 1 for this participation.)")
                                          .AddMessage("If this Activity is a ToDo, you will see a box asking you to specify whether you completed the ToDo. Press the box if you completed it.")
                                          .AddMessage("3. Enter a start date and an end date. If you use the \"End = Now\" button right when the activity completes, you don't even need to type the date in. If you " +
                                                      "do have to type the date in, press the white box.")
                                          .AddMessage("4. Enter a comment if you like.")
                                          .AddMessage("5. Lastly, press OK.")
                                          .AddMessage("It's up to you how many participations you log, how often you rate them, and how accurate the start and end dates are. ActivityRecommender will be able to " +
                                                      "provide more useful help to you if you provide more accurate data, but even just a few participations per day should still be enough for meaningful feedback.")
                                          .AddLayout(new CreditsButtonBuilder(layoutStack)
                                                     .AddContribution(ActRecContributor.AARON_SMITH, new DateTime(2019, 8, 17), "Pointed out out that it was hard to tell when the participation and suggestion screens are not yet relevant due to not having any activities")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2019, 11, 10), "Suggested disallowing entering participations having empty durations")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2019, 11, 28), "Mentioned that the keyboard was often in the way of text boxes on iOS")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 1, 26), "Pointed out that feedback should be relative to average rather happiness than relative to the previous participation")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 4, 19), "Discussed participation feedback messages")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 7, 12), "Pointed out that the time required to log a participation can cause the end time of the next participation to be a couple minutes after the previous one")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 8, 15), "Suggested that if the participation feedback recommends a different time, then it should specify which time")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 8, 30), "Pointed out that participation feedback was missing more often than it should have been.")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 8, 30), "Pointed out that the text in the starttime box had stopped fitting properly.")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 10, 3), "Pointed out that it was possible record participations in the future.")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2021, 3, 9), "Suggested making different metrics appear more distinct.")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2021, 3, 21), "Pointed out that the participation feedback had stopped finding a better activity")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2021, 6, 6), "Suggested showing suggestions in the participation entry view")
                                                     .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2021, 7, 2), "Suggested shortening the text in the rating entry view")
                                                     .Build()
                                                     )
                                          .Build();

            GridLayout grid4 = GridLayout.New(BoundProperty_List.Uniform(1), BoundProperty_List.Uniform(4), LayoutScore.Zero);

            grid4.AddLayout(new ButtonLayout(this.setStartdateButton, "Start = now", 16));
            grid4.AddLayout(new ButtonLayout(this.okButton));
            grid4.AddLayout(new HelpButtonLayout(helpWindow, this.layoutStack));
            grid4.AddLayout(new ButtonLayout(this.setEnddateButton, "End = now", 16));
            contents.AddLayout(grid4);

            this.mainLayout = LayoutCache.For(contents);

            Vertical_GridLayout_Builder noActivities_help_builder = new Vertical_GridLayout_Builder();

            noActivities_help_builder.AddLayout(new TextblockLayout("This screen is where you will be able to record having participated in an activity.\n"));
            noActivities_help_builder.AddLayout(
                new HelpButtonLayout("Recording a participation is deceptively easy",
                                     new HelpWindowBuilder()
                                     .AddMessage("Autocomplete is everywhere in ActivityRecommender and is very fast. You will be impressed.")
                                     .AddMessage("Autocomplete is one of the reasons that you must enter an Activity before you can record a participation, so " +
                                                 "ActivityRecommender can know which activity you're referring to, usually after you type only one or two letters.")
                                     .Build()
                                     ,
                                     layoutStack
                                     )
                );
            noActivities_help_builder.AddLayout(
                new HelpButtonLayout("You get feedback!",
                                     new HelpWindowBuilder()
                                     .AddMessage("Nearly every time you record a participation, ActivityRecommender will give you feedback on what you're doing. " +
                                                 "This feedback will eventually contain suggestions of other things you could be doing now, and alternate times for what you " +
                                                 "did do. This feedback gets increasingly specific and increasingly accurate as you record more data, eventually including " +
                                                 "current happiness, future happiness, and future efficiency. Wow!")
                                     .Build()
                                     ,
                                     layoutStack
                                     )
                );

            noActivities_help_builder.AddLayout(new TextblockLayout("Before you can record a participation, ActivityRecommender needs you to go back " +
                                                                    "and add some activities first. Here is a convenient button for jumping directly to the Activities screen:"));

            Button activitiesButton = new Button();

            activitiesButton.Text     = "Activities";
            activitiesButton.Clicked += ActivitiesButton_Clicked;
            noActivities_help_builder.AddLayout(new ButtonLayout(activitiesButton));

            this.noActivities_explanationLayout = noActivities_help_builder.BuildAnyLayout();
        }
        public LayoutChoice_Set MakeLayout(LayoutStack layoutStack)
        {
            Vertical_GridLayout_Builder builder = new Vertical_GridLayout_Builder();

            if (this.SuggestedBadIdea)
            {
                string apology;
                if (this.PredictedValue > 1)
                {
                    // A fun idea that we didn't expect the user to do
                    // We expected the user to get distracted while considering the fun idea
                    apology = "Sorry, I didn't expect you to actually do this! I thought that this suggestion would help you think of a better idea!";
                }
                else
                {
                    // An annoying idea that we didn't expect the user to do
                    // We expected the user to remember how annoying this was and to avoid it and things like it
                    apology = "Sorry, I didn't expect you to actually do this! I thought that this suggestion would remind you to look harder for something better!";
                }
                builder.AddLayout(new TextblockLayout(apology));
            }
            builder.AddLayout(new TextblockLayout(ChosenActivity.Name));
            builder.AddLayout(new TextblockLayout("From " + this.StartDate + " to " + this.EndDate + ", " + ParticipationDurationDividedByAverage + " as long as average. I predict:"));

            GridLayout_Builder nowBuilder = new Horizontal_GridLayout_Builder().Uniform();

            nowBuilder.AddLayout(
                new Vertical_GridLayout_Builder().Uniform()
                .AddLayout(
                    new HelpButtonLayout("Fun (vs average):",
                                         new TextblockLayout("This column shows the amount of happiness you are expected to have while doing this activity at this time, divided by the average amount of happiness you usually have doing other things"),
                                         layoutStack)
                    )
                .AddLayout(coloredRatio(PredictedValue, ComparisonPredictedValue, PredictedCurrentValueStddev))
                .Build()
                );
            nowBuilder.AddLayout(
                new Vertical_GridLayout_Builder().Uniform()
                .AddLayout(
                    new HelpButtonLayout("Future Fun (days):",
                                         new TextblockLayout("This column shows an estimate of the net present value of your happiness at this time after doing this activity, compared to what it usually is. " +
                                                             "This is very similar to computing how many days of happiness you will gain or lose over the next " + Math.Round(UserPreferences.DefaultPreferences.HalfLife.TotalDays / Math.Log(2), 0) +
                                                             " days after doing this."),
                                         layoutStack)
                    )
                .AddLayout(signedColoredValue(ExpectedFutureFun, ComparisonExpectedFutureFun, ExpectedFutureFunStddev))
                .Build()
                );
            nowBuilder.AddLayout(
                new Vertical_GridLayout_Builder().Uniform()
                .AddLayout(
                    new HelpButtonLayout("Future Efficiency (hours):",
                                         new TextblockLayout("This column shows an estimate of the net present value of your efficiency at this time after doing this activity, compared to what it usually is. " +
                                                             "This is very similar to computing how many hours of efficiency you will gain or lose over the next " + Math.Round(UserPreferences.DefaultPreferences.EfficiencyHalflife.TotalDays / Math.Log(2), 0) +
                                                             " days after doing this."),
                                         layoutStack)
                    )
                .AddLayout(signedColoredValue(ExpectedEfficiency, ComparisonExpectedEfficiency, ExpectedEfficiencyStddev))
                .Build()
                );
            builder.AddLayout(nowBuilder.Build());

            builder.AddLayout(new TextblockLayout("If you had done this at " + this.ComparisonDate + ":"));

            GridLayout_Builder laterBuilder = new Horizontal_GridLayout_Builder().Uniform();

            laterBuilder.AddLayout(coloredRatio(ComparisonPredictedValue, 1, 0));
            laterBuilder.AddLayout(signedColoredValue(ComparisonExpectedFutureFun, 1, 0));
            laterBuilder.AddLayout(signedColoredValue(ComparisonExpectedEfficiency, 0, 0));
            builder.AddLayout(laterBuilder.Build());

            ActivityRequest request = new ActivityRequest();

            request.ActivityToBeat = this.ChosenActivity.MakeDescriptor();
            request.Date           = this.StartDate;
            //request.RequestedProcessingTime = TimeSpan.FromSeconds(0.5);
            ActivitiesSuggestion suggestion       = this.engine.MakeRecommendation(request);
            Activity             betterActivity   = this.ActivityDatabase.ResolveDescriptor(suggestion.ActivityDescriptors[0]);
            Prediction           betterPrediction = this.engine.Get_OverallHappiness_ParticipationEstimate(betterActivity, request);
            string       redirectionText;
            Color        redirectionColor;
            Distribution betterFutureHappinessImprovementInDays = this.engine.compute_longtermValue_increase_in_days(betterPrediction.Distribution, this.StartDate, this.StartDate);
            double       improvementInDays = Math.Round(betterFutureHappinessImprovementInDays.Mean - this.ExpectedFutureFun, 1);

            if (improvementInDays <= 0)
            {
                string noIdeasText = "I don't have any better suggestions for things to do at this time.";
                if (ExpectedFutureFun >= 0)
                {
                    if (PredictedValue >= 1)
                    {
                        redirectionText = "Nice! " + noIdeasText; // Happy now, happy later
                    }
                    else
                    {
                        redirectionText = noIdeasText + " Sorry!"; // Happy later, not happy now
                    }
                }
                else
                {
                    if (PredictedValue >= 1)
                    {
                        redirectionText = noIdeasText; // Happy now, not happy later
                    }
                    else
                    {
                        redirectionText = "How about adding a new activity? " + noIdeasText; // Not happy now or later
                    }
                }
                redirectionColor = Color.Green;
            }
            else
            {
                string improvementText = improvementInDays.ToString();
                if (this.Suggested)
                {
                    redirectionText  = "I thought of a better idea: " + betterActivity.Name + ", better by +" + improvementText + " days fun. Sorry for not mentioning this earlier!";
                    redirectionColor = Color.Yellow;
                }
                else
                {
                    if (ExpectedFutureFun >= 0)
                    {
                        redirectionText  = "I suggest that " + betterActivity.Name + " would be even better: +" + improvementText + " days fun.";
                        redirectionColor = Color.Yellow;
                    }
                    else
                    {
                        redirectionText  = "I suggest that " + betterActivity.Name + " would improve your future happiness by " + improvementText + " days.";
                        redirectionColor = Color.Red;
                    }
                }
            }
            builder.AddLayout(new TextblockLayout(redirectionText, redirectionColor));


            return(builder.BuildAnyLayout());
        }
Ejemplo n.º 11
0
        public BrowseParticipations_Layout(ActivityDatabase activityDatabase, Engine engine, ScoreSummarizer scoreSummarizer, LayoutStack layoutStack)
        {
            this.activityDatabase = activityDatabase;
            this.engine           = engine;
            this.layoutStack      = layoutStack;
            this.scoreSummarizer  = scoreSummarizer;

            TextblockLayout helpLayout = new TextblockLayout("Browse participations");

            ActivityNameEntryBox categoryBox = new ActivityNameEntryBox("Category", activityDatabase, layoutStack, false, false);

            categoryBox.Placeholder("(Optional)");
            this.categoryBox = categoryBox;

            this.sinceDate_box = new DateEntryView("Since", layoutStack, false);
            this.sinceDate_box.Placeholder("(Optional)");

            this.displayRatings_box         = new VisiPlacement.CheckBox("No", "Yes");
            this.displayRatings_box.Checked = true;
            Thickness        buttonMargin          = new Thickness(0, 1);
            LayoutChoice_Set displayRatings_layout = new Horizontal_GridLayout_Builder()
                                                     .Uniform()
                                                     .AddLayout(new TextblockLayout("Show ratings?"))
                                                     .AddLayout(new MustBorderLayout(null, this.displayRatings_box, buttonMargin))
                                                     .BuildAnyLayout();

            this.requireComments_box         = new VisiPlacement.CheckBox("No", "Yes");
            this.requireComments_box.Checked = true;
            LayoutChoice_Set requireComments_layout = new Horizontal_GridLayout_Builder()
                                                      .Uniform()
                                                      .AddLayout(new TextblockLayout("Require comments?"))
                                                      .AddLayout(new MustBorderLayout(null, this.requireComments_box, buttonMargin))
                                                      .BuildAnyLayout();

            this.requireSuccessful_box = new VisiPlacement.SingleSelect(null, new List <string>()
            {
                "Any", "No Metric", "Successful", "Failed"
            });
            LayoutChoice_Set requireSuccessful_layout = new Horizontal_GridLayout_Builder()
                                                        .Uniform()
                                                        .AddLayout(new TextblockLayout("Require success status ="))
                                                        .AddLayout(new MustBorderLayout(null, this.requireSuccessful_box, buttonMargin))
                                                        .BuildAnyLayout();

            this.sortBy_box = new VisiPlacement.SingleSelect(null, new List <string>()
            {
                this.sortByFun_text, this.sortBy_netPresentHappiness_text, this.sortByEfficiency_text
            });
            LayoutChoice_Set sortBy_layout = new Horizontal_GridLayout_Builder()
                                             .Uniform()
                                             .AddLayout(new TextblockLayout("Sort by"))
                                             .AddLayout(new MustBorderLayout(null, this.sortBy_box, buttonMargin))
                                             .BuildAnyLayout();


            Button       browseTopParticipations_button = new Button();
            ButtonLayout browseTopParticipations_layout = new ButtonLayout(browseTopParticipations_button, "Top " + this.maxNumTopParticipationsToShow);

            browseTopParticipations_button.Clicked += BrowseTopParticipations_Button_Clicked;

            Button       browseExtremeParticipations_button = new Button();
            ButtonLayout browseExtremeParticipations_layout = new ButtonLayout(browseExtremeParticipations_button, "" + this.maxNumTopParticipationsToShow + " best/worst");

            browseExtremeParticipations_button.Clicked += BrowseExtremeParticipations_button_Clicked;


            Button       seeGoodRandomParticipation_button = new Button();
            ButtonLayout seeGoodRandomParticipation_layout = new ButtonLayout(seeGoodRandomParticipation_button, "A random, probably good one");

            seeGoodRandomParticipation_button.Clicked += SeeGoodRandomParticipation_Clicked;

            Button       seeRandomParticipations_button = new Button();
            ButtonLayout seeRandomParticipations_layout = new ButtonLayout(seeRandomParticipations_button, "" + this.maxNumRandomActivitiesToShow + " (uniformly) random");

            seeRandomParticipations_button.Clicked += SeeRandomParticipations_button_Clicked;

            this.SubLayout = new Vertical_GridLayout_Builder()
                             .AddLayout(helpLayout)
                             .AddLayout(categoryBox)
                             .AddLayout(sinceDate_box)
                             .AddLayout(displayRatings_layout)
                             .AddLayout(requireComments_layout)
                             .AddLayout(requireSuccessful_layout)
                             .AddLayout(sortBy_layout)
                             .AddLayout(
                new Horizontal_GridLayout_Builder()
                .Uniform()
                .AddLayout(browseTopParticipations_layout)
                .AddLayout(browseExtremeParticipations_layout)
                .AddLayout(seeGoodRandomParticipation_layout)
                .AddLayout(seeRandomParticipations_layout)
                .BuildAnyLayout()
                )
                             .Build();
            this.randomGenerator = new Random();
        }
Ejemplo n.º 12
0
        public SuggestionView(ActivitiesSuggestion suggestion, bool isFirstSuggestion, Dictionary <ActivitySuggestion, bool> repeatingDeclinedSuggestion, LayoutStack layoutStack)
        {
            this.suggestion  = suggestion;
            this.layoutStack = layoutStack;

            bool allWorseThanAverage = true;

            foreach (ActivitySuggestion child in suggestion.Children)
            {
                if (!child.WorseThanRootActivity)
                {
                    allWorseThanAverage = false;
                }
            }

            GridLayout_Builder fullBuilder   = new Vertical_GridLayout_Builder();
            string             startTimeText = suggestion.Children[0].StartDate.ToString("HH:mm");

            bool badSuggestion = (allWorseThanAverage && suggestion.Skippable);

            if (badSuggestion)
            {
                fullBuilder.AddLayout(new TextblockLayout("Best ideas at " + startTimeText + ":", 24).AlignHorizontally(TextAlignment.Center));
            }
            else
            {
                fullBuilder.AddLayout(new TextblockLayout("At " + startTimeText + ":", 24).AlignHorizontally(TextAlignment.Center));
            }

            List <LayoutChoice_Set> specificFont_contentChoices = new List <LayoutChoice_Set>(); // list of layouts we might use, each with a different font size

            this.explainButtons = new Dictionary <Button, ActivitySuggestion>();
            this.doButtons      = new Dictionary <Button, ActivitySuggestion>();
            for (int mainFontSize = 20; mainFontSize >= 12; mainFontSize -= 8)
            {
                // grid containing the specific activities the user could do
                GridLayout activityOptionsGrid = GridLayout.New(new BoundProperty_List(3), BoundProperty_List.Uniform(suggestion.Children.Count), LayoutScore.Zero);

                for (int i = 0; i < suggestion.Children.Count; i++)
                {
                    ActivitySuggestion child = suggestion.Children[i];

                    // set up the options for the text
                    string          mainText  = this.summarize(child, repeatingDeclinedSuggestion[child]);
                    TextblockLayout mainBlock = new TextblockLayout(mainText, mainFontSize);
                    TextAlignment   horizontalAlignment;
                    TextAlignment   verticalAlignment;
                    if (i == 0)
                    {
                        horizontalAlignment = TextAlignment.Start;
                        if (suggestion.Children.Count == 1)
                        {
                            verticalAlignment = TextAlignment.Start;
                        }
                        else
                        {
                            verticalAlignment = TextAlignment.End;
                        }
                    }
                    else
                    {
                        if (i == suggestion.Children.Count - 1)
                        {
                            horizontalAlignment = TextAlignment.End;
                            verticalAlignment   = TextAlignment.Start;
                        }
                        else
                        {
                            horizontalAlignment = TextAlignment.Center;
                            verticalAlignment   = TextAlignment.Center;
                        }
                    }
                    mainBlock.AlignHorizontally(horizontalAlignment);
                    mainBlock.AlignVertically(verticalAlignment);
                    activityOptionsGrid.PutLayout(mainBlock, i, 0);

                    // set up the buttons
                    GridLayout_Builder buttonsBuilder = new Horizontal_GridLayout_Builder().Uniform();
                    double             buttonFontSize = mainFontSize * 0.9;
                    // make a doNow button if needed
                    if (isFirstSuggestion)
                    {
                        Button doNowButton = new Button();
                        doNowButton.Clicked        += DoNowButton_Clicked;
                        this.doButtons[doNowButton] = child;
                        ButtonLayout doButtonLayout = new ButtonLayout(doNowButton, "OK", buttonFontSize);
                        buttonsBuilder.AddLayout(doButtonLayout);
                    }
                    if (child.PredictedScoreDividedByAverage != null)
                    {
                        Button explainButton = new Button();
                        explainButton.Clicked += explainButton_Clicked;
                        this.explainButtons[explainButton] = child;
                        ButtonLayout explainLayout = new ButtonLayout(explainButton, "?", buttonFontSize);
                        buttonsBuilder.AddLayout(explainLayout);
                    }
                    activityOptionsGrid.PutLayout(buttonsBuilder.BuildAnyLayout(), i, 1);
                    if (child.ExpectedReaction != null)
                    {
                        TextblockLayout reactionLayout = new TextblockLayout(child.ExpectedReaction, buttonFontSize * 0.9);
                        reactionLayout.AlignHorizontally(horizontalAlignment);
                        reactionLayout.AlignVertically(verticalAlignment);
                        activityOptionsGrid.PutLayout(reactionLayout, i, 2);
                    }
                }

                LayoutChoice_Set optionsAtThisFontSize;
                if (badSuggestion)
                {
                    // If the suggestion is bad and we don't really want the user to do it, then we also show the user some convenient buttons for making more activities
                    GridLayout wrapper = GridLayout.New(new BoundProperty_List(1), BoundProperty_List.WithRatios(new List <double>()
                    {
                        suggestion.Children.Count, 1
                    }), LayoutScore.Zero);
                    wrapper.AddLayout(activityOptionsGrid);                            // activity suggestions
                    wrapper.AddLayout(this.make_otherActivities_layout(mainFontSize)); // layout for making new activities
                    optionsAtThisFontSize = wrapper;
                }
                else
                {
                    // If the suggestion isn't bad, then the options we give are just the activities being suggested
                    optionsAtThisFontSize = activityOptionsGrid;
                }
                specificFont_contentChoices.Add(optionsAtThisFontSize);
            }

            LayoutChoice_Set contentGrid = LayoutUnion.New(specificFont_contentChoices);

            // Add cancel buttons to the bottom
            this.cancelButton                         = new Button();
            this.cancelButton.Clicked                += cancelButton_Click;
            this.explainWhyYouCantSkipButton          = new Button();
            this.explainWhyYouCantSkipButton.Clicked += ExplainWhyYouCantSkipButton_Clicked;
            ButtonLayout cancelLayout;

            if (suggestion.Skippable)
            {
                cancelLayout = new ButtonLayout(this.cancelButton, "X");
            }
            else
            {
                cancelLayout = new ButtonLayout(this.explainWhyYouCantSkipButton, "!");
            }



            fullBuilder.AddLayout(contentGrid)
            .AddLayout(cancelLayout);

            this.SubLayout = fullBuilder.BuildAnyLayout();
        }
Ejemplo n.º 13
0
        public ProtoActivity_Editing_Layout(ProtoActivity protoActivity, ProtoActivity_Database database, ActivityDatabase activityDatabase, LayoutStack layoutStack)
        {
            this.protoActivity    = protoActivity;
            this.database         = database;
            this.activityDatabase = activityDatabase;
            this.activityDatabase.ActivityAdded += ActivityDatabase_ActivityAdded;
            this.layoutStack  = layoutStack;
            this.textBox      = new Editor();
            this.textBox.Text = protoActivity.Text;

            Vertical_GridLayout_Builder gridBuilder = new Vertical_GridLayout_Builder();
            string titleText;

            if (protoActivity.Id >= 0)
            {
                titleText = "ProtoActivity #" + protoActivity.Id;
            }
            else
            {
                titleText = "New ProtoActivity";
            }
            gridBuilder.AddLayout(new TextblockLayout(titleText));
            gridBuilder.AddLayout(ScrollLayout.New(new TextboxLayout(this.textBox)));

            Button saveButton = new Button();

            saveButton.Text     = "Save";
            saveButton.Clicked += SaveButton_Clicked;

            Button promoteButton = new Button();

            promoteButton.Text     = "Promote to Activity";
            promoteButton.Clicked += PromoteButton_Clicked;

            Button splitButton = new Button();

            splitButton.Text     = "Split";
            splitButton.Clicked += SplitButton_Clicked;

            HelpButtonLayout helpButtonLayout = new HelpButtonLayout(new HelpWindowBuilder()
                                                                     .AddMessage("This screen allows you to edit " + titleText + ".")
                                                                     .AddMessage("Enter as much text as you like.")
                                                                     .AddMessage("To save your entry, either press Save or simply go back to another screen.")
                                                                     .AddMessage("  After you go back, if you later want to return to this same ProtoActivity, you will have to go to one of the screens for browsing existing ProtoActivities and then search for it.")
                                                                     .AddMessage("To turn this ProtoActivity into an Activity, press Promote to Activity.")
                                                                     .AddMessage("To delete this ProtoActivity, delete all of the text in the box and then either press Save or go back to a previous screen.")
                                                                     .AddLayout(new CreditsButtonBuilder(layoutStack)
                                                                                .AddContribution(ActRecContributor.AARON_SMITH, new DateTime(2019, 9, 16), "Pointed out that the promote-a-protoactivity button crashed if the text box was empty")
                                                                                .Build()
                                                                                )
                                                                     .Build()
                                                                     , layoutStack);

            LayoutChoice_Set buttonsLayout = new Horizontal_GridLayout_Builder()
                                             .AddLayout(new ButtonLayout(saveButton))
                                             .AddLayout(new ButtonLayout(promoteButton))
                                             .AddLayout(new ButtonLayout(splitButton))
                                             .AddLayout(helpButtonLayout)
                                             .BuildAnyLayout();

            gridBuilder.AddLayout(buttonsLayout);

            this.SubLayout = gridBuilder.Build();
        }