Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow SegmentedControl translate titles on the fly #720

Merged
merged 1 commit into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions ui/cryptomaterial/segmented_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ type SegmentedControl struct {
ContentPadding layout.Inset
Alignment layout.Alignment

selectedIndex int
segmentTitles []string
selectedIndex int
segmentTitlesTranslationKey []string

changed bool
mu sync.Mutex
Expand All @@ -52,23 +52,23 @@ type SegmentedControl struct {
}

// Segmented control is a linear set of two or more segments, each of which functions as a button.
func (t *Theme) SegmentedControl(segmentTitles []string, segmentType SegmentType) *SegmentedControl {
func (t *Theme) SegmentedControl(segmentTitlesTranslationKey []string, segmentType SegmentType) *SegmentedControl {
list := t.NewClickableList(layout.Horizontal)
list.IsHoverable = false

sc := &SegmentedControl{
list: list,
theme: t,
segmentTitles: segmentTitles,
leftNavBtn: t.NewClickable(false),
rightNavBtn: t.NewClickable(false),
leftNavBtnVisible: false,
rightNavBtnVisible: true,
isSwipeActionEnabled: true,
segmentType: segmentType,
slideAction: NewSlideAction(),
slideActionTitle: NewSlideAction(),
Padding: layout.UniformInset(values.MarginPadding8),
list: list,
theme: t,
segmentTitlesTranslationKey: segmentTitlesTranslationKey,
leftNavBtn: t.NewClickable(false),
rightNavBtn: t.NewClickable(false),
leftNavBtnVisible: false,
rightNavBtnVisible: true,
isSwipeActionEnabled: true,
segmentType: segmentType,
slideAction: NewSlideAction(),
slideActionTitle: NewSlideAction(),
Padding: layout.UniformInset(values.MarginPadding8),
ContentPadding: layout.Inset{
Top: values.MarginPadding14,
},
Expand Down Expand Up @@ -170,12 +170,12 @@ func (sc *SegmentedControl) GroupTileLayout(gtx C) D {
}.Layout(gtx,
layout.Rigid(func(gtx C) D {
return sc.slideActionTitle.DragLayout(gtx, func(gtx C) D {
return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D {
return sc.list.Layout(gtx, len(sc.segmentTitlesTranslationKey), func(gtx C, i int) D {
isSelectedSegment := sc.SelectedIndex() == i
textSize16 := values.TextSizeTransform(sc.isMobileView, values.TextSize16)
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.SurfaceHighlight
txt := sc.theme.DecoratedText(textSize16, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold)
txt := sc.theme.DecoratedText(textSize16, values.String(sc.segmentTitlesTranslationKey[i]), sc.theme.Color.GrayText1, font.SemiBold)
border := Border{Radius: Radius(0)}
if isSelectedSegment {
bg = sc.theme.Color.Surface
Expand Down Expand Up @@ -223,11 +223,11 @@ func (sc *SegmentedControl) splitTileLayout(gtx C) D {
return sc.leftNavBtn.Layout(gtx, sc.theme.NewIcon(sc.theme.Icons.ChevronLeft).Layout24dp)
}),
layout.Flexed(flexWidthCenter, func(gtx C) D {
return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D {
return sc.list.Layout(gtx, len(sc.segmentTitlesTranslationKey), func(gtx C, i int) D {
isSelectedSegment := sc.SelectedIndex() == i
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.Gray2
txt := sc.theme.DecoratedText(values.TextSize14, sc.segmentTitles[i], sc.theme.Color.GrayText2, font.SemiBold)
txt := sc.theme.DecoratedText(values.TextSize14, values.String(sc.segmentTitlesTranslationKey[i]), sc.theme.Color.GrayText2, font.SemiBold)
border := Border{Radius: Radius(8)}
if isSelectedSegment {
bg = sc.theme.Color.LightBlue8
Expand All @@ -237,7 +237,7 @@ func (sc *SegmentedControl) splitTileLayout(gtx C) D {
paddingTB := values.MarginPadding8
paddingLR := values.MarginPadding32
pr := values.MarginPadding6
if i == len(sc.segmentTitles) { // no need to add padding to the last item
if i == len(sc.segmentTitlesTranslationKey) { // no need to add padding to the last item
pr = values.MarginPadding0
}

Expand Down Expand Up @@ -283,11 +283,11 @@ func (sc *SegmentedControl) groupTileMaxLayout(gtx C) D {
layout.Rigid(func(gtx C) D {
textSize16 := values.TextSizeTransform(sc.isMobileView, values.TextSize16)
return sc.slideActionTitle.DragLayout(gtx, func(gtx C) D {
return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D {
return sc.list.Layout(gtx, len(sc.segmentTitlesTranslationKey), func(gtx C, i int) D {
isSelectedSegment := sc.SelectedIndex() == i
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.SurfaceHighlight
txt := sc.theme.DecoratedText(textSize16, sc.segmentTitles[i], sc.theme.Color.GrayText1, font.SemiBold)
txt := sc.theme.DecoratedText(textSize16, values.String(sc.segmentTitlesTranslationKey[i]), sc.theme.Color.GrayText1, font.SemiBold)
border := Border{Radius: Radius(0)}
if isSelectedSegment {
bg = sc.theme.Color.Surface
Expand All @@ -296,7 +296,7 @@ func (sc *SegmentedControl) groupTileMaxLayout(gtx C) D {
}
return LinearLayout{
// subtract padding on the x-axis values.MarginPadding4 x2
Width: (layoutSize - gtx.Dp(values.MarginPadding8)) / len(sc.segmentTitles),
Width: (layoutSize - gtx.Dp(values.MarginPadding8)) / len(sc.segmentTitlesTranslationKey),
Height: WrapContent,
Background: bg,
Border: border,
Expand All @@ -317,11 +317,11 @@ func (sc *SegmentedControl) dynamicSplitTileLayout(gtx C) D {
Height: WrapContent,
Orientation: layout.Horizontal,
}.Layout2(gtx, func(gtx C) D {
return sc.list.Layout(gtx, len(sc.segmentTitles), func(gtx C, i int) D {
return sc.list.Layout(gtx, len(sc.segmentTitlesTranslationKey), func(gtx C, i int) D {
isSelectedSegment := sc.SelectedIndex() == i
return layout.Center.Layout(gtx, func(gtx C) D {
bg := sc.theme.Color.Surface
txt := sc.theme.DecoratedText(values.TextSizeTransform(sc.isMobileView, values.TextSize14), sc.segmentTitles[i], sc.theme.Color.GrayText2, font.SemiBold)
txt := sc.theme.DecoratedText(values.TextSizeTransform(sc.isMobileView, values.TextSize14), values.String(sc.segmentTitlesTranslationKey[i]), sc.theme.Color.GrayText2, font.SemiBold)
border := Border{Radius: Radius(12), Color: sc.theme.Color.Gray10}
if isSelectedSegment {
bg = sc.theme.Color.Gray2
Expand All @@ -331,7 +331,7 @@ func (sc *SegmentedControl) dynamicSplitTileLayout(gtx C) D {
paddingTB := values.MarginPadding4
paddingLR := values.MarginPadding12
pr := values.MarginPadding6
if i == len(sc.segmentTitles) { // no need to add padding to the last item
if i == len(sc.segmentTitlesTranslationKey) { // no need to add padding to the last item
pr = values.MarginPadding0
}

Expand Down Expand Up @@ -388,7 +388,7 @@ func (sc *SegmentedControl) updateArrowVisibility() {
sc.leftNavBtnVisible = true
}

if sc.list.Position.First+sc.list.Position.Count >= len(sc.segmentTitles) {
if sc.list.Position.First+sc.list.Position.Count >= len(sc.segmentTitlesTranslationKey) {
sc.rightNavBtnVisible = false
} else {
sc.rightNavBtnVisible = true
Expand All @@ -404,7 +404,7 @@ func (sc *SegmentedControl) SelectedIndex() int {
func (sc *SegmentedControl) SelectedSegment() string {
sc.mu.Lock()
defer sc.mu.Unlock()
return sc.segmentTitles[sc.selectedIndex]
return sc.segmentTitlesTranslationKey[sc.selectedIndex]
}

func (sc *SegmentedControl) Changed() bool {
Expand All @@ -418,7 +418,7 @@ func (sc *SegmentedControl) Changed() bool {
func (sc *SegmentedControl) SetSelectedSegment(segment string) {
sc.mu.Lock()
defer sc.mu.Unlock()
for i, item := range sc.segmentTitles {
for i, item := range sc.segmentTitlesTranslationKey {
if item == segment {
sc.selectedIndex = i
break
Expand All @@ -427,7 +427,7 @@ func (sc *SegmentedControl) SetSelectedSegment(segment string) {
}

func (sc *SegmentedControl) handleActionEvent(isNext bool) {
l := len(sc.segmentTitles) - 1 // index starts at 0
l := len(sc.segmentTitlesTranslationKey) - 1 // index starts at 0
if isNext {
if sc.selectedIndex == l {
if !sc.allowCycle {
Expand Down
6 changes: 3 additions & 3 deletions ui/page/components/fee_rate_selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ func NewFeeRateSelector(l *load.Load, callback walletTypeCallbackFunc) *FeeRateS
fs.SaveRate = fs.Theme.Button(values.String(values.StrSave))

fs.feeRateSwitch = fs.Theme.SegmentedControl([]string{
values.String(values.StrFetched),
values.String(values.StrManual),
values.StrFetched,
values.StrManual,
}, cryptomaterial.SegmentTypeDynamicSplit)
fs.feeRateSwitch.SetEnableSwipe(false)
fs.feeRateSwitch.DisableUniform(true)
Expand Down Expand Up @@ -154,7 +154,7 @@ func (fs *FeeRateSelector) Layout(gtx C) D {
return layoutBody(gtx)
}

if fs.feeRateSwitch.SelectedSegment() == values.String(values.StrFetched) {
if fs.feeRateSwitch.SelectedSegment() == values.StrFetched {
fs.fetchedRatesDropDown.Width = gtx.Metric.PxToDp(gtx.Constraints.Max.X)
layoutBody = fs.fetchedRatesDropDown.Layout
}
Expand Down
4 changes: 2 additions & 2 deletions ui/page/components/restore_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
const CreateRestorePageID = "Restore"

var tabTitles = []string{
values.String(values.StrSeedWords),
values.String(values.StrHex),
values.StrSeedWords,
values.StrHex,
}

type Restore struct {
Expand Down
6 changes: 3 additions & 3 deletions ui/page/dcrdex/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ var (
}

buyAndSellBtnStrings = []string{
values.String(values.StrBuy),
values.String(values.StrSell),
values.StrBuy,
values.StrSell,
}

vertical = layout.Vertical
Expand Down Expand Up @@ -1983,7 +1983,7 @@ func (pg *DEXMarketPage) isMarketOrder() bool {
}

func (pg *DEXMarketPage) isSellOrder() bool {
return pg.toggleBuyAndSellBtn.SelectedSegment() == values.String(values.StrSell)
return pg.toggleBuyAndSellBtn.SelectedSegment() == values.StrSell
}

func (pg *DEXMarketPage) notifyError(errMsg string) {
Expand Down
6 changes: 3 additions & 3 deletions ui/page/exchange/trade_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ const (
var tab *cryptomaterial.SegmentedControl

var tabTitles = []string{
values.String(values.StrDcrDex),
values.String(values.StrCentralizedExchange),
values.String(values.StrTradeHistory),
values.StrDcrDex,
values.StrCentralizedExchange,
values.StrTradeHistory,
}

type TradePage struct {
Expand Down
6 changes: 3 additions & 3 deletions ui/page/governance/governance_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ type Page struct {
}

var governanceTabTitles = []string{
values.String(values.StrProposal),
values.String(values.StrConsensusChange),
values.String(values.StrTreasurySpending),
values.StrProposal,
values.StrConsensusChange,
values.StrTreasurySpending,
}

func NewGovernancePage(l *load.Load, detailData interface{}) *Page {
Expand Down
2 changes: 1 addition & 1 deletion ui/page/governance/proposal_vote_modal.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (vm *voteModal) Handle(gtx C) {
swmp := wallet.NewSingleWalletMasterPage(vm.Load, selectedWallet, walletCallbackFunc)
vm.ParentWindow().Display(swmp)
swmp.Display(staking.NewStakingPage(vm.Load, selectedWallet)) // Display staking page on the main page.]
swmp.PageNavigationTab.SetSelectedSegment(values.String(values.StrStaking))
swmp.PageNavigationTab.SetSelectedSegment(values.StrStaking)
}
}

Expand Down
2 changes: 1 addition & 1 deletion ui/page/root/overview_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func (pg *OverviewPage) HandleUserInteractions(gtx C) {
swmp := wallet.NewSingleWalletMasterPage(pg.Load, selectedWallet, walletCallbackFunc)
pg.ParentWindow().Display(swmp)
swmp.Display(privacy.NewAccountMixerPage(pg.Load, selectedWallet)) // Display mixer page on the main page.
swmp.PageNavigationTab.SetSelectedSegment(values.String(values.StrStakeShuffle))
swmp.PageNavigationTab.SetSelectedSegment(values.StrStakeShuffle)
}

for _, info := range pg.listInfoWallets {
Expand Down
6 changes: 3 additions & 3 deletions ui/page/send/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,19 @@ func (pg *Page) recipientsLayout(gtx C) D {
if pg.modalLayout == nil && len(pg.recipients) < 3 {
flexChilds = append(flexChilds, layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return layout.E.Layout(gtx, pg.addRecipentBtnLayout)
return layout.E.Layout(gtx, pg.addRecipientBtnLayout)
}))
}
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, flexChilds...)
})
}

func (pg *Page) addRecipentBtnLayout(gtx C) D {
func (pg *Page) addRecipientBtnLayout(gtx C) D {
return cryptomaterial.LinearLayout{
Width: cryptomaterial.WrapContent,
Height: cryptomaterial.WrapContent,
Background: pg.Theme.Color.SurfaceHighlight,
Clickable: pg.addRecipentBtn,
Clickable: pg.addRecipientBtn,
Alignment: layout.Middle,
}.Layout(gtx,
layout.Rigid(pg.Theme.AddIcon().Layout24dp),
Expand Down
10 changes: 5 additions & 5 deletions ui/page/send/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ type Page struct {

infoButton cryptomaterial.IconButton
// retryExchange cryptomaterial.Button // TODO not included in design
nextButton cryptomaterial.Button
closeButton cryptomaterial.Button
addRecipentBtn *cryptomaterial.Clickable
nextButton cryptomaterial.Button
closeButton cryptomaterial.Button
addRecipientBtn *cryptomaterial.Clickable

isFetchingExchangeRate bool

Expand Down Expand Up @@ -112,7 +112,7 @@ func NewSendPage(l *load.Load, wallet sharedW.Asset) *Page {
authoredTxData: &authoredTxData{},
exchangeRate: -1,
navigateToSyncBtn: l.Theme.Button(values.String(values.StrStartSync)),
addRecipentBtn: l.Theme.NewClickable(false),
addRecipientBtn: l.Theme.NewClickable(false),
recipients: make([]*recipient, 0),
}

Expand Down Expand Up @@ -645,7 +645,7 @@ func (pg *Page) HandleUserInteractions(gtx C) {
})
}

if pg.addRecipentBtn.Clicked(gtx) {
if pg.addRecipientBtn.Clicked(gtx) {
pg.addRecipient()
}

Expand Down
8 changes: 4 additions & 4 deletions ui/page/send/recipient.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,12 @@ func (rp *recipient) recipientLayout(index int, showIcon bool) layout.Widget {
}

if !rp.isSendToAddress() {
layoutBody = rp.walletAccountlayout()
layoutBody = rp.walletAccountLayout()
}

return rp.sendDestination.accountSwitch.Layout(gtx, layoutBody, rp.IsMobileView())
}),
layout.Rigid(rp.addressAndAmountlayout),
layout.Rigid(rp.addressAndAmountLayout),
layout.Rigid(rp.txLabelSection),
)
}
Expand All @@ -261,7 +261,7 @@ func (rp *recipient) topLayout(gtx C, index int) D {
)
}

func (rp *recipient) walletAccountlayout() layout.Widget {
func (rp *recipient) walletAccountLayout() layout.Widget {
return func(gtx C) D {
return cryptomaterial.LinearLayout{
Width: cryptomaterial.MatchParent,
Expand Down Expand Up @@ -299,7 +299,7 @@ func (rp *recipient) contentWrapper(gtx C, title string, content layout.Widget)
})
}

func (rp *recipient) addressAndAmountlayout(gtx C) D {
func (rp *recipient) addressAndAmountLayout(gtx C) D {
widget := func(gtx C) D { return rp.amount.amountEditor.Layout(gtx) }
if rp.pageParam().exchangeRate != -1 && rp.pageParam().usdExchangeSet {
widget = func(gtx C) D {
Expand Down
6 changes: 3 additions & 3 deletions ui/page/send/send_destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
)

var tabOptions = []string{
values.String(values.StrAddress),
values.String(values.StrWallets),
values.StrAddress,
values.StrWallets,
}

type destination struct {
Expand Down Expand Up @@ -167,7 +167,7 @@ func (dst *destination) clearAddressInput() {
// isSendToAddress returns the current tab selection status without depending
// on a buffered state.
func (dst *destination) isSendToAddress() bool {
return dst.accountSwitch.SelectedSegment() == values.String(values.StrAddress)
return dst.accountSwitch.SelectedSegment() == values.StrAddress
Comment on lines 169 to +170
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one case where the formal approach caused the send page to not function properly due to an incorrect equality check.

SelectedSegment() was returning a pre-translated string(english) and values.String(values.StrAddress) was returning the current string translation(e.g french) after a language change.

}

func (dst *destination) HandleDropdownInteraction(gtx C) {
Expand Down
8 changes: 4 additions & 4 deletions ui/page/transaction/transactions_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ type multiWalletTx struct {
}

var txTabs = []string{
values.String(values.StrTxRegular),
values.String(values.StrStakingTx),
values.StrTxRegular,
values.StrStakingTx,
}

// TransactionsPage shows transactions for a specific wallet or for all wallets.
Expand Down Expand Up @@ -189,7 +189,7 @@ func (pg *TransactionsPage) OnNavigatedTo() {
// display transactions for multiple wallets.
func (pg *TransactionsPage) initWalletSelector() {
pg.assetWallets = pg.AssetsManager.AllWallets()
if pg.txCategoryTab.SelectedSegment() != values.String(values.StrTxRegular) {
if pg.txCategoryTab.SelectedSegment() != values.StrTxRegular {
pg.assetWallets = pg.AssetsManager.AllDCRWallets()
}

Expand Down Expand Up @@ -240,7 +240,7 @@ func (pg *TransactionsPage) refreshAvailableTxType() {
settingCommonDropdown(pg.Theme, pg.statusDropDown)

// only show tx count for regular txs, not staking
if pg.txCategoryTab.SelectedSegment() == values.String(values.StrTxOverview) {
if pg.txCategoryTab.SelectedSegment() == values.StrTxOverview {
pg.showLoader = true

wallets := pg.assetWallets
Expand Down
Loading
Loading