github.com/wtfutil/wtf@v0.43.0/modules/mercurial/widget.go (about)

     1  package mercurial
     2  
     3  import (
     4  	"github.com/gdamore/tcell/v2"
     5  	"github.com/rivo/tview"
     6  	"github.com/wtfutil/wtf/utils"
     7  	"github.com/wtfutil/wtf/view"
     8  )
     9  
    10  const (
    11  	modalHeight = 7
    12  	modalWidth  = 80
    13  	offscreen   = -1000
    14  )
    15  
    16  // A Widget represents a Mercurial widget
    17  type Widget struct {
    18  	view.MultiSourceWidget
    19  	view.TextWidget
    20  
    21  	Data     []*MercurialRepo
    22  	pages    *tview.Pages
    23  	settings *Settings
    24  	tviewApp *tview.Application
    25  }
    26  
    27  // NewWidget creates a new instance of a widget
    28  func NewWidget(tviewApp *tview.Application, redrawChan chan bool, pages *tview.Pages, settings *Settings) *Widget {
    29  	widget := Widget{
    30  		MultiSourceWidget: view.NewMultiSourceWidget(settings.Common, "repository", "repositories"),
    31  		TextWidget:        view.NewTextWidget(tviewApp, redrawChan, pages, settings.Common),
    32  
    33  		tviewApp: tviewApp,
    34  		pages:    pages,
    35  		settings: settings,
    36  	}
    37  
    38  	widget.SetDisplayFunction(widget.display)
    39  
    40  	widget.initializeKeyboardControls()
    41  
    42  	return &widget
    43  }
    44  
    45  /* -------------------- Exported Functions -------------------- */
    46  
    47  func (widget *Widget) Checkout() {
    48  	form := widget.modalForm("Branch to checkout:", "")
    49  
    50  	checkoutFctn := func() {
    51  		text := form.GetFormItem(0).(*tview.InputField).GetText()
    52  		repoToCheckout := widget.Data[widget.Idx]
    53  		repoToCheckout.checkout(text)
    54  		widget.pages.RemovePage("modal")
    55  		widget.tviewApp.SetFocus(widget.View)
    56  
    57  		widget.display()
    58  
    59  		widget.Refresh()
    60  	}
    61  
    62  	widget.addButtons(form, checkoutFctn)
    63  	widget.modalFocus(form)
    64  }
    65  
    66  func (widget *Widget) Pull() {
    67  	repoToPull := widget.Data[widget.Idx]
    68  	repoToPull.pull()
    69  	widget.Refresh()
    70  }
    71  
    72  func (widget *Widget) Refresh() {
    73  	repoPaths := utils.ToStrs(widget.settings.repositories)
    74  
    75  	widget.Data = widget.mercurialRepos(repoPaths)
    76  
    77  	widget.display()
    78  }
    79  
    80  /* -------------------- Unexported Functions -------------------- */
    81  
    82  func (widget *Widget) addCheckoutButton(form *tview.Form, fctn func()) {
    83  	form.AddButton("Checkout", fctn)
    84  }
    85  
    86  func (widget *Widget) addButtons(form *tview.Form, checkoutFctn func()) {
    87  	widget.addCheckoutButton(form, checkoutFctn)
    88  	widget.addCancelButton(form)
    89  }
    90  
    91  func (widget *Widget) addCancelButton(form *tview.Form) {
    92  	cancelFn := func() {
    93  		widget.pages.RemovePage("modal")
    94  		widget.tviewApp.SetFocus(widget.View)
    95  		widget.display()
    96  	}
    97  
    98  	form.AddButton("Cancel", cancelFn)
    99  	form.SetCancelFunc(cancelFn)
   100  }
   101  
   102  func (widget *Widget) modalFocus(form *tview.Form) {
   103  	frame := widget.modalFrame(form)
   104  	widget.pages.AddPage("modal", frame, false, true)
   105  	widget.tviewApp.SetFocus(frame)
   106  }
   107  
   108  func (widget *Widget) modalForm(lbl, text string) *tview.Form {
   109  	form := tview.NewForm()
   110  	form.SetButtonsAlign(tview.AlignCenter)
   111  	form.SetButtonTextColor(tview.Styles.PrimaryTextColor)
   112  
   113  	form.AddInputField(lbl, text, 60, nil, nil)
   114  
   115  	return form
   116  }
   117  
   118  func (widget *Widget) modalFrame(form *tview.Form) *tview.Frame {
   119  	frame := tview.NewFrame(form)
   120  	frame.SetBorders(0, 0, 0, 0, 0, 0)
   121  	frame.SetRect(offscreen, offscreen, modalWidth, modalHeight)
   122  	frame.SetBorder(true)
   123  	frame.SetBorders(1, 1, 0, 0, 1, 1)
   124  
   125  	drawFunc := func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) {
   126  		w, h := screen.Size()
   127  		frame.SetRect((w/2)-(width/2), (h/2)-(height/2), width, height)
   128  		return x, y, width, height
   129  	}
   130  
   131  	frame.SetDrawFunc(drawFunc)
   132  
   133  	return frame
   134  }
   135  
   136  func (widget *Widget) currentData() *MercurialRepo {
   137  	if len(widget.Data) == 0 {
   138  		return nil
   139  	}
   140  
   141  	if widget.Idx < 0 || widget.Idx >= len(widget.Data) {
   142  		return nil
   143  	}
   144  
   145  	return widget.Data[widget.Idx]
   146  }
   147  
   148  func (widget *Widget) mercurialRepos(repoPaths []string) []*MercurialRepo {
   149  	repos := []*MercurialRepo{}
   150  
   151  	for _, repoPath := range repoPaths {
   152  		repo := NewMercurialRepo(repoPath, widget.settings.commitCount, widget.settings.commitFormat)
   153  		repos = append(repos, repo)
   154  	}
   155  
   156  	return repos
   157  }