Skip to content

Commit

Permalink
Merge pull request #314 from mrkprdo/master
Browse files Browse the repository at this point in the history
Add cursor size for text input
  • Loading branch information
ppizarror authored Apr 2, 2021
2 parents 9ce7186 + bc798a0 commit da5cc89
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
5 changes: 4 additions & 1 deletion pygame_menu/_widgetmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

from pygame_menu._types import Any, Union, Callable, Dict, Optional, CallbackType, \
PaddingInstance, NumberType, Vector2NumberType, List, Tuple, NumberInstance, \
Tuple3IntType
Tuple3IntType, Tuple2IntType


# noinspection PyProtectedMember
Expand Down Expand Up @@ -2025,6 +2025,7 @@ def text_input(
default: Union[str, int, float] = '',
copy_paste_enable: bool = True,
cursor_selection_enable: bool = True,
cursor_size: Optional[Tuple2IntType] = None,
input_type: str = INPUT_TEXT,
input_underline: str = '',
input_underline_len: int = 0,
Expand Down Expand Up @@ -2103,6 +2104,7 @@ def text_input(
:param default: Default value to display
:param copy_paste_enable: Enable text copy, paste and cut
:param cursor_selection_enable: Enable text selection on input
:param cursor_size: Size of the cursor (width, height) in px. If ``None`` uses the default sizing
:param input_type: Data type of the input. See :py:mod:`pygame_menu.locals`
:param input_underline: Underline character
:param input_underline_len: Total of characters to be drawn under the input. If ``0`` this number is computed automatically to fit the font
Expand Down Expand Up @@ -2133,6 +2135,7 @@ def text_input(
cursor_color=self._theme.cursor_color,
cursor_selection_color=self._theme.cursor_selection_color,
cursor_selection_enable=cursor_selection_enable,
cursor_size=cursor_size,
cursor_switch_ms=self._theme.cursor_switch_ms,
input_type=input_type,
input_underline=input_underline,
Expand Down
21 changes: 18 additions & 3 deletions pygame_menu/widgets/widget/textinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

from pygame_menu.locals import FINGERDOWN, FINGERUP, INPUT_INT, INPUT_FLOAT, INPUT_TEXT
from pygame_menu.utils import check_key_pressed_valid, make_surface, assert_color, \
get_finger_pos, warn
get_finger_pos, warn, assert_vector
from pygame_menu.widgets.core import Widget

from pygame_menu._types import Optional, Any, CallbackType, Tuple, List, ColorType, \
Expand Down Expand Up @@ -105,6 +105,7 @@ class TextInput(Widget):
:param cursor_color: Color of cursor
:param cursor_selection_color: Color of the text selection if the cursor is enabled on certain widgets
:param cursor_selection_enable: Enables selection of text
:param cursor_size: Set surface x,y of the cursor which determines cursor size
:param cursor_switch_ms: Interval of cursor switch between off and on status. First status is ``off``
:param history: Maximum number of editions stored
:param input_type: Type of the input data. See :py:mod:`pygame_menu.locals`
Expand Down Expand Up @@ -139,6 +140,7 @@ class TextInput(Widget):
_cursor_offset: NumberType
_cursor_position: int
_cursor_render: bool
_cursor_size: Optional[Tuple2IntType] # Size defined by user
_cursor_surface: Optional['pygame.Surface']
_cursor_surface_pos: List[int]
_cursor_switch_ms: NumberType
Expand Down Expand Up @@ -195,6 +197,7 @@ def __init__(
cursor_color: ColorInputType = (0, 0, 0),
cursor_selection_color: ColorInputType = (30, 30, 30, 100),
cursor_selection_enable: bool = True,
cursor_size: Optional[Tuple2IntType] = None,
cursor_switch_ms: NumberType = 500,
history: int = 50,
input_type: str = INPUT_TEXT,
Expand All @@ -220,6 +223,7 @@ def __init__(
) -> None:
assert isinstance(copy_paste_enable, bool)
assert isinstance(cursor_selection_enable, bool)
assert isinstance(cursor_size, (type(None), tuple))
assert isinstance(cursor_switch_ms, NumberInstance)
assert isinstance(history, int)
assert isinstance(input_type, str)
Expand Down Expand Up @@ -255,6 +259,13 @@ def __init__(
assert cursor_selection_color[3] != 255, \
'cursor selection color alpha cannot be opaque'

if cursor_size is not None:
assert_vector(cursor_size, 2, int)
assert cursor_size[0] > 0, \
'cursor size width must be greater than zero'
assert cursor_size[1] > 0, \
'cursor size height must be greater than zero'

super(TextInput, self).__init__(
args=args,
kwargs=kwargs,
Expand Down Expand Up @@ -312,6 +323,7 @@ def __init__(
self._cursor_render = True # If True cursor must be rendered
self._cursor_surface = None
self._cursor_surface_pos = [0, 0] # Position (x,y) of surface
self._cursor_size = cursor_size
self._cursor_switch_ms = cursor_switch_ms
self._cursor_visible = False # Switches every self._cursor_switch_ms ms

Expand Down Expand Up @@ -684,8 +696,11 @@ def _render_cursor(self) -> None:
if self._cursor_surface is None:
if self._rect.height == 0: # If Menu has not been initialized this error can occur
return
self._cursor_surface = make_surface(self._font_size / 20 + 1,
self._rect.height - 2)
if self._cursor_size is not None:
self._cursor_surface = make_surface(*self._cursor_size)
else:
self._cursor_surface = make_surface(self._font_size / 20 + 1,
self._rect.height - 2)
self._cursor_surface.fill(self._cursor_color)

# Get string
Expand Down
12 changes: 11 additions & 1 deletion test/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ def test_clock(self) -> None:
# Check title format
self.assertRaises(AssertionError, lambda: menu.add.clock(title_format='bad'))

# noinspection SpellCheckingInspection
# noinspection SpellCheckingInspection,PyTypeChecker
def test_textinput(self) -> None:
"""
Test TextInput widget.
Expand Down Expand Up @@ -1252,6 +1252,16 @@ def test_textinput(self) -> None:
self.assertEqual(textinput.get_width(), 134)
self.assertEqual(textinput._current_underline_string, '________')

# Test cursor size
self.assertRaises(AssertionError, lambda: menu.add.text_input('title', cursor_size=(1, 0)))
self.assertRaises(AssertionError, lambda: menu.add.text_input('title', cursor_size=(-1, -1)))
self.assertRaises(AssertionError, lambda: menu.add.text_input('title', cursor_size=(1, 1, 0)))
self.assertRaises(AssertionError, lambda: menu.add.text_input('title', cursor_size=[1, 1]))
self.assertRaises(AssertionError, lambda: menu.add.text_input('title', cursor_size=(1.6, 2.5)))

textinput_cursor = menu.add.text_input('title', cursor_size=(10, 2))
self.assertEqual(textinput_cursor._cursor_size, (10, 2))

def test_button(self) -> None:
"""
Test button widget.
Expand Down

0 comments on commit da5cc89

Please sign in to comment.