public ExperimentDifficultyEstimateLayout(SuggestedMetric suggestedMetric, Activity activity)
        {
            this.suggestedMetric = suggestedMetric;

            this.metricChooser = new ChooseMetric_View(false);
            this.metricChooser.SetActivity(activity);
            this.metricChooser.Choose(suggestedMetric.PlannedMetric.MetricName);

            this.difficultyBox              = new Editor();
            this.difficultyBox.Keyboard     = Keyboard.Numeric;
            this.difficultyBox.Placeholder  = this.defaultDifficulty.ToString();
            this.difficultyLayout           = new TitledControl("Difficulty:", new TextboxLayout(difficultyBox));
            this.difficultyBox.TextChanged += DifficultyBox_TextChanged;

            TextblockLayout nameLayout = new TextblockLayout(activity.Name);

            GridLayout evenGrid   = GridLayout.New(new BoundProperty_List(1), BoundProperty_List.Uniform(3), LayoutScore.Zero);
            GridLayout unevenGrid = GridLayout.New(new BoundProperty_List(1), new BoundProperty_List(3), LayoutScore.Get_UnCentered_LayoutScore(1));

            evenGrid.AddLayout(this.metricChooser);
            unevenGrid.AddLayout(this.metricChooser);

            evenGrid.AddLayout(nameLayout);
            unevenGrid.AddLayout(nameLayout);

            evenGrid.AddLayout(this.difficultyLayout);
            unevenGrid.AddLayout(this.difficultyLayout);


            this.SubLayout = new LayoutUnion(evenGrid, unevenGrid);
        }
Example #2
0
 public HelpDurationInput_DetailsLayout()
 {
     this.typeBox               = new VisiPlacement.CheckBox("as a multiple of your effort:", "as a number of minutes:");
     this.typeBox.Updated      += TypeBox_Clicked;
     this.minutesDurationLayout = new MinutesDurationLayout();
     this.ratioLayout           = new RatioLayout();
     this.gridLayout            = GridLayout.New(BoundProperty_List.Uniform(3), new BoundProperty_List(1), LayoutScore.Zero);
     this.gridLayout.AddLayout(new TextblockLayout("Enter help received"));
     this.gridLayout.AddLayout(this.typeBox);
     this.SubLayout = this.gridLayout;
     this.updateSublayout();
 }
Example #3
0
        public NewInheritanceLayout(ActivityDatabase activityDatabase, LayoutStack layoutStack)
        {
            this.activityDatabase = activityDatabase;
            this.layoutStack      = layoutStack;

            this.SetTitle("Relate Two Existing Activities");

            GridLayout bottomGrid = GridLayout.New(new BoundProperty_List(2), BoundProperty_List.Uniform(2), LayoutScore.Zero);

            this.childNameBox = new ActivityNameEntryBox("Activity Name", activityDatabase, layoutStack);
            this.childNameBox.AutoAcceptAutocomplete = false;
            bottomGrid.AddLayout(this.childNameBox);

            this.parentNameBox = new ActivityNameEntryBox("Parent Name", activityDatabase, layoutStack);
            this.parentNameBox.AutoAcceptAutocomplete = false;
            bottomGrid.AddLayout(this.parentNameBox);

            this.okButton          = new Button();
            this.okButton.Clicked += OkButton_Clicked;
            bottomGrid.AddLayout(new ButtonLayout(this.okButton, "OK"));


            LayoutChoice_Set helpWindow = (new HelpWindowBuilder()).AddMessage("This screen is for you to enter activities, to use as future suggestions.")
                                          .AddMessage("The text box on the left is where you type the activity name.")
                                          .AddMessage("The text box on the right is where you type another activity that you want to make be a parent of the given activity.")
                                          .AddMessage("For example, you might specify that Gaming is a child activity of the Fun activity. Grouping activities like this is helpful for two reasons. It gives " +
                                                      "ActivityRecommender more understanding about the relationships between activities and can help it to notice trends. It also means that you can later request a suggestion " +
                                                      "from within Activity \"Fun\" and ActivityRecommender will know what you mean, and might suggest \"Gaming\".")
                                          .AddMessage("If you haven't created the parent activity yet, you'll have to create it first. The only activity that exists at the beginning is the built-in activity " +
                                                      "named \"Activity\".")
                                          .AddMessage("While typing you can press Enter to fill in the autocomplete suggestion.")
                                          .Build();

            HelpButtonLayout helpLayout = new HelpButtonLayout(helpWindow, layoutStack);

            bottomGrid.AddLayout(helpLayout);

            this.feedbackLayout = new TextblockLayout();

            GridLayout mainGrid = new Vertical_GridLayout_Builder()
                                  .AddLayout(this.feedbackLayout)
                                  .AddLayout(bottomGrid)
                                  .Build();

            this.SetContent(mainGrid);
        }
Example #4
0
        public FullscreenDateEntryView(string title, List <DateCharacter> dateFormat, LayoutStack layoutStack)
        {
            this.dateFormat = dateFormat;

            this.dateLayout = new TextblockLayout("");
            this.nowLayout  = new TextblockLayout("");

            dateLayout.ScoreIfEmpty = true;
            GridLayout mainGrid = GridLayout.New(new BoundProperty_List(4), new BoundProperty_List(1), LayoutScore.Zero);

            mainGrid.AddLayout(nowLayout);
            mainGrid.AddLayout(new TextblockLayout("Enter " + title + ":"));
            mainGrid.AddLayout(dateLayout);

            GridLayout buttonGrid = GridLayout.New(BoundProperty_List.Uniform(4), BoundProperty_List.Uniform(3), LayoutScore.Zero);

            buttonGrid.AddLayout(this.makeButtonNumber(1));
            buttonGrid.AddLayout(this.makeButtonNumber(2));
            buttonGrid.AddLayout(this.makeButtonNumber(3));

            buttonGrid.AddLayout(this.makeButtonNumber(4));
            buttonGrid.AddLayout(this.makeButtonNumber(5));
            buttonGrid.AddLayout(this.makeButtonNumber(6));

            buttonGrid.AddLayout(this.makeButtonNumber(7));
            buttonGrid.AddLayout(this.makeButtonNumber(8));
            buttonGrid.AddLayout(this.makeButtonNumber(9));

            LayoutChoice_Set helpWindow = new HelpWindowBuilder()
                                          .AddMessage("This screen enables you to enter " + title + " using the format " + this.getDateFormatString() + ".")
                                          .AddMessage("Press the backspace button (the '<-') to remove any incorrect characters (it will remove several at a time).")
                                          .AddMessage("Then use the keypad to enter new digits to use in the date/time.")
                                          .AddMessage("Filler characters like '-', 'T', and ':' will be automatically added for you.")
                                          .AddMessage("Press your device's Back button when finished.")
                                          .Build();

            buttonGrid.AddLayout(new HelpButtonLayout(helpWindow, layoutStack));
            buttonGrid.AddLayout(this.makeButtonNumber(0));
            buttonGrid.AddLayout(this.makeBackspaceButton());

            mainGrid.AddLayout(buttonGrid);
            this.DateText = DateText;

            this.SubLayout = mainGrid;
        }
        public MetricEditingLayout(ActivityDatabase activityDatabase, LayoutStack layoutStack)
        {
            this.activityDatabase = activityDatabase;
            this.nameBox          = new ActivityNameEntryBox("Activity", activityDatabase, layoutStack);
            Button okButton = new Button();

            okButton.Clicked       += OkButton_Clicked;
            this.metricBox          = new TitledTextbox("Metric Name");
            this.errorMessageHolder = new TextblockLayout();

            LayoutChoice_Set helpWindow = new HelpWindowBuilder()
                                          .AddMessage("This screen lets you add a Metric to an existing activity (metrics are required for running experiments).")
                                          .AddMessage("A metric is a way of measuring how well a participation accomplishes a goal.")
                                          .AddMessage("At the moment, ActivityRecommender only supports adding Metrics that classify a participation as a success or failure.")
                                          .AddMessage("(You record the success/failure status when you record having participated in the Activity)")
                                          .AddMessage("For example, if you have an Activity named Making Food, one possible metric would be 'Make 1 gallon of smoothie'.")
                                          .AddMessage("Alternatively, if you have a computer game you'd like to beat, another possible metric would be 'Beat 1 Level'.")
                                          .AddMessage("The reason you might want to create a Metric is to allow ActivityRecommender to know it can measure your effectiveness on this task.")
                                          .AddMessage("Any Activity with a Metric is eligible to take part in effectiveness experiments.")
                                          .AddMessage("Also note that any Activity of type ToDo already starts with a built-in metric, which is to complete the ToDo.")
                                          .AddMessage("Also note that any Activity that is a Problem or inherits from a Problem will receive a metric, which is to solve the Problem.")
                                          .Build();

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

            mainGrid.AddLayout(new TextblockLayout("Add Metric to Existing Activity"));
            mainGrid.AddLayout(new TextblockLayout("Metrics are required before running an experiment (and measuring your efficiency).", 12));
            mainGrid.AddLayout(this.errorMessageHolder);

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

            bottomGrid.AddLayout(this.metricBox);
            bottomGrid.AddLayout(this.nameBox);
            bottomGrid.AddLayout(new ButtonLayout(okButton, "OK"));
            bottomGrid.AddLayout(new HelpButtonLayout(helpWindow, layoutStack));

            mainGrid.AddLayout(bottomGrid);

            this.SubLayout = mainGrid;
        }
        public ActivityVisualizationView(IProgression participationXAxis, Activity yAxisActivity, ScoreSummarizer overallRating_summarizer, ScoreSummarizer overallEfficiency_summarizer, LayoutStack layoutStack)
        {
            this.layoutStack = layoutStack;
            this.overallRating_summarizer     = overallRating_summarizer;
            this.overallEfficiency_summarizer = overallEfficiency_summarizer;

            this.xAxisProgression = participationXAxis;
            this.yAxisActivity    = yAxisActivity;

            // setup the title
            this.SetTitle(this.YAxisLabel + " vs. " + this.XAxisLabel);

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

            this.SetContent(fixedGrid);

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

            // setup a graph of the ratings
            this.ratingsView = new TitledControl("Ratings vs. Time");
            graphGrid.AddLayout(this.ratingsView);

            // setup a graph of the participations
            this.participationsView = new TitledControl("Participations vs. " + this.XAxisLabel);
            graphGrid.AddLayout(this.participationsView);

            //flexibleGrid.AddLayout(graphGrid);
            fixedGrid.AddLayout(graphGrid);

            this.statsLayoutHolder           = new ContainerLayout();
            this.statsLayoutHolder.SubLayout = this.Make_StatsView();

            fixedGrid.AddLayout(this.statsLayoutHolder);

            this.UpdateDrawing();
        }
Example #7
0
        public BrowseBest_ProtoActivities_Layout(ProtoActivity_Database protoActivity_database, ActivityDatabase activityDatabase, LayoutStack layoutStack)
        {
            this.protoActivity_database = protoActivity_database;
            this.layoutStack            = layoutStack;
            this.activityDatabase       = activityDatabase;

            Button edit1Button = new Button();

            edit1Button.Text     = "Edit";
            edit1Button.Clicked += Edit1Button_Clicked;

            Button edit2Button = new Button();

            edit2Button.Text     = "Edit";
            edit2Button.Clicked += Edit2Button_Clicked;

            Button mark1Worse_button = new Button();

            mark1Worse_button.Text     = "Worse";
            mark1Worse_button.Clicked += Mark1Worse_button_Clicked;

            Button explainScore1Button = new Button();

            explainScore1Button.Text     = "?";
            explainScore1Button.Clicked += ExplainScore1Button_Clicked;
            this.explainScore1Button     = new ButtonLayout(explainScore1Button);

            Button mark2Worse_button = new Button();

            mark2Worse_button.Text     = "Worse";
            mark2Worse_button.Clicked += Mark2Worse_button_Clicked;

            Button explainScore2Button = new Button();

            explainScore2Button.Text     = "?";
            explainScore2Button.Clicked += ExplainScore2Button_Clicked;
            this.explainScore2Button     = new ButtonLayout(explainScore2Button);

            BoundProperty_List rowHeights   = BoundProperty_List.Uniform(3);
            BoundProperty_List columnWidths = new BoundProperty_List(3);

            columnWidths.BindIndices(0, 1);
            columnWidths.BindIndices(0, 2);
            columnWidths.SetPropertyScale(0, 1);
            columnWidths.SetPropertyScale(1, 4);
            columnWidths.SetPropertyScale(2, 1);

            GridLayout grid = GridLayout.New(rowHeights, columnWidths, LayoutScore.Zero);

            this.numBrowsesPerProtoactivity_Layout = new TextblockLayout().AlignVertically(TextAlignment.Center);
            grid.PutLayout(this.numBrowsesPerProtoactivity_Layout, 0, 0);

            this.titleLayout = new TextblockLayout("Browse Best ProtoActivities");
            grid.PutLayout(this.titleLayout, 1, 0);
            LayoutChoice_Set helpButton = new HelpButtonLayout(
                new HelpWindowBuilder()
                .AddMessage("If you have entered any ProtoActivities (which are ideas that are not yet fully-formed enough for you to want them to be suggested), then you can browse them here.")
                .AddMessage("This screen allows you to see the ProtoActivities that ActivityRecommender thinks you consider to be most interesting, and also asks you to choose which one of the top " +
                            "two is most interesting to you.")
                .AddMessage("If you want to modify a ProtoActivity, press its Edit button (note that if you make any changes, then this will temporarily dismiss it (by resetting its interest score)).")
                .AddMessage("If you want to see different ProtoActivities, then first you should choose which one (of the two visible ProtoActivities) you like less. Press the button marked " +
                            "'Worse' next to the ProtoActivity that you like less. This will cause two new ProtoActivities to appear (by resetting the interest scores of the two currently visible " +
                            "ProtoActivities to 0). This will also cause the one you marked 'Worse' to return less often and " +
                            "the other one to return more often.")
                .AddMessage("The way that ProtoActivities are chosen in this screen is that each ProtoActivity has a score of how much you like it, and " +
                            "a duration since the last time you interacted with that ProtoActivity. The product of the two is its interest score, and the " +
                            "ProtoActivities with the highest interest scores are the ones that will be displayed.")
                .AddMessage("If you want to see the calculation of the interest scores of the two current ProtoActivities, press the \"?\" button.")
                .AddMessage("Enjoy!")
                .AddLayout(new CreditsButtonBuilder(layoutStack)
                           .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 5, 28), "Suggested explaining the calculation of protoactivity sort score")
                           .Build()
                           )
                .Build(),
                layoutStack);

            grid.PutLayout(helpButton, 2, 0);
            grid.PutLayout(new ButtonLayout(edit1Button), 0, 1);
            grid.PutLayout(new ButtonLayout(edit2Button), 0, 2);
            this.activity1Holder = new ContainerLayout();
            grid.PutLayout(this.activity1Holder, 1, 1);
            this.activity2Holder = new ContainerLayout();
            grid.PutLayout(this.activity2Holder, 1, 2);
            this.activity1ScoreBlock = new TextblockLayout();
            this.score1Holder        = new ContainerLayout();
            this.score2Holder        = new ContainerLayout();
            grid.PutLayout(
                new Vertical_GridLayout_Builder()
                .Uniform()
                .AddLayout(new ButtonLayout(mark1Worse_button))
                .AddLayout(this.score1Holder)
                .BuildAnyLayout()
                , 2, 1);
            this.activity2ScoreBlock = new TextblockLayout();
            grid.PutLayout(
                new Vertical_GridLayout_Builder()
                .Uniform()
                .AddLayout(new ButtonLayout(mark2Worse_button))
                .AddLayout(this.score2Holder)
                .BuildAnyLayout()
                , 2, 2);

            this.multiActivitiesLayout = grid;

            this.protoActivity_database.RatingsChanged += ProtoActivity_database_Changed;
            this.protoActivity_database.TextChanged    += ProtoActivity_database_Changed;

            this.singleActivityButton          = new Button();
            this.singleActivityButton.Clicked += SingleActivityButton_Clicked;
            this.singleActivityLayout          = new ButtonLayout(this.singleActivityButton);

            this.invalidate();
        }
        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();
        }
Example #9
0
        public Full_RequestSuggestion_Layout(ActivityDatabase activityDatabase, bool allowRequestingActivitiesDirectly, bool allowMultipleSuggestionTypes, bool vertical,
                                             int numChoicesPerSuggestion, Engine engine, LayoutStack layoutStack)
        {
            this.numChoicesPerSuggestion = numChoicesPerSuggestion;
            Button suggestionButton = new Button();

            suggestionButton.Clicked += SuggestBestActivity_Clicked;
            ButtonLayout suggest_maxLongtermHappiness_button;

            if (allowMultipleSuggestionTypes)
            {
                suggest_maxLongtermHappiness_button = new ButtonLayout(suggestionButton, "Best");
            }
            else
            {
                suggest_maxLongtermHappiness_button = new ButtonLayout(suggestionButton, "Suggest");
            }
            LayoutChoice_Set suggestButton_layout;

            if (allowRequestingActivitiesDirectly)
            {
                GridLayout_Builder builder = new Vertical_GridLayout_Builder().Uniform().AddLayout(suggest_maxLongtermHappiness_button);
                if (allowMultipleSuggestionTypes)
                {
                    Button suggestionButton2 = new Button();
                    suggestionButton2.Clicked += SuggestMostLikelyActivity_Clicked;
                    ButtonLayout suggest_mostLikely_button = new ButtonLayout(suggestionButton2, "Most Likely");
                    builder.AddLayout(suggest_mostLikely_button);

                    Button suggestionButton3 = new Button();
                    suggestionButton3.Clicked += SuggestMostEfficientActivity_Clicked;
                    ButtonLayout suggest_mostEfficient_button = new ButtonLayout(suggestionButton3, "Most Future Efficiency");
                    builder.AddLayout(suggest_mostEfficient_button);
                }
                suggestButton_layout = builder.BuildAnyLayout();
            }
            else
            {
                suggestButton_layout = suggest_maxLongtermHappiness_button;
            }

            this.categoryBox = new ActivityNameEntryBox("Category:", activityDatabase, layoutStack);
            this.categoryBox.Placeholder("(Optional)");
            this.activityDatabase = activityDatabase;
            this.engine           = engine;
            this.layoutStack      = layoutStack;


            if (!allowRequestingActivitiesDirectly)
            {
                this.SubLayout = suggest_maxLongtermHappiness_button;
            }
            else
            {
                GridLayout configurationLayout = GridLayout.New(BoundProperty_List.Uniform(2), new BoundProperty_List(1), LayoutScore.Zero);
                configurationLayout.AddLayout(this.categoryBox);


                this.atLeastAsFunAs_button     = new Button();
                atLeastAsFunAs_button.Clicked += RequestAsFunAs_Button_Clicked;
                configurationLayout.AddLayout(new TitledControl("As fun as:", new ButtonLayout(atLeastAsFunAs_button)));

                if (vertical)
                {
                    GridLayout verticalContentLayout = GridLayout.New(new BoundProperty_List(2), new BoundProperty_List(1), LayoutScore.Get_UnCentered_LayoutScore(2));
                    verticalContentLayout.AddLayout(configurationLayout);
                    verticalContentLayout.AddLayout(suggestButton_layout);
                    this.SubLayout = verticalContentLayout;
                }
                else
                {
                    GridLayout horizontalContentLayout = GridLayout.New(new BoundProperty_List(1), new BoundProperty_List(2), LayoutScore.Get_UnCentered_LayoutScore(1));
                    horizontalContentLayout.AddLayout(suggestButton_layout);
                    horizontalContentLayout.AddLayout(configurationLayout);

                    this.SubLayout = horizontalContentLayout;
                }
                this.specify_AtLeastAsFunAs_Layout = new Specify_AtLeastAsFunAs_Layout(this.activityDatabase, this.layoutStack);
                this.update_atLeastAsFunAs_activity();
            }
        }
Example #10
0
        public ActivityCreationLayout(ActivityDatabase activityDatabase, LayoutStack layoutStack)
        {
            this.activityDatabase = activityDatabase;
            this.layoutStack      = layoutStack;

            this.SetTitle("New Activity");
            SingleSelect typeSelector = new SingleSelect("Type:", this.typeChoices);

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

            mainGrid.AddLayout(typeSelector);
            this.feedbackLayout = new TextblockLayout("", 18).AlignVertically(TextAlignment.Center);
            mainGrid.AddLayout(this.feedbackLayout);

            GridLayout bottomGrid = GridLayout.New(new BoundProperty_List(2), BoundProperty_List.Uniform(2), LayoutScore.Zero);

            mainGrid.AddLayout(bottomGrid);

            this.typePicker       = typeSelector;
            typeSelector.Updated += TypeSelector_Clicked;

            this.childNameBox = new ActivityNameEntryBox("Activity Name", activityDatabase, layoutStack, true);
            this.childNameBox.AutoAcceptAutocomplete = false;
            bottomGrid.AddLayout(this.childNameBox);

            this.parentNameBox = new ActivityNameEntryBox("Parent Name", activityDatabase, layoutStack);
            this.parentNameBox.AutoAcceptAutocomplete = false;
            // for first-time users, make it extra obvious that the root activity exists
            this.parentNameBox.autoselectRootActivity_if_noCustomActivities();
            bottomGrid.AddLayout(this.parentNameBox);

            this.okButton          = new Button();
            this.okButton.Clicked += OkButton_Clicked;
            bottomGrid.AddLayout(new ButtonLayout(this.okButton, "OK"));

            LayoutChoice_Set helpWindow = (new HelpWindowBuilder()).AddMessage("This screen is for you to enter activities to do, to use as future suggestions.")
                                          .AddMessage("In the left text box, choose a name for the activity.")
                                          .AddMessage("In the right text box, specify another activity to assign as its parent.")
                                          .AddMessage("For example, you might specify that Gaming is a child activity of the Fun activity. Grouping activities like this is helpful for two reasons. It gives " +
                                                      "ActivityRecommender more understanding about the relationships between activities and can help it to notice trends. It also means that you can later request a suggestion " +
                                                      "from within Activity \"Fun\" and ActivityRecommender will know what you mean, and might suggest \"Gaming\".")
                                          .AddMessage("If you haven't created the parent activity yet, you'll have to create it first. The only activity that exists at the beginning is the built-in activity " +
                                                      "named \"Activity\".")
                                          .AddMessage("While typing you can press Enter to fill in the autocomplete suggestion.")
                                          .AddMessage("If the thing you're creating is something you plan to do many times (or even if you want it to be able to be the parent of another Activity), then select the type " +
                                                      "Category. For example, Sleeping would be a Category.")
                                          .AddMessage("If the thing you're creating is something you plan to complete once and don't plan to do again, then select the type ToDo. For example, \"Reading " +
                                                      "ActivityRecommender's Built-In Features Overview\" would be a ToDo.")
                                          .AddMessage("If the thing you're creating is something measureable that you might try to solve repeatedly but in different ways, then select the type Problem. For example, " +
                                                      "\"Headache\" (or \"Fixing my Headache\") would be a Problem because it may be addressed in several ways: resting, drinking water, or adjusting your posture")
                                          .AddMessage("If the thing you're creating is something that solves a Problem, then select the type Category and choose the appropriate Problem as a parent. Note " +
                                                      "that there is also a choice named \"Solution\", which is another name for Category, to emphasize this.")
                                          .AddLayout(new CreditsButtonBuilder(layoutStack)
                                                     .AddContribution(ActRecContributor.AARON_SMITH, new DateTime(2019, 8, 17), "Suggested that if Activity is the only valid choice then it should autopopulate")
                                                     .AddContribution(ActRecContributor.DAGOBERT_RENOUF, new DateTime(2021, 06, 14), "Mentioned that it was difficult to determine how to create a new activity without " +
                                                                      "visual hierarchy among the elements on the screen")
                                                     .Build()
                                                     )
                                          .Build();

            HelpButtonLayout helpLayout = new HelpButtonLayout(helpWindow, layoutStack);

            bottomGrid.AddLayout(helpLayout);

            this.explainActivityType();

            this.SetContent(mainGrid);
        }
Example #11
0
        public ActivityNameEntryBox(string title, ActivityDatabase activityDatabase, LayoutStack layoutStack, bool createNewActivity = false, bool placeTitleAbove = true)
        {
            // some settings
            this.layoutStack               = layoutStack;
            this.AutoAcceptAutocomplete    = true;
            this.createNewActivity         = createNewActivity;
            this.activityDatabase          = activityDatabase;
            this.numAutocompleteRowsToShow = 1;

            // the box the user is typing in
            this.nameBox              = new Editor();
            this.nameBox.TextChanged += NameBox_TextChanged;
            this.nameBox_layout       = new TextboxLayout(this.nameBox);

            // "X"/"?" button for clearing text or getting help
            // We use one button for both purposes so that the layout doesn't relayout (and shift focus) when this button switches from one to the other
            this.sideButton          = new Button();
            this.sideButton.Clicked += SideButton_Clicked;
            this.sideButtonLayout    = new ButtonLayout(this.sideButton);

            // layouts controlling the alignment of the main text box and the side button
            this.sideLayout           = new ContainerLayout();
            this.sideLayout.SubLayout = this.sideButtonLayout;

            GridView   gridView = new GridView();
            GridLayout evenBox  = GridLayout.New(new BoundProperty_List(1), BoundProperty_List.WithRatios(new List <double>()
            {
                7, 1
            }), LayoutScore.Zero, 1, gridView);
            GridLayout unevenBox = GridLayout.New(new BoundProperty_List(1), new BoundProperty_List(2), LayoutScore.Get_UnCentered_LayoutScore(1), 1, gridView);

            evenBox.AddLayout(this.nameBox_layout);
            evenBox.AddLayout(this.sideLayout);
            unevenBox.AddLayout(this.nameBox_layout);
            unevenBox.AddLayout(this.sideLayout);
            this.nameBoxWithSideLayout = new LayoutUnion(evenBox, unevenBox);

            // the autocomplete above the text box
            this.autocompleteLayout = new TextblockLayout();
            this.autocompleteLayout.ScoreIfEmpty = false;

            // button that gives help with autocomplete
            this.helpWindow = new HelpWindowBuilder()
                              .AddMessage("This screen explains how to enter " + title + " in the previous screen. " +
                                          "If you haven't already created the activity that you want to enter here, you will have to go back and create it first in the Activities screen.")
                              .AddMessage("")
                              .AddMessage("To input an activity name, you may type it in using the letters on the keyboard.")
                              .AddMessage("While you do this, ActivityRecommender will try to guess which activity you mean, and " +
                                          "that autocomplete guess will appear above. If this autocomplete suggestion is what you want, then you can press " +
                                          "[enter] to use the autocomplete suggestion.")
                              .AddMessage("Autocomplete does not require you to type full words but it does require spaces between words.")
                              .AddMessage("Autocomplete does not require that you type letters using the correct case but it is more effective if you do.")
                              .AddMessage("Consider the following example:")
                              .AddMessage("If you have already entered an activity named \"Taking out the Garbage\", " +
                                          "here are some things you can type that might cause it to become the autocomplete suggestion:")
                              .AddMessage("Taking out the")
                              .AddMessage("Taking")
                              .AddMessage("out")
                              .AddMessage("Garbage")
                              .AddMessage("garbage")
                              .AddMessage("Taking o t G")
                              .AddMessage("T o t G")
                              .AddMessage("T")
                              .AddMessage("G")
                              .AddMessage("t")
                              .AddMessage("")
                              .AddMessage("Note, of course, that the longer and more unique your text, the more likely that it will be matched with the activity that you intend, rather than " +
                                          "with another activity, like for example, 'Talking on the Phone'")
                              .AddLayout(new CreditsButtonBuilder(layoutStack)
                                         .AddContribution(ActRecContributor.ANNI_ZHANG, new DateTime(2020, 6, 7), "Pointed out that completed ToDos should have a very low autocomplete priority")
                                         .Build()
                                         )
                              .Build();

            // help buttons that appear when the user types something invalid
            Button help_createNew_button = new Button();

            help_createNew_button.Clicked   += help_createNew_button_Clicked;
            this.autocomplete_longHelpLayout = new Horizontal_GridLayout_Builder().Uniform()
                                               .AddLayout(new ButtonLayout(help_createNew_button, "Create"))
                                               .AddLayout(new HelpButtonLayout(this.helpWindow, layoutStack))
                                               .Build();

            // the main layout that contains everything
            LayoutChoice_Set content;

            if (createNewActivity)
            {
                content = unevenBox;
            }
            else
            {
                GridLayout contentWithFeedback = GridLayout.New(new BoundProperty_List(2), new BoundProperty_List(1), LayoutScore.Get_UnCentered_LayoutScore(1));
                contentWithFeedback.AddLayout(this.responseLayout);
                contentWithFeedback.AddLayout(this.nameBoxWithSideLayout);

                content = contentWithFeedback;

                this.UpdateFeedback();
            }

            this.updateSideButton();

            TextblockLayout titleLayout = new TextblockLayout(title);

            titleLayout.AlignHorizontally(TextAlignment.Center);
            if (placeTitleAbove)
            {
                this.SubLayout = new Vertical_GridLayout_Builder()
                                 .AddLayout(titleLayout)
                                 .AddLayout(content)
                                 .Build();
            }
            else
            {
                GridLayout evenGrid   = GridLayout.New(new BoundProperty_List(1), BoundProperty_List.Uniform(2), LayoutScore.Zero);
                GridLayout unevenGrid = GridLayout.New(new BoundProperty_List(1), new BoundProperty_List(2), LayoutScore.Get_UnCentered_LayoutScore(1));
                evenGrid.AddLayout(titleLayout);
                unevenGrid.AddLayout(titleLayout);
                evenGrid.AddLayout(content);
                unevenGrid.AddLayout(content);
                this.SubLayout = new LayoutUnion(evenGrid, unevenGrid);
            }
        }
Example #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();
        }