Class: Clogs::ListBox

Inherits:
Control show all
Defined in:
lib/clogs/drawables/controls.rb

Overview

A drop-down list. libui's combobox is a real native control, but it cannot live inside an area, so the popup is drawn as an overlay on the same canvas.

Constant Summary collapse

ROW_HEIGHT =
22

Constants inherited from Control

Control::PADDING_X, Control::PADDING_Y

Instance Attribute Summary

Attributes inherited from Control

#focused, #hovered, #pressed

Attributes inherited from Drawable

#abs_x, #abs_y, #children, #height, #parent, #shoes_linkable_id, #styles, #width, #x, #y

Instance Method Summary collapse

Methods inherited from Control

#clickable?, #label, #on_mouse_enter, #on_mouse_leave, #text_style

Methods inherited from Drawable

#add_child, #app, #clickable?, #contains?, #destroy_self, #each_peer, #focus_gained, #focus_lost, #focusable?, for_shoes_class, #hidden?, #initialize, #margin, #needs_layout!, #notify, #on_key, #on_mouse_move, #on_release, #paint, #positioned?, #properties_changed, #redraw!, #remove_child, #requested_height, #requested_width, #set_parent, #style

Constructor Details

This class inherits a constructor from Clogs::Drawable

Instance Method Details

#chosenObject



486
487
488
# File 'lib/clogs/drawables/controls.rb', line 486

def chosen
  style(:chosen) || items.first
end

#closeObject



561
562
563
564
565
566
# File 'lib/clogs/drawables/controls.rb', line 561

def close
  return unless @open

  @open = false
  redraw!
end

#draw(painter, x, y) ⇒ Object



495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
# File 'lib/clogs/drawables/controls.rb', line 495

def draw(painter, x, y)
  painter.draw(fill: [255, 255, 255, 255], stroke: [160, 160, 160, 255], thickness: 1) do |p|
    Clogs.rounded_rect(p, x + 0.5, y + 0.5, @width - 1, @height - 1, 3)
  end
  st = text_style
  unless chosen.to_s.empty?
    block = TextBlock.new([Run.new(text: chosen.to_s, size: st.size, family: st.family, color: st.color)],
      -1, default_family: st.family, default_size: st.size)
    block.draw(painter, x + 6, y + PADDING_Y / 2.0)
    block.free
  end
  # Arrow
  painter.draw(fill: [80, 80, 80, 255]) do |p|
    ax = x + @width - 16
    ay = y + @height / 2.0 - 2
    p.move_to(ax, ay).line_to(ax + 8, ay).line_to(ax + 4, ay + 5).close
  end
end

#draw_overlay(painter) ⇒ Object

Drawn by the app after everything else so it sits on top.



515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'lib/clogs/drawables/controls.rb', line 515

def draw_overlay(painter)
  return unless @open

  x = @abs_x
  y = @abs_y + @height
  h = ROW_HEIGHT * items.size
  painter.draw(fill: [255, 255, 255, 255], stroke: [140, 140, 140, 255], thickness: 1) do |p|
    p.rect(x + 0.5, y + 0.5, @width - 1, h)
  end
  st = text_style
  items.each_with_index do |item, i|
    iy = y + i * ROW_HEIGHT
    painter.fill_rect(x + 1, iy + 1, @width - 2, ROW_HEIGHT - 1, [220, 235, 255, 255]) if item == chosen
    block = TextBlock.new([Run.new(text: item, size: st.size, family: st.family, color: st.color)],
      -1, default_family: st.family, default_size: st.size)
    block.draw(painter, x + 6, iy + 3)
    block.free
  end
end

#itemsObject



482
483
484
# File 'lib/clogs/drawables/controls.rb', line 482

def items
  Array(style(:items)).map(&:to_s)
end

#measure(available_width) ⇒ Object



490
491
492
493
# File 'lib/clogs/drawables/controls.rb', line 490

def measure(available_width)
  @width = requested_width(available_width) || [available_width, 200].min
  @height = requested_height(available_width) || (Clogs.default_font_size + PADDING_Y * 2).ceil
end

#on_click(x, y, _button) ⇒ Object



546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'lib/clogs/drawables/controls.rb', line 546

def on_click(x, y, _button)
  if @open && overlay_contains?(x, y)
    index = ((y - (@abs_y + @height)) / ROW_HEIGHT).to_i
    item = items[index]
    if item
      @styles["chosen"] = item
      notify("change", item)
    end
    @open = false
  else
    @open = !@open
  end
  redraw!
end

#open?Boolean

Returns:

  • (Boolean)


535
536
537
# File 'lib/clogs/drawables/controls.rb', line 535

def open?
  @open
end

#overlay_contains?(px, py) ⇒ Boolean

Returns:

  • (Boolean)


539
540
541
542
543
544
# File 'lib/clogs/drawables/controls.rb', line 539

def overlay_contains?(px, py)
  return false unless @open

  py >= @abs_y + @height && py < @abs_y + @height + ROW_HEIGHT * items.size &&
    px >= @abs_x && px < @abs_x + @width
end