2011-10-15 14:56:47 +04:00
|
|
|
/*
|
|
|
|
Widgets for the Midnight Commander
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2024-01-01 09:46:17 +03:00
|
|
|
Copyright (C) 1994-2024
|
2014-02-12 10:33:10 +04:00
|
|
|
Free Software Foundation, Inc.
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
Authors:
|
|
|
|
Radek Doulik, 1994, 1995
|
|
|
|
Miguel de Icaza, 1994, 1995
|
|
|
|
Jakub Jelinek, 1995
|
|
|
|
Andrej Borsenkow, 1996
|
|
|
|
Norbert Warmuth, 1997
|
2022-04-30 18:45:15 +03:00
|
|
|
Andrew Borodin <aborodin@vmail.ru>, 2009-2022
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
This file is part of the Midnight Commander.
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander is free software: you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
The Midnight Commander is distributed in the hope that it will be useful,
|
2010-11-12 11:03:57 +03:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2011-10-15 14:56:47 +04:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2010-11-12 11:03:57 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file widget-common.c
|
|
|
|
* \brief Source: shared stuff of widgets
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "lib/global.h"
|
|
|
|
|
|
|
|
#include "lib/tty/tty.h"
|
|
|
|
#include "lib/tty/color.h"
|
|
|
|
#include "lib/skin.h"
|
|
|
|
#include "lib/strutil.h"
|
|
|
|
#include "lib/widget.h"
|
|
|
|
|
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
|
|
|
|
/*** file scope macro definitions ****************************************************************/
|
|
|
|
|
|
|
|
/*** file scope type declarations ****************************************************************/
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/*** file scope variables ************************************************************************/
|
|
|
|
|
2016-09-28 13:37:31 +03:00
|
|
|
/* maximum value of used widget ID */
|
|
|
|
static unsigned long widget_id = 0;
|
|
|
|
|
2016-07-16 21:00:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-12 11:03:57 +03:00
|
|
|
/*** file scope functions ************************************************************************/
|
2016-07-16 21:00:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-09-28 13:37:31 +03:00
|
|
|
/**
|
|
|
|
* Calc widget ID,
|
|
|
|
* Widget ID is uniq for each widget created during MC session (like PID in OS).
|
|
|
|
*
|
|
|
|
* @return widget ID.
|
|
|
|
*/
|
|
|
|
static unsigned long
|
|
|
|
widget_set_id (void)
|
|
|
|
{
|
|
|
|
unsigned long id;
|
|
|
|
|
|
|
|
id = widget_id++;
|
|
|
|
/* TODO IF NEEDED: if id is already used, find next free id. */
|
|
|
|
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-10-13 10:15:03 +03:00
|
|
|
static cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_resize (Widget *w, const WRect *r)
|
2016-10-13 10:15:03 +03:00
|
|
|
{
|
|
|
|
if (r == NULL)
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
2022-05-01 10:43:33 +03:00
|
|
|
w->rect = *r;
|
2016-10-13 10:15:03 +03:00
|
|
|
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-07-16 21:00:28 +03:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_do_focus (Widget *w, gboolean enable)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
2019-08-11 15:15:14 +03:00
|
|
|
if (w != NULL && widget_get_state (WIDGET (w->owner), WST_VISIBLE | WST_FOCUSED))
|
2016-07-16 21:00:28 +03:00
|
|
|
widget_set_state (w, WST_FOCUSED, enable);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Focus specified widget in it's owner.
|
|
|
|
*
|
|
|
|
* @param w widget to be focused.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_focus (Widget *w)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
WGroup *g = w->owner;
|
2016-07-16 21:00:28 +03:00
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g == NULL)
|
2016-07-16 21:00:28 +03:00
|
|
|
return;
|
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (WIDGET (g->current->data) != w)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
widget_do_focus (WIDGET (g->current->data), FALSE);
|
2016-07-16 21:00:28 +03:00
|
|
|
/* Test if focus lost was allowed and focus has really been loose */
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g->current == NULL || !widget_get_state (WIDGET (g->current->data), WST_FOCUSED))
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
|
|
|
widget_do_focus (w, TRUE);
|
2016-09-29 11:16:17 +03:00
|
|
|
g->current = widget_find (WIDGET (g), w);
|
2016-07-16 21:00:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!widget_get_state (w, WST_FOCUSED))
|
|
|
|
widget_do_focus (w, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Put widget on top or bottom of Z-order.
|
|
|
|
*/
|
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_reorder (GList *l, gboolean set_top)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
WGroup *g = WIDGET (l->data)->owner;
|
2016-07-16 21:00:28 +03:00
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
g->widgets = g_list_remove_link (g->widgets, l);
|
2016-07-16 21:00:28 +03:00
|
|
|
if (set_top)
|
2016-09-27 13:53:17 +03:00
|
|
|
g->widgets = g_list_concat (g->widgets, l);
|
2016-07-16 21:00:28 +03:00
|
|
|
else
|
2016-09-27 13:53:17 +03:00
|
|
|
g->widgets = g_list_concat (l, g->widgets);
|
2016-07-16 21:00:28 +03:00
|
|
|
}
|
|
|
|
|
2019-12-14 12:53:44 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
hotkey_cmp (const char *s1, const char *s2)
|
|
|
|
{
|
|
|
|
gboolean n1, n2;
|
|
|
|
|
|
|
|
n1 = s1 != NULL;
|
|
|
|
n2 = s2 != NULL;
|
|
|
|
|
|
|
|
if (n1 != n2)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (n1 && n2 && strcmp (s1, s2) != 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2019-11-17 17:58:52 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2020-03-30 09:43:09 +03:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
|
2020-03-30 09:43:09 +03:00
|
|
|
{
|
|
|
|
/* do nothing */
|
|
|
|
(void) w;
|
|
|
|
(void) msg;
|
|
|
|
(void) event;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2019-11-17 17:58:52 +03:00
|
|
|
static const int *
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_get_colors (const Widget *w)
|
2019-11-17 17:58:52 +03:00
|
|
|
{
|
|
|
|
const Widget *owner = CONST_WIDGET (w->owner);
|
|
|
|
|
|
|
|
return (owner == NULL ? NULL : widget_get_colors (owner));
|
|
|
|
}
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/*** public functions ****************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
struct hotkey_t
|
2019-12-14 11:50:04 +03:00
|
|
|
hotkey_new (const char *text)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
hotkey_t result;
|
|
|
|
const char *cp, *p;
|
|
|
|
|
|
|
|
if (text == NULL)
|
|
|
|
text = "";
|
|
|
|
|
|
|
|
/* search for '&', that is not on the of text */
|
|
|
|
cp = strchr (text, '&');
|
|
|
|
if (cp != NULL && cp[1] != '\0')
|
|
|
|
{
|
|
|
|
result.start = g_strndup (text, cp - text);
|
|
|
|
|
|
|
|
/* skip '&' */
|
|
|
|
cp++;
|
|
|
|
p = str_cget_next_char (cp);
|
|
|
|
result.hotkey = g_strndup (cp, p - cp);
|
|
|
|
|
|
|
|
cp = p;
|
|
|
|
result.end = g_strdup (cp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result.start = g_strdup (text);
|
|
|
|
result.hotkey = NULL;
|
|
|
|
result.end = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
2019-12-14 11:50:04 +03:00
|
|
|
hotkey_free (const hotkey_t hotkey)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
g_free (hotkey.start);
|
|
|
|
g_free (hotkey.hotkey);
|
|
|
|
g_free (hotkey.end);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
int
|
|
|
|
hotkey_width (const hotkey_t hotkey)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
result = str_term_width1 (hotkey.start);
|
|
|
|
result += (hotkey.hotkey != NULL) ? str_term_width1 (hotkey.hotkey) : 0;
|
|
|
|
result += (hotkey.end != NULL) ? str_term_width1 (hotkey.end) : 0;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2019-12-14 12:53:44 +03:00
|
|
|
gboolean
|
|
|
|
hotkey_equal (const hotkey_t hotkey1, const hotkey_t hotkey2)
|
|
|
|
{
|
|
|
|
/* *INDENT-OFF* */
|
|
|
|
return (strcmp (hotkey1.start, hotkey2.start) == 0) &&
|
|
|
|
hotkey_cmp (hotkey1.hotkey, hotkey2.hotkey) &&
|
|
|
|
hotkey_cmp (hotkey1.end, hotkey2.end);
|
|
|
|
/* *INDENT-ON* */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
hotkey_draw (const Widget *w, const hotkey_t hotkey, gboolean focused)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2019-12-14 16:56:18 +03:00
|
|
|
if (hotkey.start[0] != '\0')
|
|
|
|
{
|
|
|
|
widget_selectcolor (w, focused, FALSE);
|
|
|
|
tty_print_string (hotkey.start);
|
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
if (hotkey.hotkey != NULL)
|
|
|
|
{
|
|
|
|
widget_selectcolor (w, focused, TRUE);
|
|
|
|
tty_print_string (hotkey.hotkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hotkey.end != NULL)
|
2019-12-14 16:56:18 +03:00
|
|
|
{
|
|
|
|
widget_selectcolor (w, focused, FALSE);
|
2010-11-12 11:03:57 +03:00
|
|
|
tty_print_string (hotkey.end);
|
2019-12-14 16:56:18 +03:00
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2019-12-14 16:32:26 +03:00
|
|
|
char *
|
|
|
|
hotkey_get_text (const hotkey_t hotkey)
|
|
|
|
{
|
|
|
|
GString *text;
|
|
|
|
|
|
|
|
text = g_string_new (hotkey.start);
|
|
|
|
|
|
|
|
if (hotkey.hotkey != NULL)
|
|
|
|
{
|
|
|
|
g_string_append_c (text, '&');
|
|
|
|
g_string_append (text, hotkey.hotkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hotkey.end != NULL)
|
|
|
|
g_string_append (text, hotkey.end);
|
|
|
|
|
|
|
|
return g_string_free (text, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_init (Widget *w, const WRect *r, widget_cb_fn callback, widget_mouse_cb_fn mouse_callback)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2016-09-28 13:37:31 +03:00
|
|
|
w->id = widget_set_id ();
|
2022-05-21 16:11:06 +03:00
|
|
|
w->rect = *r;
|
2013-08-12 13:51:01 +04:00
|
|
|
w->pos_flags = WPOS_KEEP_DEFAULT;
|
2010-11-12 11:03:57 +03:00
|
|
|
w->callback = callback;
|
2017-03-08 14:41:35 +03:00
|
|
|
|
|
|
|
w->keymap = NULL;
|
|
|
|
w->ext_keymap = NULL;
|
|
|
|
w->ext_mode = FALSE;
|
|
|
|
|
2020-03-30 09:43:09 +03:00
|
|
|
w->mouse_callback = mouse_callback != NULL ? mouse_callback : widget_default_mouse_callback;
|
2010-11-12 11:03:57 +03:00
|
|
|
w->owner = NULL;
|
2016-11-15 09:33:34 +03:00
|
|
|
w->mouse_handler = mouse_handle_event;
|
2016-03-06 09:44:16 +03:00
|
|
|
w->mouse.forced_capture = FALSE;
|
2016-03-23 19:17:05 +03:00
|
|
|
w->mouse.capture = FALSE;
|
|
|
|
w->mouse.last_msg = MSG_MOUSE_NONE;
|
2016-03-06 09:44:16 +03:00
|
|
|
w->mouse.last_buttons_down = 0;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2016-05-08 19:51:45 +03:00
|
|
|
w->options = WOP_DEFAULT;
|
2019-08-11 15:15:14 +03:00
|
|
|
w->state = WST_CONSTRUCT | WST_VISIBLE;
|
2016-09-29 11:16:17 +03:00
|
|
|
|
2021-03-15 21:29:46 +03:00
|
|
|
w->make_global = widget_default_make_global;
|
|
|
|
w->make_local = widget_default_make_local;
|
|
|
|
|
2016-09-29 11:16:17 +03:00
|
|
|
w->find = widget_default_find;
|
|
|
|
w->find_by_type = widget_default_find_by_type;
|
|
|
|
w->find_by_id = widget_default_find_by_id;
|
2019-11-17 17:02:52 +03:00
|
|
|
|
|
|
|
w->set_state = widget_default_set_state;
|
2020-10-31 19:32:29 +03:00
|
|
|
w->destroy = widget_default_destroy;
|
2019-11-17 17:58:52 +03:00
|
|
|
w->get_colors = widget_default_get_colors;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/* Default callback for widgets */
|
|
|
|
cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2012-06-26 11:52:21 +04:00
|
|
|
(void) sender;
|
2010-11-12 11:03:57 +03:00
|
|
|
(void) parm;
|
|
|
|
|
|
|
|
switch (msg)
|
|
|
|
{
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_INIT:
|
|
|
|
case MSG_FOCUS:
|
|
|
|
case MSG_UNFOCUS:
|
2016-04-10 12:26:48 +03:00
|
|
|
case MSG_ENABLE:
|
|
|
|
case MSG_DISABLE:
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_DRAW:
|
|
|
|
case MSG_DESTROY:
|
|
|
|
case MSG_CURSOR:
|
|
|
|
case MSG_IDLE:
|
2010-11-12 11:03:57 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2016-10-13 10:15:03 +03:00
|
|
|
case MSG_RESIZE:
|
|
|
|
return widget_default_resize (w, CONST_RECT (data));
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
default:
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2012-09-09 16:36:50 +04:00
|
|
|
/**
|
2016-04-10 12:26:48 +03:00
|
|
|
* Apply new options to widget.
|
2012-09-09 16:36:50 +04:00
|
|
|
*
|
|
|
|
* @param w widget
|
2016-04-10 12:26:48 +03:00
|
|
|
* @param options widget option flags to modify. Several flags per call can be modified.
|
2012-09-09 16:36:50 +04:00
|
|
|
* @param enable TRUE if specified options should be added, FALSE if options should be removed
|
|
|
|
*/
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_set_options (Widget *w, widget_options_t options, gboolean enable)
|
2012-09-09 16:36:50 +04:00
|
|
|
{
|
|
|
|
if (enable)
|
|
|
|
w->options |= options;
|
|
|
|
else
|
|
|
|
w->options &= ~options;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-10-10 10:20:27 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_adjust_position (widget_pos_flags_t pos_flags, WRect *r)
|
2016-10-10 10:20:27 +03:00
|
|
|
{
|
|
|
|
if ((pos_flags & WPOS_FULLSCREEN) != 0)
|
|
|
|
{
|
2022-05-21 19:37:31 +03:00
|
|
|
r->y = 0;
|
|
|
|
r->x = 0;
|
|
|
|
r->lines = LINES;
|
|
|
|
r->cols = COLS;
|
2016-10-10 10:20:27 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((pos_flags & WPOS_CENTER_HORZ) != 0)
|
2022-05-21 19:37:31 +03:00
|
|
|
r->x = (COLS - r->cols) / 2;
|
2016-10-10 10:20:27 +03:00
|
|
|
|
|
|
|
if ((pos_flags & WPOS_CENTER_VERT) != 0)
|
2022-05-21 19:37:31 +03:00
|
|
|
r->y = (LINES - r->lines) / 2;
|
2016-10-10 10:20:27 +03:00
|
|
|
|
|
|
|
if ((pos_flags & WPOS_TRYUP) != 0)
|
|
|
|
{
|
2022-05-21 19:37:31 +03:00
|
|
|
if (r->y > 3)
|
|
|
|
r->y -= 2;
|
|
|
|
else if (r->y == 3)
|
|
|
|
r->y = 2;
|
2016-10-10 10:20:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2016-10-13 10:15:03 +03:00
|
|
|
/**
|
|
|
|
* Change widget position and size.
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @param y y coordinate of top-left corner
|
|
|
|
* @param x x coordinate of top-left corner
|
|
|
|
* @param lines width
|
|
|
|
* @param cols height
|
|
|
|
*/
|
2016-10-10 10:20:27 +03:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_set_size (Widget *w, int y, int x, int lines, int cols)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2016-10-13 10:15:03 +03:00
|
|
|
WRect r = { y, x, lines, cols };
|
|
|
|
|
|
|
|
send_message (w, NULL, MSG_RESIZE, 0, &r);
|
2019-08-11 14:25:13 +03:00
|
|
|
widget_draw (w);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
2022-04-30 18:45:15 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Change widget position and size.
|
|
|
|
*
|
|
|
|
* @param w widget
|
Fix various typos in the source code (closes MidnightCommander/mc#177).
Found via `codespell -S
po,doc,./misc/syntax,./src/vfs/extfs/helpers/README.it -L
parm,rouge,sav,ect,vie,te,dum,clen,wee,dynamc,childs,ths,fo,nin,unx,nd,iif,iterm,ser,makrs,wil`
Co-authored-by: Yury V. Zaytsev <yury@shurup.com>
Signed-off-by: Kian-Meng Ang <kianmeng@cpan.org>
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
2023-01-10 06:02:52 +03:00
|
|
|
* @param r WRect object that holds position and size
|
2022-04-30 18:45:15 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_set_size_rect (Widget *w, WRect *r)
|
2022-04-30 18:45:15 +03:00
|
|
|
{
|
|
|
|
send_message (w, NULL, MSG_RESIZE, 0, r);
|
|
|
|
widget_draw (w);
|
|
|
|
}
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_selectcolor (const Widget *w, gboolean focused, gboolean hotkey)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
int color;
|
2019-11-17 17:58:52 +03:00
|
|
|
const int *colors;
|
|
|
|
|
|
|
|
colors = widget_get_colors (w);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2016-04-10 12:26:48 +03:00
|
|
|
if (widget_get_state (w, WST_DISABLED))
|
2010-11-12 11:03:57 +03:00
|
|
|
color = DISABLED_COLOR;
|
|
|
|
else if (hotkey)
|
2019-11-17 17:58:52 +03:00
|
|
|
color = colors[focused ? DLG_COLOR_HOT_FOCUS : DLG_COLOR_HOT_NORMAL];
|
2010-11-12 11:03:57 +03:00
|
|
|
else
|
2019-11-17 17:58:52 +03:00
|
|
|
color = colors[focused ? DLG_COLOR_FOCUS : DLG_COLOR_NORMAL];
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
tty_setcolor (color);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_erase (Widget *w)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
if (w != NULL)
|
2022-05-01 10:43:33 +03:00
|
|
|
tty_fill_region (w->rect.y, w->rect.x, w->rect.lines, w->rect.cols, ' ');
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
2019-08-11 15:15:14 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_set_visibility (Widget *w, gboolean make_visible)
|
2019-08-11 15:15:14 +03:00
|
|
|
{
|
|
|
|
if (widget_get_state (w, WST_VISIBLE) != make_visible)
|
|
|
|
widget_set_state (w, WST_VISIBLE, make_visible);
|
|
|
|
}
|
|
|
|
|
2013-06-24 10:47:03 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Check whether widget is active or not.
|
2016-09-30 10:50:19 +03:00
|
|
|
* Widget is active if it's current in the its owner and each owner in the chain is current too.
|
|
|
|
*
|
2013-06-24 10:47:03 +04:00
|
|
|
* @param w the widget
|
|
|
|
*
|
|
|
|
* @return TRUE if the widget is active, FALSE otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
widget_is_active (const void *w)
|
|
|
|
{
|
2016-09-30 10:50:19 +03:00
|
|
|
const WGroup *owner;
|
|
|
|
|
|
|
|
/* Is group top? */
|
|
|
|
if (w == top_dlg->data)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
owner = CONST_WIDGET (w)->owner;
|
|
|
|
|
|
|
|
/* Is widget in any group? */
|
|
|
|
if (owner == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (w != owner->current->data)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return widget_is_active (owner);
|
2013-06-24 10:47:03 +04:00
|
|
|
}
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2011-03-21 16:43:56 +03:00
|
|
|
|
2016-10-30 12:40:20 +03:00
|
|
|
cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_draw (Widget *w)
|
2013-02-11 15:35:00 +04:00
|
|
|
{
|
2016-10-30 12:40:20 +03:00
|
|
|
cb_ret_t ret = MSG_NOT_HANDLED;
|
|
|
|
|
2019-08-11 15:15:14 +03:00
|
|
|
if (w != NULL && widget_get_state (w, WST_VISIBLE))
|
2013-02-11 15:35:00 +04:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
WGroup *g = w->owner;
|
2013-02-11 15:35:00 +04:00
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g != NULL && widget_get_state (WIDGET (g), WST_ACTIVE))
|
2016-10-30 12:40:20 +03:00
|
|
|
ret = w->callback (w, NULL, MSG_DRAW, 0, NULL);
|
2013-02-11 15:35:00 +04:00
|
|
|
}
|
2016-10-30 12:40:20 +03:00
|
|
|
|
|
|
|
return ret;
|
2013-02-11 15:35:00 +04:00
|
|
|
}
|
|
|
|
|
2013-06-24 10:57:01 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Replace widget in the dialog.
|
|
|
|
*
|
|
|
|
* @param old_w old widget that need to be replaced
|
|
|
|
* @param new_w new widget that will replace @old_w
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_replace (Widget *old_w, Widget *new_w)
|
2013-06-24 10:57:01 +04:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
WGroup *g = old_w->owner;
|
2013-06-24 10:57:01 +04:00
|
|
|
gboolean should_focus = FALSE;
|
2016-10-11 10:42:44 +03:00
|
|
|
GList *holder;
|
2013-06-24 10:57:01 +04:00
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g->widgets == NULL)
|
2013-06-24 10:57:01 +04:00
|
|
|
return;
|
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g->current == NULL)
|
|
|
|
g->current = g->widgets;
|
2013-06-24 10:57:01 +04:00
|
|
|
|
2016-10-11 10:42:44 +03:00
|
|
|
/* locate widget position in the list */
|
2016-09-27 13:53:17 +03:00
|
|
|
if (old_w == g->current->data)
|
|
|
|
holder = g->current;
|
2016-10-11 10:42:44 +03:00
|
|
|
else
|
2016-09-27 13:53:17 +03:00
|
|
|
holder = g_list_find (g->widgets, old_w);
|
2016-10-11 10:42:44 +03:00
|
|
|
|
|
|
|
/* if old widget is focused, we should focus the new one... */
|
|
|
|
if (widget_get_state (old_w, WST_FOCUSED))
|
2013-06-24 10:57:01 +04:00
|
|
|
should_focus = TRUE;
|
2016-10-11 10:42:44 +03:00
|
|
|
/* ...but if new widget isn't selectable, we cannot focus it */
|
|
|
|
if (!widget_get_options (new_w, WOP_SELECTABLE))
|
|
|
|
should_focus = FALSE;
|
|
|
|
|
|
|
|
/* if new widget isn't selectable, select other widget before replace */
|
|
|
|
if (!should_focus)
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
2021-12-24 16:36:38 +03:00
|
|
|
for (l = group_get_widget_next_of (holder);
|
|
|
|
!widget_is_focusable (WIDGET (l->data)) && l != holder;
|
2016-09-27 16:16:38 +03:00
|
|
|
l = group_get_widget_next_of (l))
|
2016-10-11 10:42:44 +03:00
|
|
|
;
|
|
|
|
|
|
|
|
widget_select (WIDGET (l->data));
|
|
|
|
}
|
2013-06-24 10:57:01 +04:00
|
|
|
|
2016-10-11 10:42:44 +03:00
|
|
|
/* replace widget */
|
2016-09-27 13:53:17 +03:00
|
|
|
new_w->owner = g;
|
2013-06-24 10:57:01 +04:00
|
|
|
new_w->id = old_w->id;
|
2016-10-11 10:42:44 +03:00
|
|
|
holder->data = new_w;
|
2013-06-24 10:57:01 +04:00
|
|
|
|
|
|
|
send_message (old_w, NULL, MSG_DESTROY, 0, NULL);
|
|
|
|
send_message (new_w, NULL, MSG_INIT, 0, NULL);
|
|
|
|
|
|
|
|
if (should_focus)
|
2016-08-09 09:35:27 +03:00
|
|
|
widget_select (new_w);
|
2016-10-11 10:42:44 +03:00
|
|
|
else
|
2019-10-18 15:44:57 +03:00
|
|
|
widget_draw (new_w);
|
2016-07-16 21:00:28 +03:00
|
|
|
}
|
|
|
|
|
2019-08-11 14:37:43 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
gboolean
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_is_focusable (const Widget *w)
|
2019-08-11 14:37:43 +03:00
|
|
|
{
|
2019-08-11 15:15:14 +03:00
|
|
|
return (widget_get_options (w, WOP_SELECTABLE) && widget_get_state (w, WST_VISIBLE) &&
|
|
|
|
!widget_get_state (w, WST_DISABLED));
|
2019-08-11 14:37:43 +03:00
|
|
|
}
|
|
|
|
|
2016-07-16 21:00:28 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Select specified widget in it's owner.
|
2017-02-26 00:16:04 +03:00
|
|
|
*
|
|
|
|
* Note: this function (and widget_focus(), which it calls) is a no-op
|
|
|
|
* if the widget is already selected.
|
2016-07-16 21:00:28 +03:00
|
|
|
*
|
|
|
|
* @param w widget to be selected
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_select (Widget *w)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
2016-09-29 11:16:17 +03:00
|
|
|
WGroup *g;
|
2016-07-16 21:00:28 +03:00
|
|
|
|
|
|
|
if (!widget_get_options (w, WOP_SELECTABLE))
|
|
|
|
return;
|
|
|
|
|
2016-09-29 11:16:17 +03:00
|
|
|
g = GROUP (w->owner);
|
|
|
|
if (g != NULL)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
|
|
|
if (widget_get_options (w, WOP_TOP_SELECT))
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
2016-09-29 11:16:17 +03:00
|
|
|
l = widget_find (WIDGET (g), w);
|
2016-07-16 21:00:28 +03:00
|
|
|
widget_reorder (l, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
widget_focus (w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Set widget at bottom of widget list.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_set_bottom (Widget *w)
|
2016-07-16 21:00:28 +03:00
|
|
|
{
|
2016-09-29 11:16:17 +03:00
|
|
|
widget_reorder (widget_find (WIDGET (w->owner), w), FALSE);
|
2013-06-24 10:57:01 +04:00
|
|
|
}
|
|
|
|
|
2017-03-08 14:41:35 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Look up key event of widget and translate it to command ID.
|
|
|
|
* @param w widget
|
|
|
|
* @param key key event
|
|
|
|
*
|
|
|
|
* @return command ID binded with @key.
|
|
|
|
*/
|
|
|
|
|
|
|
|
long
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_lookup_key (Widget *w, int key)
|
2017-03-08 14:41:35 +03:00
|
|
|
{
|
|
|
|
if (w->ext_mode)
|
|
|
|
{
|
|
|
|
w->ext_mode = FALSE;
|
|
|
|
return keybind_lookup_keymap_command (w->ext_keymap, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
return keybind_lookup_keymap_command (w->keymap, key);
|
|
|
|
}
|
|
|
|
|
2021-03-15 21:29:46 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default widget callback to convert widget coordinates from local (relative to owner) to global
|
|
|
|
* (relative to screen).
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @delta offset for top-left corner coordinates. Used for child widgets of WGroup
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_make_global (Widget *w, const WRect *delta)
|
2021-03-15 21:29:46 +03:00
|
|
|
{
|
|
|
|
if (delta != NULL)
|
2022-05-01 10:43:33 +03:00
|
|
|
rect_move (&w->rect, delta->y, delta->x);
|
2021-03-15 21:29:46 +03:00
|
|
|
else if (w->owner != NULL)
|
2022-05-01 10:43:33 +03:00
|
|
|
rect_move (&w->rect, WIDGET (w->owner)->rect.y, WIDGET (w->owner)->rect.x);
|
2021-03-15 21:29:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default widget callback to convert widget coordinates from global (relative to screen) to local
|
|
|
|
* (relative to owner).
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @delta offset for top-left corner coordinates. Used for child widgets of WGroup
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_make_local (Widget *w, const WRect *delta)
|
2021-03-15 21:29:46 +03:00
|
|
|
{
|
|
|
|
if (delta != NULL)
|
2022-05-01 10:43:33 +03:00
|
|
|
rect_move (&w->rect, -delta->y, -delta->x);
|
2021-03-15 21:29:46 +03:00
|
|
|
else if (w->owner != NULL)
|
2022-05-01 10:43:33 +03:00
|
|
|
rect_move (&w->rect, -WIDGET (w->owner)->rect.y, -WIDGET (w->owner)->rect.x);
|
2021-03-15 21:29:46 +03:00
|
|
|
}
|
|
|
|
|
2016-09-29 11:16:17 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Default callback function to find widget.
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @param what widget to find
|
|
|
|
*
|
|
|
|
* @return holder of @what if widget is @what, NULL otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
GList *
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_find (const Widget *w, const Widget *what)
|
2016-09-29 11:16:17 +03:00
|
|
|
{
|
|
|
|
return (w != what
|
|
|
|
|| w->owner == NULL) ? NULL : g_list_find (CONST_GROUP (w->owner)->widgets, what);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default callback function to find widget by widget type using widget callback.
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @param cb widget callback
|
|
|
|
*
|
|
|
|
* @return @w if widget callback is @cb, NULL otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
Widget *
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_find_by_type (const Widget *w, widget_cb_fn cb)
|
2016-09-29 11:16:17 +03:00
|
|
|
{
|
|
|
|
return (w->callback == cb ? WIDGET (w) : NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Default callback function to find widget by widget ID.
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @param id widget ID
|
|
|
|
*
|
|
|
|
* @return @w if widget id is equal to @id, NULL otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
Widget *
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_find_by_id (const Widget *w, unsigned long id)
|
2016-09-29 11:16:17 +03:00
|
|
|
{
|
|
|
|
return (w->id == id ? WIDGET (w) : NULL);
|
|
|
|
}
|
|
|
|
|
2019-11-17 17:02:52 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default callback function to modify state of widget.
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
* @param state widget state flag to modify
|
|
|
|
* @param enable specifies whether to turn the flag on (TRUE) or off (FALSE).
|
|
|
|
* Only one flag per call can be modified.
|
|
|
|
* @return MSG_HANDLED if set was handled successfully, MSG_NOT_HANDLED otherwise.
|
|
|
|
*/
|
|
|
|
|
|
|
|
cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_set_state (Widget *w, widget_state_t state, gboolean enable)
|
2019-11-17 17:02:52 +03:00
|
|
|
{
|
|
|
|
gboolean ret = MSG_HANDLED;
|
2019-08-11 15:15:14 +03:00
|
|
|
Widget *owner = WIDGET (GROUP (w->owner));
|
2019-11-17 17:02:52 +03:00
|
|
|
|
|
|
|
if (enable)
|
|
|
|
w->state |= state;
|
|
|
|
else
|
|
|
|
w->state &= ~state;
|
|
|
|
|
|
|
|
if (enable)
|
|
|
|
{
|
|
|
|
/* exclusive bits */
|
2023-01-06 13:00:15 +03:00
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case WST_CONSTRUCT:
|
2019-11-17 17:02:52 +03:00
|
|
|
w->state &= ~(WST_ACTIVE | WST_SUSPENDED | WST_CLOSED);
|
2023-01-06 13:00:15 +03:00
|
|
|
break;
|
|
|
|
case WST_ACTIVE:
|
2019-11-17 17:02:52 +03:00
|
|
|
w->state &= ~(WST_CONSTRUCT | WST_SUSPENDED | WST_CLOSED);
|
2023-01-06 13:00:15 +03:00
|
|
|
break;
|
|
|
|
case WST_SUSPENDED:
|
2019-11-17 17:02:52 +03:00
|
|
|
w->state &= ~(WST_CONSTRUCT | WST_ACTIVE | WST_CLOSED);
|
2023-01-06 13:00:15 +03:00
|
|
|
break;
|
|
|
|
case WST_CLOSED:
|
2019-11-17 17:02:52 +03:00
|
|
|
w->state &= ~(WST_CONSTRUCT | WST_ACTIVE | WST_SUSPENDED);
|
2023-01-06 13:00:15 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2019-11-17 17:02:52 +03:00
|
|
|
}
|
|
|
|
|
2019-08-11 15:15:14 +03:00
|
|
|
if (owner == NULL)
|
2019-11-17 17:02:52 +03:00
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
2019-08-11 15:15:14 +03:00
|
|
|
case WST_VISIBLE:
|
|
|
|
if (widget_get_state (owner, WST_ACTIVE))
|
|
|
|
{
|
|
|
|
/* redraw owner to show/hide widget */
|
|
|
|
widget_draw (owner);
|
|
|
|
|
|
|
|
if (!enable)
|
|
|
|
{
|
|
|
|
/* try select another widget if current one got hidden */
|
|
|
|
if (w == GROUP (owner)->current->data)
|
|
|
|
group_select_next_widget (GROUP (owner));
|
|
|
|
|
|
|
|
widget_update_cursor (owner); /* FIXME: unneeded? */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2019-11-17 17:02:52 +03:00
|
|
|
case WST_DISABLED:
|
|
|
|
ret = send_message (w, NULL, enable ? MSG_DISABLE : MSG_ENABLE, 0, NULL);
|
2019-08-11 15:15:14 +03:00
|
|
|
if (ret == MSG_HANDLED && widget_get_state (owner, WST_ACTIVE))
|
2019-11-17 17:02:52 +03:00
|
|
|
ret = widget_draw (w);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WST_FOCUSED:
|
|
|
|
{
|
|
|
|
widget_msg_t msg;
|
|
|
|
|
|
|
|
msg = enable ? MSG_FOCUS : MSG_UNFOCUS;
|
|
|
|
ret = send_message (w, NULL, msg, 0, NULL);
|
2019-08-11 15:15:14 +03:00
|
|
|
if (ret == MSG_HANDLED && widget_get_state (owner, WST_ACTIVE))
|
2019-11-17 17:02:52 +03:00
|
|
|
{
|
|
|
|
widget_draw (w);
|
|
|
|
/* Notify owner that focus was moved from one widget to another */
|
2019-08-11 15:15:14 +03:00
|
|
|
send_message (owner, w, MSG_CHANGED_FOCUS, 0, NULL);
|
2019-11-17 17:02:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-31 19:32:29 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Default callback function to destroy widget.
|
|
|
|
*
|
|
|
|
* @param w widget
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
widget_default_destroy (Widget *w)
|
2020-10-31 19:32:29 +03:00
|
|
|
{
|
|
|
|
send_message (w, NULL, MSG_DESTROY, 0, NULL);
|
|
|
|
g_free (w);
|
|
|
|
}
|
|
|
|
|
2013-02-11 15:35:00 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2011-03-21 16:43:56 +03:00
|
|
|
/* get mouse pointer location within widget */
|
2013-06-24 10:47:03 +04:00
|
|
|
|
2011-03-21 16:43:56 +03:00
|
|
|
Gpm_Event
|
2024-06-01 21:12:14 +03:00
|
|
|
mouse_get_local (const Gpm_Event *global, const Widget *w)
|
2011-03-21 16:43:56 +03:00
|
|
|
{
|
|
|
|
Gpm_Event local;
|
|
|
|
|
2020-12-07 16:41:18 +03:00
|
|
|
memset (&local, 0, sizeof (local));
|
|
|
|
|
2011-03-21 16:43:56 +03:00
|
|
|
local.buttons = global->buttons;
|
2022-05-01 10:43:33 +03:00
|
|
|
local.x = global->x - w->rect.x;
|
|
|
|
local.y = global->y - w->rect.y;
|
2011-03-21 16:43:56 +03:00
|
|
|
local.type = global->type;
|
|
|
|
|
|
|
|
return local;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
gboolean
|
2024-06-01 21:12:14 +03:00
|
|
|
mouse_global_in_widget (const Gpm_Event *event, const Widget *w)
|
2011-03-21 16:43:56 +03:00
|
|
|
{
|
2022-05-01 10:43:33 +03:00
|
|
|
const WRect *r = &w->rect;
|
|
|
|
|
|
|
|
return (event->x > r->x) && (event->y > r->y) && (event->x <= r->x + r->cols)
|
|
|
|
&& (event->y <= r->y + r->lines);
|
2011-03-21 16:43:56 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|