Class: Zif::UI::Label

Inherits:
Object
  • Object
show all
Includes:
Actions::Actionable
Defined in:
lib/zif/ui/label.rb

Overview

A basic label which is aware of it’s size and can be truncated

Direct Known Subclasses

ExampleApp::FutureLabel, Input

Constant Summary collapse

MAGIC_NEWLINE_DELIMITER =
'+newline+'.freeze
ALIGNMENT =
{
  left:   0,
  center: 1,
  right:  2
}.freeze
VERTICAL_ALIGNMENT =
{
  bottom: 0,
  center: 1,
  top:    2
}.freeze
BLENDMODE =
{
  none:     0,
  alpha:    1,
  add:      2,
  mod:      3,
  multiply: 4
}.freeze

Instance Attribute Summary collapse

Attributes included from Actions::Actionable

#actions, #dirty

Instance Method Summary collapse

Methods included from Actions::Actionable

#bounce_forever_around, #delayed_action, #fade_in, #fade_out, #fade_out_and_in_forever, #new_action, #perform_actions, #run_action, #running_actions?, #stop_action

Constructor Details

#initialize(text = '', size: -1,, alignment: :left, vertical_alignment: :top, font: 'font.tff', ellipsis: '…', r: 51, g: 51, b: 51, a: 255, blend: :alpha) ⇒ Label

Returns a new instance of Label.

Parameters:

  • text (String) (defaults to: '')
  • size (Integer) (defaults to: -1,)
  • alignment (Symbol, Integer) (defaults to: :left)

    #align :left, :center, :right or 0, 1, 2. See ALIGNMENT

  • vertical_alignment (Symbol, Integer) (defaults to: :top)

    #vertical_align :bottom, :center, :top or 0, 1, 2. See VERTICAL_ALIGNMENT

  • font (String) (defaults to: 'font.tff')
  • ellipsis (String) (defaults to: '…')
  • r (Integer) (defaults to: 51)

    #r

  • g (Integer) (defaults to: 51)

    #g

  • b (Integer) (defaults to: 51)

    #b

  • a (Integer) (defaults to: 255)

    #a

  • blend (Symbol, Integer) (defaults to: :alpha)

    #blend :none, :alpha, :add, :mod, :multiply or 0, 1, 2, 3, 4. See BLENDMODE



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/zif/ui/label.rb', line 75

def initialize(
  text='',
  size:               -1,
  alignment:          :left,
  vertical_alignment: :top,
  font:               'font.tff',
  ellipsis:           '',
  r:                  51,
  g:                  51,
  b:                  51,
  a:                  255,
  blend:              :alpha
)
  @text               = text
  @full_text          = text
  @size               = size
  @ellipsis           = ellipsis
  @font               = font
  @r                  = r
  @g                  = g
  @b                  = b
  @a                  = a
  self.blend          = blend
  self.align          = alignment
  self.vertical_align = vertical_alignment
  recalculate_minimums
end

Instance Attribute Details

#aNumeric

Returns Alpha channel (Transparency) (0-255).

Returns:

  • (Numeric)

    Alpha channel (Transparency) (0-255)



40
41
42
# File 'lib/zif/ui/label.rb', line 40

def a
  @a
end

#anchor_xNumeric

Returns Anchor X for rendering relative to width; default ‘nil` (same as 0.0). Set to 0.5 to center horziontally, for example.

Returns:

  • (Numeric)

    Anchor X for rendering relative to width; default ‘nil` (same as 0.0). Set to 0.5 to center horziontally, for example.



60
61
62
# File 'lib/zif/ui/label.rb', line 60

def anchor_x
  @anchor_x
end

#anchor_yNumeric

Returns Anchor Y for rendering relative to height; default ‘nil` (same as 0.0). Set to 0.5 to center vertically, for example.

Returns:

  • (Numeric)

    Anchor Y for rendering relative to height; default ‘nil` (same as 0.0). Set to 0.5 to center vertically, for example.



62
63
64
# File 'lib/zif/ui/label.rb', line 62

def anchor_y
  @anchor_y
end

#bNumeric

Returns Blue color (0-255).

Returns:

  • (Numeric)

    Blue color (0-255)



38
39
40
# File 'lib/zif/ui/label.rb', line 38

def b
  @b
end

#ellipsisString

Returns A character to use to indicate the text has been truncated.

Returns:

  • (String)

    A character to use to indicate the text has been truncated



54
55
56
# File 'lib/zif/ui/label.rb', line 54

def ellipsis
  @ellipsis
end

#fontString

Returns Path to the font file.

Returns:

  • (String)

    Path to the font file



56
57
58
# File 'lib/zif/ui/label.rb', line 56

def font
  @font
end

#full_textString

Returns The complete text of the label before truncation.

Returns:

  • (String)

    The complete text of the label before truncation



42
43
44
# File 'lib/zif/ui/label.rb', line 42

def full_text
  @full_text
end

#gNumeric

Returns Green color (0-255).

Returns:

  • (Numeric)

    Green color (0-255)



36
37
38
# File 'lib/zif/ui/label.rb', line 36

def g
  @g
end

#max_widthInteger (readonly)

Returns The maximum width of the full text.

Returns:

  • (Integer)

    The maximum width of the full text



46
47
48
# File 'lib/zif/ui/label.rb', line 46

def max_width
  @max_width
end

#min_heightInteger (readonly)

Returns The minimum height of the text truncated down to just the ellipsis.

Returns:

  • (Integer)

    The minimum height of the text truncated down to just the ellipsis



50
51
52
# File 'lib/zif/ui/label.rb', line 50

def min_height
  @min_height
end

#min_widthInteger (readonly)

Returns The minimum width of the text truncated down to just the ellipsis.

Returns:

  • (Integer)

    The minimum width of the text truncated down to just the ellipsis



48
49
50
# File 'lib/zif/ui/label.rb', line 48

def min_width
  @min_width
end

#rNumeric

Returns Red color (0-255).

Returns:

  • (Numeric)

    Red color (0-255)



34
35
36
# File 'lib/zif/ui/label.rb', line 34

def r
  @r
end

#sizeInteger Also known as: size_enum

Returns The size value to render the text at.

Returns:

  • (Integer)

    The size value to render the text at



52
53
54
# File 'lib/zif/ui/label.rb', line 52

def size
  @size
end

#size_pxNumeric

Returns Font size in pixels; overrides size_enum if both are provided.

Returns:

  • (Numeric)

    Font size in pixels; overrides size_enum if both are provided



58
59
60
# File 'lib/zif/ui/label.rb', line 58

def size_px
  @size_px
end

#textString

Returns The current visible text of the label.

Returns:

  • (String)

    The current visible text of the label



44
45
46
# File 'lib/zif/ui/label.rb', line 44

def text
  @text
end

#xNumeric

Returns X axis position.

Returns:

  • (Numeric)

    X axis position



30
31
32
# File 'lib/zif/ui/label.rb', line 30

def x
  @x
end

#yNumeric

Returns Y axis position.

Returns:

  • (Numeric)

    Y axis position



32
33
34
# File 'lib/zif/ui/label.rb', line 32

def y
  @y
end

Instance Method Details

#alignInteger Also known as: alignment_enum

Returns The integer value for the specified alignment. See ALIGNMENT.

Examples:

This always returns an integer, even if you set it using a symbol

mylabel.align = :center # => 1
mylabel.align           # => 1

Returns:

  • (Integer)

    The integer value for the specified alignment. See ALIGNMENT



119
120
121
# File 'lib/zif/ui/label.rb', line 119

def align
  @alignment
end

#align=(new_alignment) ⇒ Integer

Set alignment using either symbol names or the enum integer values.

Parameters:

  • new_alignment (Symbol, Integer)

    #align :left, :center, :right or 0, 1, 2. See ALIGNMENT

Returns:

  • (Integer)

    The integer value for the specified alignment



111
112
113
# File 'lib/zif/ui/label.rb', line 111

def align=(new_alignment)
  @alignment = ALIGNMENT.fetch(new_alignment, new_alignment)
end

#blendInteger Also known as: blendmode_enum

Returns The integer value for the specified blend mode. See BLENDMODE.

Examples:

This always returns an integer, even if you set it using a symbol

mylabel.blend = :alpha  # => 1
mylabel.blend           # => 1

Returns:

  • (Integer)

    The integer value for the specified blend mode. See BLENDMODE



142
143
144
# File 'lib/zif/ui/label.rb', line 142

def blend
  @blendmode
end

#blend=(new_blendmode) ⇒ Integer

Set blend mode using either symbol names or the enum integer values.

Parameters:

  • new_blendmode (Symbol, Integer)

    #blend :none, :alpha, :add, :mod, :multiply or 0, 1, 2, 3, 4. See BLENDMODE

Returns:

  • (Integer)

    The integer value for the specified blend mode



134
135
136
# File 'lib/zif/ui/label.rb', line 134

def blend=(new_blendmode)
  @blendmode = BLENDMODE.fetch(new_blendmode, new_blendmode)
end

#colorHash<Symbol, Numeric>

Returns r: #r, g: #g, b: #b, a: #a.

Returns:

  • (Hash<Symbol, Numeric>)

    r: #r, g: #g, b: #b, a: #a



206
207
208
209
210
211
212
213
# File 'lib/zif/ui/label.rb', line 206

def color
  {
    r: @r,
    g: @g,
    b: @b,
    a: @a
  }
end

#color=(rgba_array = []) ⇒ Object

Note:

Use #assign if you want to assign with a hash. This works with positional array.

Parameters:

  • rgba_array (Array<Numeric>) (defaults to: [])

    [r, g, b, a]. If any entry is nil, assignment is skipped.



217
218
219
220
221
222
# File 'lib/zif/ui/label.rb', line 217

def color=(rgba_array=[])
  @r = rgba_array[0] if rgba_array[0]
  @g = rgba_array[1] if rgba_array[1]
  @b = rgba_array[2] if rgba_array[2]
  @a = rgba_array[3] if rgba_array[3]
end

#full_size_rectArray<Integer>

Returns 2-element array [w, h] of the full sized text.

Returns:

  • (Array<Integer>)

    2-element array [w, h] of the full sized text



158
159
160
# File 'lib/zif/ui/label.rb', line 158

def full_size_rect
  $gtk.calcstringbox(@full_text, @size, @font).map(&:round)
end

#primitive_markerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



293
294
295
# File 'lib/zif/ui/label.rb', line 293

def primitive_marker
  :label
end

#recalculate_minimumsObject

Recalculate #min_width #max_width #min_height You should invoke this if the text is changing & you care about truncation



164
165
166
167
# File 'lib/zif/ui/label.rb', line 164

def recalculate_minimums
  @min_width, @min_height = $gtk.calcstringbox(@ellipsis, @size, @font)
  @max_width, = full_size_rect
end

#recenter_in(w, h, offset: 0) ⇒ Object

Reposition #x and #y to center the text

Parameters:

  • w (Integer)

    Width

  • h (Integer)

    Height

  • offset (Integer) (defaults to: 0)

    Y-Offset



200
201
202
203
# File 'lib/zif/ui/label.rb', line 200

def recenter_in(w, h, offset: 0)
  @x = w.idiv(2)
  @y = (h + min_height).idiv(2) + offset
end

#rectArray<Integer>

Returns 2-element array [w, h] of the current text.

Returns:

  • (Array<Integer>)

    2-element array [w, h] of the current text



153
154
155
# File 'lib/zif/ui/label.rb', line 153

def rect
  $gtk.calcstringbox(@text, @size, @font).map(&:round)
end

#retruncate(width) ⇒ Object

Recalculate minimums and then truncate



191
192
193
194
# File 'lib/zif/ui/label.rb', line 191

def retruncate(width)
  recalculate_minimums
  truncate(width)
end

#rightInteger

Returns right edge of the label’s current size

Returns:

  • (Integer)

    Returns right edge of the label’s current size



272
273
274
# File 'lib/zif/ui/label.rb', line 272

def right
  x + rect[0]
end

#split_labels(label, a, b, width, height) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/zif/ui/label.rb', line 277

def split_labels(label, a, b, width, height)
  label.text = a
  label.recalculate_minimums
  label.truncate(width)

  old_y = label.y

  b_label = dup
  b_label.text = b
  b_label.recalculate_minimums
  b_label.truncate(width)
  b_label.y = old_y - height
  [label, b_label]
end

#truncate(width) ⇒ Object

Determine the largest possible portion of the text we can display End the text with an ellispsis if truncation occurs

Parameters:

  • width (Integer)

    The allowable width of the text, will be truncated until it fits



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/zif/ui/label.rb', line 172

def truncate(width)
  if @max_width <= width
    @text = @full_text
    return
  end

  (@full_text.length - 1).downto 0 do |i|
    truncated = "#{@full_text[0..i]}#{@ellipsis}"
    cur_width, = $gtk.calcstringbox(truncated, @size, @font)
    if cur_width <= width
      @text = truncated
      return # rubocop:disable Lint/NonLocalExitFromIterator
    end
  end

  @text = ''
end

#vertical_alignObject Also known as: vertical_alignment_enum



127
128
129
# File 'lib/zif/ui/label.rb', line 127

def vertical_align
  @vertical_alignment
end

#vertical_align=(new_alignment) ⇒ Object



123
124
125
# File 'lib/zif/ui/label.rb', line 123

def vertical_align=(new_alignment)
  @vertical_alignment = VERTICAL_ALIGNMENT.fetch(new_alignment, new_alignment)
end

#wrap(width, indent: '') ⇒ Array<Zif::UI::Label] An array of new labels for this text

Converts this label into a list of new labels for individual lines which can fit inside the given width.

Parameters:

  • width (Integer)

    The maximum width per line

Returns:

  • (Array<Zif::UI::Label] An array of new labels for this text)

    Array<Zif::UI::Label] An array of new labels for this text



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/zif/ui/label.rb', line 227

def wrap(width, indent: '')
  return [self] unless @full_text.length.positive?

  words = @full_text.gsub('\\', '').gsub("\n", MAGIC_NEWLINE_DELIMITER).split(' ')
  new_labels = []
  cur_label = dup
  cur_label.text = ''

  while words.any?
    finish_line = false
    cur_word = words.shift

    # If this word contains newlines, split into new words and add the extras back to 'words'
    cur_word, remainder = cur_word.split(MAGIC_NEWLINE_DELIMITER, 2)
    if remainder
      finish_line = true
      words.unshift(remainder)
    end

    existing_text = cur_label.text
    cur_label.text = existing_text + (existing_text == '' ? '' : ' ') + cur_word unless cur_word.nil?
    cur_label.recalculate_minimums
    cur_rect = cur_label.rect
    if cur_rect[0] > width
      if existing_text == ''
        cur_label.truncate(width)
      else
        old_label, cur_label = split_labels(cur_label, existing_text, indent + cur_word, width, cur_rect[1])
        new_labels << old_label
      end
    end
    if finish_line
      old_label, cur_label = split_labels(cur_label, cur_label.text, '', width, cur_rect[1])
      new_labels << old_label
    end
  end

  cur_label.recalculate_minimums
  cur_label.truncate(width)
  new_labels << cur_label

  new_labels
end