check.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. Widgets for the Midnight Commander
  3. Copyright (C) 1994-2024
  4. Free Software Foundation, Inc.
  5. Authors:
  6. Radek Doulik, 1994, 1995
  7. Miguel de Icaza, 1994, 1995
  8. Jakub Jelinek, 1995
  9. Andrej Borsenkow, 1996
  10. Norbert Warmuth, 1997
  11. Andrew Borodin <aborodin@vmail.ru>, 2009-2022
  12. This file is part of the Midnight Commander.
  13. The Midnight Commander is free software: you can redistribute it
  14. and/or modify it under the terms of the GNU General Public License as
  15. published by the Free Software Foundation, either version 3 of the License,
  16. or (at your option) any later version.
  17. The Midnight Commander is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. GNU General Public License for more details.
  21. You should have received a copy of the GNU General Public License
  22. along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. */
  24. /** \file check.c
  25. * \brief Source: WCheck widget (checkbutton)
  26. */
  27. #include <config.h>
  28. #include <stdlib.h>
  29. #include "lib/global.h"
  30. #include "lib/tty/tty.h"
  31. #include "lib/widget.h"
  32. /*** global variables ****************************************************************************/
  33. /*** file scope macro definitions ****************************************************************/
  34. /*** file scope type declarations ****************************************************************/
  35. /*** forward declarations (file scope functions) *************************************************/
  36. /*** file scope variables ************************************************************************/
  37. /* --------------------------------------------------------------------------------------------- */
  38. /*** file scope functions ************************************************************************/
  39. /* --------------------------------------------------------------------------------------------- */
  40. static cb_ret_t
  41. check_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
  42. {
  43. WCheck *c = CHECK (w);
  44. switch (msg)
  45. {
  46. case MSG_HOTKEY:
  47. if (c->text.hotkey != NULL)
  48. {
  49. if (g_ascii_tolower ((gchar) c->text.hotkey[0]) == parm)
  50. {
  51. /* make action */
  52. send_message (w, sender, MSG_KEY, ' ', data);
  53. return MSG_HANDLED;
  54. }
  55. }
  56. return MSG_NOT_HANDLED;
  57. case MSG_KEY:
  58. if (parm != ' ')
  59. return MSG_NOT_HANDLED;
  60. c->state = !c->state;
  61. widget_draw (w);
  62. send_message (w->owner, w, MSG_NOTIFY, 0, NULL);
  63. return MSG_HANDLED;
  64. case MSG_CURSOR:
  65. widget_gotoyx (w, 0, 1);
  66. return MSG_HANDLED;
  67. case MSG_DRAW:
  68. {
  69. gboolean focused;
  70. focused = widget_get_state (w, WST_FOCUSED);
  71. widget_selectcolor (w, focused, FALSE);
  72. widget_gotoyx (w, 0, 0);
  73. tty_print_string (c->state ? "[x] " : "[ ] ");
  74. hotkey_draw (w, c->text, focused);
  75. return MSG_HANDLED;
  76. }
  77. case MSG_DESTROY:
  78. hotkey_free (c->text);
  79. return MSG_HANDLED;
  80. default:
  81. return widget_default_callback (w, sender, msg, parm, data);
  82. }
  83. }
  84. /* --------------------------------------------------------------------------------------------- */
  85. static void
  86. check_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
  87. {
  88. (void) event;
  89. switch (msg)
  90. {
  91. case MSG_MOUSE_DOWN:
  92. widget_select (w);
  93. break;
  94. case MSG_MOUSE_CLICK:
  95. send_message (w, NULL, MSG_KEY, ' ', NULL);
  96. send_message (w->owner, w, MSG_POST_KEY, ' ', NULL);
  97. break;
  98. default:
  99. break;
  100. }
  101. }
  102. /* --------------------------------------------------------------------------------------------- */
  103. /*** public functions ****************************************************************************/
  104. /* --------------------------------------------------------------------------------------------- */
  105. WCheck *
  106. check_new (int y, int x, gboolean state, const char *text)
  107. {
  108. WRect r = { y, x, 1, 1 };
  109. WCheck *c;
  110. Widget *w;
  111. c = g_new (WCheck, 1);
  112. w = WIDGET (c);
  113. c->text = hotkey_new (text);
  114. /* 4 is width of "[X] " */
  115. r.cols = 4 + hotkey_width (c->text);
  116. widget_init (w, &r, check_callback, check_mouse_callback);
  117. w->options |= WOP_SELECTABLE | WOP_WANT_CURSOR | WOP_WANT_HOTKEY;
  118. c->state = state;
  119. return c;
  120. }
  121. /* --------------------------------------------------------------------------------------------- */
  122. void
  123. check_set_text (WCheck *check, const char *text)
  124. {
  125. Widget *w = WIDGET (check);
  126. hotkey_t hk;
  127. hk = hotkey_new (text);
  128. if (hotkey_equal (check->text, hk))
  129. {
  130. hotkey_free (hk);
  131. return;
  132. }
  133. hotkey_free (check->text);
  134. check->text = hk;
  135. if (check->text.start[0] == '\0' && check->text.hotkey == NULL && check->text.end == NULL)
  136. w->rect.cols = 3; /* "[ ]" */
  137. else
  138. w->rect.cols = 4 + hotkey_width (check->text); /* "[ ] text" */
  139. widget_draw (w);
  140. }
  141. /* --------------------------------------------------------------------------------------------- */