package gui // viewGeneticReferencesGui.go implements pages to display information about genetic diseases and traits import "fyne.io/fyne/v2" import "fyne.io/fyne/v2/widget" import "fyne.io/fyne/v2/theme" import "fyne.io/fyne/v2/container" import "fyne.io/fyne/v2/layout" import "seekia/resources/geneticReferences/locusMetadata" import "seekia/resources/geneticReferences/traits" import "seekia/resources/geneticReferences/monogenicDiseases" import "seekia/resources/geneticReferences/polygenicDiseases" import "seekia/internal/helpers" import "strings" import "slices" import "errors" func setViewMonogenicDiseaseDetailsPage(window fyne.Window, diseaseName string, previousPage func()){ currentPage := func(){setViewMonogenicDiseaseDetailsPage(window, diseaseName, previousPage)} title := getPageTitleCentered("Monogenic Disease Details - " + diseaseName) backButton := getBackButtonCentered(previousPage) diseaseObject, err := monogenicDiseases.GetMonogenicDiseaseObject(diseaseName) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } diseaseGeneName := diseaseObject.GeneName diseaseIsDominantOrRecessive := diseaseObject.DominantOrRecessive diseaseDescription := diseaseObject.DiseaseDescription diseaseReferencesMap := diseaseObject.References diseaseNameLabel := widget.NewLabel("Disease Name:") diseaseNameText := getBoldLabel(diseaseName) diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer()) geneNameLabel := widget.NewLabel("Gene Name:") geneNameText := getBoldLabel(diseaseGeneName) geneNameRow := container.NewHBox(layout.NewSpacer(), geneNameLabel, geneNameText, layout.NewSpacer()) dominantOrRecessiveLabel := widget.NewLabel("Dominant or Recessive?:") dominantOrRecessiveText := getBoldLabel(diseaseIsDominantOrRecessive) dominantOrRecessiveRow := container.NewHBox(layout.NewSpacer(), dominantOrRecessiveLabel, dominantOrRecessiveText, layout.NewSpacer()) diseaseDescriptionTrimmed, _, err := helpers.TrimAndFlattenString(diseaseDescription, 10) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } diseaseDescriptionLabel := widget.NewLabel("Description:") diseaseDescriptionText := getBoldLabel(diseaseDescriptionTrimmed) viewDiseaseDescriptionButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){ setViewTextPage(window, "Disease Description", diseaseDescription, false, currentPage) }) diseaseDescriptionRow := container.NewHBox(layout.NewSpacer(), diseaseDescriptionLabel, diseaseDescriptionText, viewDiseaseDescriptionButton, layout.NewSpacer()) viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){ setViewGeneticAnalysisReferencesPage(window, "Monogenic Disease", diseaseReferencesMap, currentPage) })) page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), geneNameRow, widget.NewSeparator(), dominantOrRecessiveRow, widget.NewSeparator(), diseaseDescriptionRow, widget.NewSeparator(), viewReferencesButton) setPageContent(page, window) } func setViewMonogenicDiseaseVariantDetailsPage(window fyne.Window, diseaseName string, variantIdentifier string, previousPage func()){ currentPage := func(){setViewMonogenicDiseaseVariantDetailsPage(window, diseaseName, variantIdentifier, previousPage)} title := getPageTitleCentered("Viewing Monogenic Disease Variant Details") backButton := getBackButtonCentered(previousPage) diseaseNameLabel := widget.NewLabel("Disease Name:") diseaseNameText := getBoldLabel(diseaseName) diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer()) variantObject, err := monogenicDiseases.GetMonogenicDiseaseVariantObject(diseaseName, variantIdentifier) if (err != nil) { setErrorEncounteredPage(window, err, previousPage) return } variantNamesList := variantObject.VariantNames nucleotideChange := variantObject.NucleotideChange aminoAcidChange := variantObject.AminoAcidChange variantRSID := variantObject.VariantRSID variantEffectIsMild := variantObject.EffectIsMild referencesMap := variantObject.References variantRSIDsList := []int64{variantRSID} // We add aliases to variantRSIDsList anyAliasesExist, rsidAliasesList, err := locusMetadata.GetRSIDAliases(variantRSID) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } if (anyAliasesExist == true){ variantRSIDsList = append(variantRSIDsList, rsidAliasesList...) } getVariantNamesLabelText := func()string{ if(len(variantNamesList) == 1){ return "Variant Name:" } return "Variant Names:" } variantNamesLabelText := getVariantNamesLabelText() variantNamesListString := strings.Join(variantNamesList, ", ") variantNamesLabel := widget.NewLabel(variantNamesLabelText) variantNamesText := getBoldLabel(variantNamesListString) variantNamesRow := container.NewHBox(layout.NewSpacer(), variantNamesLabel, variantNamesText, layout.NewSpacer()) nucleotideChangeLabel := widget.NewLabel("Nucleotide Change:") nucleotideChangeText := getBoldLabel(nucleotideChange) nucleotideChangeRow := container.NewHBox(layout.NewSpacer(), nucleotideChangeLabel, nucleotideChangeText, layout.NewSpacer()) page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), variantNamesRow, widget.NewSeparator(), nucleotideChangeRow, widget.NewSeparator()) if (aminoAcidChange != ""){ aminoAcidChangeLabel := widget.NewLabel("Amino Acid Change:") aminoAcidChangeText := getBoldLabel(aminoAcidChange) aminoAcidChangeRow := container.NewHBox(layout.NewSpacer(), aminoAcidChangeLabel, aminoAcidChangeText, layout.NewSpacer()) page.Add(aminoAcidChangeRow) page.Add(widget.NewSeparator()) } getVariantRSIDsLabelText := func()string{ if (len(variantRSIDsList) == 1){ return "Variant rsID:" } return "Variant rsIDs:" } variantRSIDsLabelText := getVariantRSIDsLabelText() variantRSIDStringsList := make([]string, 0, len(variantRSIDsList)) for _, variantRSID := range variantRSIDsList{ variantRSIDString := helpers.ConvertInt64ToString(variantRSID) variantRSIDName := "rs" + variantRSIDString variantRSIDStringsList = append(variantRSIDStringsList, variantRSIDName) } variantRSIDsListString := strings.Join(variantRSIDStringsList, ", ") variantRSIDsLabel := widget.NewLabel(variantRSIDsLabelText) variantRSIDsText := getBoldLabel(variantRSIDsListString) variantRSIDsRow := container.NewHBox(layout.NewSpacer(), variantRSIDsLabel, variantRSIDsText, layout.NewSpacer()) page.Add(variantRSIDsRow) page.Add(widget.NewSeparator()) effectIsMildString := helpers.ConvertBoolToYesOrNoString(variantEffectIsMild) effectIsMildLabel := widget.NewLabel("Effect is Mild:") effectIsMildText := getBoldLabel(effectIsMildString) effectIsMildHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){ setVariantEffectIsMildExplainerPage(window, currentPage) }) effectIsMildRow := container.NewHBox(layout.NewSpacer(), effectIsMildLabel, effectIsMildText, effectIsMildHelpButton, layout.NewSpacer()) page.Add(effectIsMildRow) page.Add(widget.NewSeparator()) viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){ setViewGeneticAnalysisReferencesPage(window, "Variant", referencesMap, currentPage) })) page.Add(viewReferencesButton) setPageContent(page, window) } func setViewPolygenicDiseaseDetailsPage(window fyne.Window, diseaseName string, previousPage func()){ currentPage := func(){setViewPolygenicDiseaseDetailsPage(window, diseaseName, previousPage)} title := getPageTitleCentered("Disease Details - " + diseaseName) backButton := getBackButtonCentered(previousPage) diseaseObject, err := polygenicDiseases.GetPolygenicDiseaseObject(diseaseName) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } diseaseDescription := diseaseObject.DiseaseDescription effectedSex := diseaseObject.EffectedSex diseaseReferencesMap := diseaseObject.References diseaseNameLabel := widget.NewLabel("Disease Name:") diseaseNameText := getBoldLabel(diseaseName) diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer()) getEffectedSexTextLabelText := func()string{ if (effectedSex == "Both"){ return "Male and Female" } return effectedSex } effectedSexTextLabelText := getEffectedSexTextLabelText() effectedSexLabel := widget.NewLabel("Effected Sex:") effectedSexText := getBoldLabel(effectedSexTextLabelText) effectedSexRow := container.NewHBox(layout.NewSpacer(), effectedSexLabel, effectedSexText, layout.NewSpacer()) diseaseDescriptionTrimmed, _, err := helpers.TrimAndFlattenString(diseaseDescription, 10) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } diseaseDescriptionLabel := widget.NewLabel("Description:") diseaseDescriptionText := getBoldLabel(diseaseDescriptionTrimmed) viewDiseaseDescriptionButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){ setViewTextPage(window, "Disease Description", diseaseDescription, false, currentPage) }) diseaseDescriptionRow := container.NewHBox(layout.NewSpacer(), diseaseDescriptionLabel, diseaseDescriptionText, viewDiseaseDescriptionButton, layout.NewSpacer()) viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){ setViewGeneticAnalysisReferencesPage(window, "Polygenic Disease", diseaseReferencesMap, currentPage) })) page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), effectedSexRow, widget.NewSeparator(), diseaseDescriptionRow, widget.NewSeparator(), viewReferencesButton) setPageContent(page, window) } func setViewGeneticAnalysisReferencesPage(window fyne.Window, referencesTopic string, referencesMap map[string]string, previousPage func()){ currentPage := func(){setViewGeneticAnalysisReferencesPage(window, referencesTopic, referencesMap, previousPage)} pageTitle := "Viewing " + referencesTopic + " References" title := getPageTitleCentered(pageTitle) backButton := getBackButtonCentered(previousPage) referencesContainer := container.NewVBox() referenceNamesList := helpers.GetListOfMapKeys(referencesMap) // We sort the references so they always show up in the same order slices.Sort(referenceNamesList) for index, referenceName := range referenceNamesList{ referenceLink, exists := referencesMap[referenceName] if (exists == false){ setErrorEncounteredPage(window, errors.New("referencesMap missing referenceName"), previousPage) return } indexString := helpers.ConvertIntToString(index+1) indexLabel := getBoldLabel(indexString + ".") referenceNameTrimmed, _, err := helpers.TrimAndFlattenString(referenceName, 35) if (err != nil) { setErrorEncounteredPage(window, err, previousPage) return } referenceNameLabel := getItalicLabel(referenceNameTrimmed) referenceViewNameButton := widget.NewButtonWithIcon("View Name", theme.VisibilityIcon(), func(){ setViewTextPage(window, "Viewing Reference Name", referenceName, false, currentPage) }) referenceLinkButton := widget.NewButtonWithIcon("View Link", theme.VisibilityIcon(), func(){ setViewLinkPage(window, "Viewing Reference Link", referenceLink, currentPage) }) referenceRow := container.NewHBox(layout.NewSpacer(), indexLabel, referenceNameLabel, referenceViewNameButton, referenceLinkButton, layout.NewSpacer()) referencesContainer.Add(referenceRow) referencesContainer.Add(widget.NewSeparator()) } page := container.NewVBox(title, backButton, widget.NewSeparator(), referencesContainer) setPageContent(page, window) } func setViewTraitDetailsPage(window fyne.Window, traitName string, previousPage func()){ currentPage := func(){setViewTraitDetailsPage(window, traitName, previousPage)} title := getPageTitleCentered("Trait Details - " + traitName) backButton := getBackButtonCentered(previousPage) traitObject, err := traits.GetTraitObject(traitName) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } traitDescription := traitObject.TraitDescription traitReferencesMap := traitObject.ReferencesMap traitNameLabel := widget.NewLabel("Trait Name:") traitNameText := getBoldLabel(traitName) traitNameRow := container.NewHBox(layout.NewSpacer(), traitNameLabel, traitNameText, layout.NewSpacer()) traitDescriptionTrimmed, _, err := helpers.TrimAndFlattenString(traitDescription, 10) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } traitDescriptionLabel := widget.NewLabel("Description:") traitDescriptionText := getBoldLabel(traitDescriptionTrimmed) viewTraitDescriptionButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){ setViewTextPage(window, "Trait Description", traitDescription, false, currentPage) }) traitDescriptionRow := container.NewHBox(layout.NewSpacer(), traitDescriptionLabel, traitDescriptionText, viewTraitDescriptionButton, layout.NewSpacer()) viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){ setViewGeneticAnalysisReferencesPage(window, "Trait", traitReferencesMap, currentPage) })) page := container.NewVBox(title, backButton, widget.NewSeparator(), traitNameRow, widget.NewSeparator(), traitDescriptionRow, widget.NewSeparator(), viewReferencesButton) setPageContent(page, window) } func setViewDiscreteTraitRuleDetailsPage(window fyne.Window, traitName string, ruleIdentifier string, previousPage func()){ currentPage := func(){setViewDiscreteTraitRuleDetailsPage(window, traitName, ruleIdentifier, previousPage)} title := getPageTitleCentered("Viewing Rule Details") backButton := getBackButtonCentered(previousPage) traitNameLabel := widget.NewLabel("Trait Name:") traitNameText := getBoldLabel(traitName) traitNameRow := container.NewHBox(layout.NewSpacer(), traitNameLabel, traitNameText, layout.NewSpacer()) ruleIdentifierLabel := widget.NewLabel("Rule Identifier:") ruleIdentifierText := getBoldLabel(ruleIdentifier) ruleIdentifierRow := container.NewHBox(layout.NewSpacer(), ruleIdentifierLabel, ruleIdentifierText, layout.NewSpacer()) traitRuleObject, err := traits.GetTraitRuleObject(traitName, ruleIdentifier) if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } ruleOutcomePointsMap := traitRuleObject.OutcomePointsMap ruleReferencesMap := traitRuleObject.ReferencesMap viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){ setViewGeneticAnalysisReferencesPage(window, "Rule", ruleReferencesMap, currentPage) })) ruleEffectsLabel := getBoldLabelCentered("Rule Effects:") getRuleEffectsGrid := func()(*fyne.Container, error){ outcomeNameLabel := getItalicLabelCentered("Outcome Name") outcomeEffectLabel := getItalicLabelCentered("Outcome Effect") outcomeNameColumn := container.NewVBox(outcomeNameLabel, widget.NewSeparator()) outcomeEffectColumn := container.NewVBox(outcomeEffectLabel, widget.NewSeparator()) for outcomeName, outcomePointsEffect := range ruleOutcomePointsMap{ outcomeNameLabel := getBoldLabelCentered(outcomeName) getOutcomeEffect := func()string{ outcomePointsEffectString := helpers.ConvertIntToString(outcomePointsEffect) if (outcomePointsEffect < 0){ return outcomePointsEffectString } outcomeEffect := "+" + outcomePointsEffectString return outcomeEffect } outcomeEffect := getOutcomeEffect() outcomeEffectLabel := getBoldLabelCentered(outcomeEffect) outcomeNameColumn.Add(outcomeNameLabel) outcomeEffectColumn.Add(outcomeEffectLabel) outcomeNameColumn.Add(widget.NewSeparator()) outcomeEffectColumn.Add(widget.NewSeparator()) } outcomeEffectHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){ setDiscreteTraitRuleOutcomeEffectsExplainerPage(window, currentPage) }) outcomeEffectColumn.Add(outcomeEffectHelpButton) ruleEffectsGrid := container.NewHBox(layout.NewSpacer(), outcomeNameColumn, outcomeEffectColumn, layout.NewSpacer()) return ruleEffectsGrid, nil } ruleEffectsGrid, err := getRuleEffectsGrid() if (err != nil){ setErrorEncounteredPage(window, err, previousPage) return } page := container.NewVBox(title, backButton, widget.NewSeparator(), traitNameRow, widget.NewSeparator(), ruleIdentifierRow, widget.NewSeparator(), viewReferencesButton, widget.NewSeparator(), ruleEffectsLabel, ruleEffectsGrid) setPageContent(page, window) }