2 Widget group features module for the Midnight Commander
5 The Free Software Foundation, Inc.
8 Andrew Borodin <aborodin@vmail.ru>, 2020
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 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.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 * \brief Source: widget group features module
36 #include "lib/global.h"
38 #include "lib/widget.h"
40 /*** global variables ****************************************************************************/
42 /*** file scope macro definitions ****************************************************************/
44 /*** file scope type declarations ****************************************************************/
46 /*** file scope variables ************************************************************************/
48 /* --------------------------------------------------------------------------------------------- */
49 /*** file scope functions ************************************************************************/
50 /* --------------------------------------------------------------------------------------------- */
53 group_get_next_or_prev_of (GList
* list
, gboolean next
)
59 WGroup
*owner
= WIDGET (list
->data
)->owner
;
65 l
= g_list_next (list
);
71 l
= g_list_previous (list
);
73 l
= g_list_last (owner
->widgets
);
81 /* --------------------------------------------------------------------------------------------- */
84 group_select_next_or_prev (WGroup
* g
, gboolean next
)
86 if (g
->widgets
!= NULL
&& g
->current
!= NULL
)
88 GList
*l
= g
->current
;
93 l
= group_get_next_or_prev_of (l
, next
);
96 while ((widget_get_state (w
, WST_DISABLED
) || !widget_get_options (w
, WOP_SELECTABLE
))
99 widget_select (l
->data
);
103 /* --------------------------------------------------------------------------------------------- */
104 /*** public functions ****************************************************************************/
105 /* --------------------------------------------------------------------------------------------- */
108 * Insert widget to group before specified widget with specified positioning.
109 * Make the inserted widget current.
111 * @param g WGroup object
112 * @param w widget to be added
113 * @pos positioning flags
114 * @param before add @w before this widget
120 group_add_widget_autopos (WGroup
* g
, void *w
, widget_pos_flags_t pos_flags
, const void *before
)
122 Widget
*wg
= WIDGET (g
);
123 Widget
*ww
= WIDGET (w
);
126 /* Don't accept NULL widget. This shouldn't happen */
129 if ((pos_flags
& WPOS_CENTER_HORZ
) != 0)
130 ww
->x
= (wg
->cols
- ww
->cols
) / 2;
133 if ((pos_flags
& WPOS_CENTER_VERT
) != 0)
134 ww
->y
= (wg
->lines
- ww
->lines
) / 2;
138 ww
->pos_flags
= pos_flags
;
139 ww
->id
= g
->widget_id
++;
141 if (g
->widgets
== NULL
|| before
== NULL
)
143 g
->widgets
= g_list_append (g
->widgets
, ww
);
144 new_current
= g_list_last (g
->widgets
);
150 b
= g_list_find (g
->widgets
, before
);
152 /* don't accept widget not from group. This shouldn't happen */
156 g
->widgets
= g_list_insert_before (g
->widgets
, b
, ww
);
158 new_current
= g_list_previous (b
);
160 new_current
= g_list_last (g
->widgets
);
163 /* widget has been added at runtime */
164 if (widget_get_state (wg
, WST_ACTIVE
))
166 send_message (ww
, NULL
, MSG_INIT
, 0, NULL
);
170 g
->current
= new_current
;
175 /* --------------------------------------------------------------------------------------------- */
178 * Delete widget from group.
180 * @param w Widget object
183 group_del_widget (void *w
)
188 /* Don't accept NULL widget. This shouldn't happen */
191 g
= WIDGET (w
)->owner
;
193 d
= g_list_find (g
->widgets
, w
);
195 group_set_current_widget_next (g
);
197 g
->widgets
= g_list_remove_link (g
->widgets
, d
);
198 if (g
->widgets
== NULL
)
201 /* widget has been deleted at runtime */
202 if (widget_get_state (WIDGET (g
), WST_ACTIVE
))
204 dlg_draw (DIALOG (g
)); /* FIXME */
205 group_select_current_widget (g
);
209 /* --------------------------------------------------------------------------------------------- */
212 * Switch current widget to widget after current in group.
214 * @param g WGroup object
218 group_set_current_widget_next (WGroup
* g
)
220 g
->current
= group_get_next_or_prev_of (g
->current
, TRUE
);
223 /* --------------------------------------------------------------------------------------------- */
225 * Switch current widget to widget before current in group.
227 * @param g WGroup object
231 group_set_current_widget_prev (WGroup
* g
)
233 g
->current
= group_get_next_or_prev_of (g
->current
, FALSE
);
236 /* --------------------------------------------------------------------------------------------- */
238 * Get widget that is after specified widget in group.
240 * @param w widget holder
242 * @return widget that is after "w" or NULL if "w" is NULL or widget doesn't have owner
246 group_get_widget_next_of (GList
* w
)
248 return group_get_next_or_prev_of (w
, TRUE
);
251 /* --------------------------------------------------------------------------------------------- */
253 * Get widget that is before specified widget in group.
255 * @param w widget holder
257 * @return widget that is before "w" or NULL if "w" is NULL or widget doesn't have owner
261 group_get_widget_prev_of (GList
* w
)
263 return group_get_next_or_prev_of (w
, FALSE
);
266 /* --------------------------------------------------------------------------------------------- */
268 * Try to select next widget in the Z order.
270 * @param g WGroup object
274 group_select_next_widget (WGroup
* g
)
276 group_select_next_or_prev (g
, TRUE
);
279 /* --------------------------------------------------------------------------------------------- */
281 * Try to select previous widget in the Z order.
283 * @param g WGroup object
287 group_select_prev_widget (WGroup
* g
)
289 group_select_next_or_prev (g
, FALSE
);
292 /* --------------------------------------------------------------------------------------------- */
294 * Find the widget with the specified ID in the group and select it
296 * @param g WGroup object
297 * @param id widget ID
301 group_select_widget_by_id (const WGroup
* g
, unsigned long id
)
305 w
= dlg_find_by_id (DIALOG (g
), id
);
310 /* --------------------------------------------------------------------------------------------- */