Class: Fidgit::TextArea
- Defined in:
- lib/fidgit/elements/text_area.rb
Constant Summary collapse
- ENTITY_PLACEHOLDER =
"*"
- ENTITIES_AND_TAGS_PATTERN =
%r%<[a-z](?:=[a-f0-9]+)?>|</[a-z]>|&\w+;%i
Constants inherited from Element
Element::DEFAULT_SCHEMA_FILE, Element::VALID_ALIGN_H, Element::VALID_ALIGN_V
Instance Attribute Summary collapse
- #editable ⇒ Boolean writeonly
- #line_spacing ⇒ Number readonly
- #max_height ⇒ Number readonly
- #min_height ⇒ Number readonly
-
#stripped_text ⇒ String
readonly
Text, but stripped of tags.
Attributes inherited from Element
#align_h, #align_v, #background_color, #border_thickness, #font, #padding_bottom, #padding_left, #padding_right, #padding_top, #parent, #tip, #z
Instance Method Summary collapse
- #blur(sender) ⇒ nil
-
#caret_position ⇒ Integer
Position of the caret.
-
#caret_position=(position) ⇒ Integer
Position of the caret.
- #click_in_text(sender, x, y) ⇒ nil
-
#copy ⇒ Object
Copy the selection to the clipboard.
-
#cut ⇒ Object
Cut the selection and copy it to the clipboard.
- #drag?(button) ⇒ Boolean
-
#draw_foreground ⇒ nil
Draw the text area.
-
#editable? ⇒ Boolean
Is the area editable? This will always be false if the Element is disabled.
- #focus(sender) ⇒ nil
-
#focused? ⇒ Boolean
Does the element have the focus?.
-
#initialize(options = {}, &block) ⇒ TextArea
constructor
A new instance of TextArea.
-
#paste ⇒ Object
Paste the contents of the clipboard into the TextArea.
-
#selection_range ⇒ Range
Returns the range of the selection.
-
#selection_text ⇒ String
Returns the text within the selection.
-
#selection_text=(str) ⇒ String
Sets the text within the selection.
-
#text ⇒ String
Text within the element.
-
#text=(text) ⇒ String
Sets caret to the end of the text.
Methods inherited from Element
#default, #draw, #draw_frame, #draw_rect, #enabled=, #enabled?, #height, #height=, #hit?, #max_width, #min_width, new, original_new, #outer_height, #outer_width, #recalc, schema, #to_s, #update, #width, #width=, #with, #x, #x=, #y, #y=
Methods included from Event
#events, included, new_event_handlers, #publish, #subscribe, #unsubscribe
Constructor Details
#initialize(options = {}, &block) ⇒ TextArea
Returns a new instance of TextArea.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/fidgit/elements/text_area.rb', line 125 def initialize( = {}, &block) = { text: '', max_height: Float::INFINITY, line_spacing: default(:line_spacing), background_color: default(:background_color), border_color: default(:border_color), caret_color: default(:caret_color), caret_period: default(:caret_period), focused_border_color: default(:focused, :border_color), selection_color: default(:selection_color), editable: true, }.merge! @line_spacing = [:line_spacing] @caret_color = [:caret_color].dup @caret_period = [:caret_period] @focused_border_color = [:focused_border_color].dup @selection_color = [:selection_color].dup @editable = [:editable] @lines = [''] # List of lines of wrapped text. @caret_positions = [[0, 0]] # [x, y] of each position the caret can be in. @char_widths = [] # Width of each character in the text. @text_input = Gosu::TextInput.new @old_text = '' @old_caret_position = 0 @old_selection_start = 0 @tags = Hash.new("") # Hash of tags embedded in the text. @text_input.text = [:text].dup @stripped_text = '' # Text stripped of xml tags. super() min_height = padding_left + padding_right + font.height if [:height] @max_height = @min_height = [[:height], min_height].max else @max_height = [[:max_height], min_height].max @min_height = [:min_height] ? [[:min_height], min_height].max : min_height end rect.height = [padding_left + padding_right + font.height, @min_height].max subscribe :left_mouse_button, method(:click_in_text) subscribe :right_mouse_button, method(:click_in_text) # Handle dragging. subscribe :begin_drag do |sender, x, y| # Store position of the handle when it starts to drag. @drag_start_pos = [x - self.x, y - self.y] end subscribe :update_drag do |sender, x, y| index = text_index_at_position(x, y) self.caret_position = [index, @stripped_text.length].min if index end subscribe :end_drag do @drag_start_pos = nil end end |
Instance Attribute Details
#editable=(value) ⇒ Boolean (writeonly)
18 19 20 |
# File 'lib/fidgit/elements/text_area.rb', line 18 def editable=(value) @editable = value end |
#line_spacing ⇒ Number (readonly)
14 15 16 |
# File 'lib/fidgit/elements/text_area.rb', line 14 def line_spacing @line_spacing end |
#max_height ⇒ Number (readonly)
11 12 13 |
# File 'lib/fidgit/elements/text_area.rb', line 11 def max_height @max_height end |
#min_height ⇒ Number (readonly)
9 10 11 |
# File 'lib/fidgit/elements/text_area.rb', line 9 def min_height @min_height end |
#stripped_text ⇒ String (readonly)
Returns Text, but stripped of tags.
21 22 23 |
# File 'lib/fidgit/elements/text_area.rb', line 21 def stripped_text @stripped_text end |
Instance Method Details
#blur(sender) ⇒ nil
212 213 214 215 216 217 218 219 220 221 |
# File 'lib/fidgit/elements/text_area.rb', line 212 def blur(sender) if focused? $window.current_game_state.focus = nil $window.text_input = nil end @focused = false nil end |
#caret_position ⇒ Integer
Position of the caret.
89 90 91 |
# File 'lib/fidgit/elements/text_area.rb', line 89 def caret_position @text_input.caret_pos end |
#caret_position=(position) ⇒ Integer
Position of the caret.
97 98 99 100 101 102 |
# File 'lib/fidgit/elements/text_area.rb', line 97 def caret_position=(position) raise ArgumentError, "Caret position must be in the range 0 to the length of the text (inclusive)" unless position.between?(0, stripped_text.length) @text_input.caret_pos = position position end |
#click_in_text(sender, x, y) ⇒ nil
189 190 191 192 193 194 195 196 197 |
# File 'lib/fidgit/elements/text_area.rb', line 189 def click_in_text(sender, x, y) publish :focus unless focused? # Move caret to position the user clicks on. index = text_index_at_position x, y self.caret_position = @text_input.selection_start = [index, @stripped_text.length].min if index nil end |
#copy ⇒ Object
Copy the selection to the clipboard.
454 455 456 457 |
# File 'lib/fidgit/elements/text_area.rb', line 454 def copy str = selection_text Clipboard.copy str unless str.empty? end |
#cut ⇒ Object
Cut the selection and copy it to the clipboard.
444 445 446 447 448 449 450 |
# File 'lib/fidgit/elements/text_area.rb', line 444 def cut str = selection_text unless str.empty? Clipboard.copy str self.selection_text = '' if editable? end end |
#drag?(button) ⇒ Boolean
31 |
# File 'lib/fidgit/elements/text_area.rb', line 31 def drag?(); == :left; end |
#draw_foreground ⇒ nil
Draw the text area.
226 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 |
# File 'lib/fidgit/elements/text_area.rb', line 226 def draw_foreground # Always roll back changes made by the user unless the text is editable. if editable? or text == @old_text recalc if focused? # Workaround for Windows draw/update bug. @old_caret_position = caret_position @old_selection_start = @text_input.selection_start else roll_back end if caret_position > stripped_text.length self.caret_position = stripped_text.length end if @text_input.selection_start >= stripped_text.length @text_input.selection_start = stripped_text.length end # Draw the selection. selection_range.each do |pos| char_x, char_y = @caret_positions[pos] char_width = @char_widths[pos] left, top = x + padding_left + char_x, y + padding_top + char_y draw_rect left, top, char_width, font.height, z, @selection_color end # Draw text. @lines.each_with_index do |line, index| font.draw(line, x + padding_left, y + padding_top + y_at_line(index), z) end # Draw the caret. if focused? and ((Gosu::milliseconds / @caret_period) % 2 == 0) caret_x, caret_y = @caret_positions[caret_position] left, top = x + padding_left + caret_x, y + padding_top + caret_y draw_rect left, top, 1, font.height, z, @caret_color end end |
#editable? ⇒ Boolean
Is the area editable? This will always be false if the Element is disabled.
34 35 36 |
# File 'lib/fidgit/elements/text_area.rb', line 34 def editable? enabled? and @editable end |
#focus(sender) ⇒ nil
203 204 205 206 207 208 209 |
# File 'lib/fidgit/elements/text_area.rb', line 203 def focus(sender) @focused = true $window.current_game_state.focus = self $window.text_input = @text_input nil end |
#focused? ⇒ Boolean
Does the element have the focus?
200 |
# File 'lib/fidgit/elements/text_area.rb', line 200 def focused?; @focused; end |
#paste ⇒ Object
Paste the contents of the clipboard into the TextArea.
461 462 463 |
# File 'lib/fidgit/elements/text_area.rb', line 461 def paste self.selection_text = Clipboard.paste end |
#selection_range ⇒ Range
Returns the range of the selection.
47 48 49 50 51 52 |
# File 'lib/fidgit/elements/text_area.rb', line 47 def selection_range from = [@text_input.selection_start, caret_position].min to = [@text_input.selection_start, caret_position].max (from...to) end |
#selection_text ⇒ String
Returns the text within the selection.
57 58 59 |
# File 'lib/fidgit/elements/text_area.rb', line 57 def selection_text stripped_text[selection_range] end |
#selection_text=(str) ⇒ String
Sets the text within the selection. The caret will be placed at the end of the inserted text.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/fidgit/elements/text_area.rb', line 65 def selection_text=(str) from = [@text_input.selection_start, @text_input.caret_pos].min to = [@text_input.selection_start, @text_input.caret_pos].max new_length = str.length full_text = text = (0...from).inject(0) {|m, i| m + @tags[i].length } = (from...to).inject(0) {|m, i| m + @tags[i].length } range = (selection_range.first + )...(selection_range.last + + ) full_text[range] = str.encode('UTF-8', undef: :replace) @text_input.text = full_text @text_input.selection_start = @text_input.caret_pos = from + new_length recalc # This may roll back the text if it is too long! publish :changed, self.text str end |
#text ⇒ String
Text within the element.
40 41 42 |
# File 'lib/fidgit/elements/text_area.rb', line 40 def text @text_input.text.force_encoding 'UTF-8' end |
#text=(text) ⇒ String
Sets caret to the end of the text.
108 109 110 111 112 113 |
# File 'lib/fidgit/elements/text_area.rb', line 108 def text=(text) @text_input.text = text recalc # This may roll back the text if it is too long. publish :changed, self.text self.text end |