github.com/df-mc/dragonfly@v0.9.13/server/player/form/element.go (about)

     1  package form
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  )
     7  
     8  // Element represents an element that may be added to a Form. Any of the types in this package that implement
     9  // the element interface may be used as struct fields when passing the form structure to form.New().
    10  type Element interface {
    11  	json.Marshaler
    12  	elem()
    13  }
    14  
    15  // Label represents a static label on a form. It serves only to display a box of text, and users cannot
    16  // submit values to it.
    17  type Label struct {
    18  	// Text is the text held by the label. The text may contain Minecraft formatting codes.
    19  	Text string
    20  }
    21  
    22  // NewLabel creates and returns a new Label with the values passed.
    23  func NewLabel(text string) Label {
    24  	return Label{Text: text}
    25  }
    26  
    27  // MarshalJSON ...
    28  func (l Label) MarshalJSON() ([]byte, error) {
    29  	return json.Marshal(map[string]any{
    30  		"type": "label",
    31  		"text": l.Text,
    32  	})
    33  }
    34  
    35  // Input represents a text input box element. Submitters may write any text in these boxes with no specific
    36  // length.
    37  type Input struct {
    38  	// Text is the text displayed over the input element. The text may contain Minecraft formatting codes.
    39  	Text string
    40  	// Default is the default value filled out in the input. The user may remove this value and fill out its
    41  	// own text. The text may contain Minecraft formatting codes.
    42  	Default string
    43  	// Placeholder is the text displayed in the input box if it does not contain any text filled out by the
    44  	// user. The text may contain Minecraft formatting codes.
    45  	Placeholder string
    46  
    47  	value string
    48  }
    49  
    50  // NewInput creates and returns a new Input with the values passed.
    51  func NewInput(text, defaultValue, placeholder string) Input {
    52  	return Input{Text: text, Default: defaultValue, Placeholder: placeholder}
    53  }
    54  
    55  // MarshalJSON ...
    56  func (i Input) MarshalJSON() ([]byte, error) {
    57  	return json.Marshal(map[string]any{
    58  		"type":        "input",
    59  		"text":        i.Text,
    60  		"default":     i.Default,
    61  		"placeholder": i.Placeholder,
    62  	})
    63  }
    64  
    65  // Value returns the value filled out by the user.
    66  func (i Input) Value() string {
    67  	return i.value
    68  }
    69  
    70  // Toggle represents an on-off button element. Submitters may either toggle this on or off, which will then
    71  // hold a value of true or false respectively.
    72  type Toggle struct {
    73  	// Text is the text displayed over the toggle element. The text may contain Minecraft formatting codes.
    74  	Text string
    75  	// Default is the default value filled out in the input. The user may remove this value and fill out its
    76  	// own text. The text may contain Minecraft formatting codes.
    77  	Default bool
    78  
    79  	value bool
    80  }
    81  
    82  // NewToggle creates and returns a new Toggle with the values passed.
    83  func NewToggle(text string, defaultValue bool) Toggle {
    84  	return Toggle{Text: text, Default: defaultValue}
    85  }
    86  
    87  // MarshalJSON ...
    88  func (t Toggle) MarshalJSON() ([]byte, error) {
    89  	return json.Marshal(map[string]any{
    90  		"type":    "toggle",
    91  		"text":    t.Text,
    92  		"default": t.Default,
    93  	})
    94  }
    95  
    96  // Value returns the value filled out by the user.
    97  func (t Toggle) Value() bool {
    98  	return t.value
    99  }
   100  
   101  // Slider represents a slider element. Submitters may move the slider to values within the range of the slider
   102  // to select a value.
   103  type Slider struct {
   104  	// Text is the text displayed over the slider element. The text may contain Minecraft formatting codes.
   105  	Text string
   106  	// Min and Max are used to specify the minimum and maximum range of the slider. A value lower or higher
   107  	// than these values cannot be selected.
   108  	Min, Max float64
   109  	// StepSize is the size that one step of the slider takes up. When set to 1.0 for example, a submitter
   110  	// will be able to select only whole values.
   111  	StepSize float64
   112  	// Default is the default value filled out for the slider.
   113  	Default float64
   114  
   115  	value float64
   116  }
   117  
   118  // NewSlider creates and returns a new Slider using the values passed.
   119  func NewSlider(text string, min, max, stepSize, defaultValue float64) Slider {
   120  	return Slider{Text: text, Min: min, Max: max, StepSize: stepSize, Default: defaultValue}
   121  }
   122  
   123  // MarshalJSON ...
   124  func (s Slider) MarshalJSON() ([]byte, error) {
   125  	return json.Marshal(map[string]any{
   126  		"type":    "slider",
   127  		"text":    s.Text,
   128  		"min":     s.Min,
   129  		"max":     s.Max,
   130  		"step":    s.StepSize,
   131  		"default": s.Default,
   132  	})
   133  }
   134  
   135  // Value returns the value filled out by the user.
   136  func (s Slider) Value() float64 {
   137  	return s.value
   138  }
   139  
   140  // Dropdown represents a dropdown which, when clicked, opens a window with the options set in the Options
   141  // field. Submitters may select one of the options.
   142  type Dropdown struct {
   143  	// Text is the text displayed over the dropdown element. The text may contain Minecraft formatting codes.
   144  	Text string
   145  	// Options holds a list of options that a Submitter may select. The order of these options is retained
   146  	// when shown to the submitter of the form.
   147  	Options []string
   148  	// DefaultIndex is the index in the Options slice that is used as default. When sent to a Submitter, the
   149  	// value at this index in the Options slice will be selected.
   150  	DefaultIndex int
   151  
   152  	value int
   153  }
   154  
   155  // NewDropdown creates and returns new Dropdown using the values passed.
   156  func NewDropdown(text string, options []string, defaultIndex int) Dropdown {
   157  	return Dropdown{Text: text, Options: options, DefaultIndex: defaultIndex}
   158  }
   159  
   160  // MarshalJSON ...
   161  func (d Dropdown) MarshalJSON() ([]byte, error) {
   162  	return json.Marshal(map[string]any{
   163  		"type":    "dropdown",
   164  		"text":    d.Text,
   165  		"default": d.DefaultIndex,
   166  		"options": d.Options,
   167  	})
   168  }
   169  
   170  // Value returns the value that the Submitter submitted. The value is an index pointing to the selected option
   171  // in the Options slice.
   172  func (d Dropdown) Value() int {
   173  	return d.value
   174  }
   175  
   176  // StepSlider represents a slider that has a number of options that may be selected. It is essentially a
   177  // combination of a Dropdown and a Slider, looking like a slider but having properties like a dropdown.
   178  type StepSlider Dropdown
   179  
   180  // NewStepSlider creates and returns new StepSlider using the values passed.
   181  func NewStepSlider(text string, options []string, defaultIndex int) StepSlider {
   182  	return StepSlider{Text: text, Options: options, DefaultIndex: defaultIndex}
   183  }
   184  
   185  // MarshalJSON ...
   186  func (s StepSlider) MarshalJSON() ([]byte, error) {
   187  	return json.Marshal(map[string]any{
   188  		"type":    "step_slider",
   189  		"text":    s.Text,
   190  		"default": s.DefaultIndex,
   191  		"steps":   s.Options,
   192  	})
   193  }
   194  
   195  // Value returns the value that the Submitter submitted. The value is an index pointing to the selected option
   196  // in the Options slice.
   197  func (s StepSlider) Value() int {
   198  	return s.value
   199  }
   200  
   201  // Button represents a button added to a Menu or Modal form. The button has text on it and an optional image,
   202  // which may be either retrieved from a website or the local assets of the game.
   203  type Button struct {
   204  	// Text holds the text displayed on the button. It may use Minecraft formatting codes and may have
   205  	// newlines.
   206  	Text string
   207  	// Image holds a path to an image for the button. The Image may either be a URL pointing to an image,
   208  	// such as 'https://someimagewebsite.com/someimage.png', or a path pointing to a local asset, such as
   209  	// 'textures/blocks/grass_carried'.
   210  	Image string
   211  }
   212  
   213  // NewButton creates and returns a new Button using the text and image passed.
   214  func NewButton(text, image string) Button {
   215  	return Button{Text: text, Image: image}
   216  }
   217  
   218  // MarshalJSON ...
   219  func (b Button) MarshalJSON() ([]byte, error) {
   220  	m := map[string]any{"text": b.Text}
   221  	if b.Image != "" {
   222  		buttonType := "path"
   223  		if strings.HasPrefix(b.Image, "http:") || strings.HasPrefix(b.Image, "https:") {
   224  			buttonType = "url"
   225  		}
   226  		m["image"] = map[string]any{"type": buttonType, "data": b.Image}
   227  	}
   228  	return json.Marshal(m)
   229  }
   230  
   231  func (Label) elem()      {}
   232  func (Input) elem()      {}
   233  func (Toggle) elem()     {}
   234  func (Slider) elem()     {}
   235  func (Dropdown) elem()   {}
   236  func (StepSlider) elem() {}