mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Add WScrollBar.
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
d84b98af3b
commit
8912ba1c8e
@ -31,6 +31,7 @@ typedef struct WDialog WDialog;
|
||||
#include "lib/widget/input.h"
|
||||
#include "lib/widget/listbox-window.h"
|
||||
#include "lib/widget/quick.h"
|
||||
#include "lib/widget/scrollbar.h"
|
||||
#include "lib/widget/wtools.h"
|
||||
#include "lib/widget/dialog-switch.h"
|
||||
|
||||
|
@ -19,6 +19,7 @@ libmcwidget_la_SOURCES = \
|
||||
menu.c menu.h \
|
||||
quick.c quick.h \
|
||||
radio.c radio.h \
|
||||
scrollbar.c scrollbar.h \
|
||||
widget-common.c widget-common.h \
|
||||
wtools.c wtools.h
|
||||
|
||||
|
@ -124,6 +124,9 @@ history_dlg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, v
|
||||
case MSG_RESIZE:
|
||||
return history_dlg_reposition (DIALOG (w));
|
||||
|
||||
case MSG_ACTION:
|
||||
return dlg_broadcast_msg_to (DIALOG (w), msg, FALSE, 0);
|
||||
|
||||
default:
|
||||
return dlg_default_callback (w, sender, msg, parm, data);
|
||||
}
|
||||
@ -358,6 +361,18 @@ history_show (GList ** history, Widget * widget, int current)
|
||||
listbox_select_entry (query_list, current);
|
||||
}
|
||||
|
||||
if (!mc_global.tty.slow_terminal)
|
||||
{
|
||||
WScrollBar *scrollbar;
|
||||
|
||||
scrollbar = scrollbar_new (WIDGET (query_list), SCROLLBAR_VERTICAL);
|
||||
scrollbar_set_current (scrollbar, &query_list->pos);
|
||||
scrollbar_set_total (scrollbar, &query_list->count);
|
||||
scrollbar_set_first_displayed (scrollbar, &query_list->top);
|
||||
|
||||
add_widget (query_dlg, scrollbar);
|
||||
}
|
||||
|
||||
if (dlg_run (query_dlg) != B_CANCEL)
|
||||
{
|
||||
char *q;
|
||||
|
@ -80,44 +80,6 @@ listbox_entry_free (void *data)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
listbox_drawscroll (WListbox * l)
|
||||
{
|
||||
Widget *w = WIDGET (l);
|
||||
int max_line = w->lines - 1;
|
||||
int line = 0;
|
||||
int i;
|
||||
|
||||
/* Are we at the top? */
|
||||
widget_move (w, 0, w->cols);
|
||||
if (l->top == 0)
|
||||
tty_print_one_vline (TRUE);
|
||||
else
|
||||
tty_print_char ('^');
|
||||
|
||||
/* Are we at the bottom? */
|
||||
widget_move (w, max_line, w->cols);
|
||||
if ((l->top + w->lines == l->count) || (w->lines >= l->count))
|
||||
tty_print_one_vline (TRUE);
|
||||
else
|
||||
tty_print_char ('v');
|
||||
|
||||
/* Now draw the nice relative pointer */
|
||||
if (l->count != 0)
|
||||
line = 1 + ((l->pos * (w->lines - 2)) / l->count);
|
||||
|
||||
for (i = 1; i < max_line; i++)
|
||||
{
|
||||
widget_move (w, i, w->cols);
|
||||
if (i != line)
|
||||
tty_print_one_vline (TRUE);
|
||||
else
|
||||
tty_print_char ('*');
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
listbox_draw (WListbox * l, gboolean focused)
|
||||
{
|
||||
@ -172,12 +134,6 @@ listbox_draw (WListbox * l, gboolean focused)
|
||||
}
|
||||
|
||||
l->cursor_y = sel_line;
|
||||
|
||||
if (l->scrollbar && (l->count > w->lines))
|
||||
{
|
||||
tty_setcolor (normalc);
|
||||
listbox_drawscroll (l);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -535,7 +491,6 @@ listbox_new (int y, int x, int height, int width, gboolean deletable, lcback_fn
|
||||
l->deletable = deletable;
|
||||
l->callback = callback;
|
||||
l->allow_duplicates = TRUE;
|
||||
l->scrollbar = !mc_global.tty.slow_terminal;
|
||||
widget_want_hotkey (w, TRUE);
|
||||
widget_want_cursor (w, FALSE);
|
||||
|
||||
|
@ -50,7 +50,6 @@ typedef struct WListbox
|
||||
int top; /* The first element displayed */
|
||||
int count; /* Number of items in the listbox */
|
||||
gboolean allow_duplicates; /* Do we allow duplicates on the list? */
|
||||
gboolean scrollbar; /* Draw a scrollbar? */
|
||||
gboolean deletable; /* Can list entries be deleted? */
|
||||
lcback_fn callback; /* The callback function */
|
||||
int cursor_x, cursor_y; /* Cache the values */
|
||||
|
285
lib/widget/scrollbar.c
Normal file
285
lib/widget/scrollbar.c
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
Widgets for the Midnight Commander: scrollbar
|
||||
|
||||
Copyright (C) 2014
|
||||
The Free Software Foundation, Inc.
|
||||
|
||||
Authors:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2014
|
||||
|
||||
This file is part of the Midnight Commander.
|
||||
|
||||
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,
|
||||
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
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file scrollbar.c
|
||||
* \brief Source: WScrollBar widget
|
||||
*/
|
||||
|
||||
#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 ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
scrollbar_set_size (WScrollBar *scrollbar)
|
||||
{
|
||||
Widget *w = WIDGET (scrollbar);
|
||||
Widget *p = scrollbar->parent;
|
||||
Widget *o = WIDGET (p->owner);
|
||||
int py = p->y;
|
||||
int px = p->x;
|
||||
|
||||
/* There folloing cases are possible here:
|
||||
1. Parent is in dialog, scrollbar isn't.
|
||||
Parents coordinates are absolute. Scrollbar's coordinate are relative to owner.
|
||||
We need relative parent's coordinates here to place scrollbar properly.
|
||||
2. Parent and scrollbar are in dialog.
|
||||
Parent's and scrollbar's coordinates are absolute. Use them.
|
||||
3. Parent and scrollbar aren't in dialog.
|
||||
Parent's and scrollbar's coordinates are relative to owner. Use them.
|
||||
4. Parent isn't in dialog, scrollbar is.
|
||||
This is abnormal and should not happen. */
|
||||
|
||||
if (o != NULL && w->owner == NULL)
|
||||
{
|
||||
/* Get relative parent's coordinates */
|
||||
py -= o->y;
|
||||
px -= o->x;
|
||||
}
|
||||
|
||||
switch (scrollbar->type)
|
||||
{
|
||||
case SCROLLBAR_VERTICAL:
|
||||
w->y = py;
|
||||
w->x = px + p->cols;
|
||||
w->lines = p->lines;
|
||||
w->cols = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
w->x = px;
|
||||
w->y = py + p->lines;
|
||||
w->cols = p->cols;
|
||||
w->lines = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
scrollbar_draw_horizontal (WScrollBar * scrollbar)
|
||||
{
|
||||
Widget *w = WIDGET (scrollbar);
|
||||
int column = 0;
|
||||
int i;
|
||||
|
||||
/* Now draw the nice relative pointer */
|
||||
if (*scrollbar->total != 0)
|
||||
column = *scrollbar->current * w->cols / *scrollbar->total;
|
||||
|
||||
for (i = 0; i < w->cols; i++)
|
||||
{
|
||||
widget_move (w, 0, i);
|
||||
if (i != column)
|
||||
tty_print_char ('!');
|
||||
else
|
||||
tty_print_char ('+');
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
scrollbar_draw_vertical (WScrollBar * scrollbar)
|
||||
{
|
||||
Widget *w = WIDGET (scrollbar);
|
||||
int line = 0;
|
||||
int i;
|
||||
|
||||
/* Now draw the nice relative pointer */
|
||||
if (*scrollbar->total != 0)
|
||||
line = *scrollbar->current * w->lines / *scrollbar->total;
|
||||
|
||||
for (i = 0; i < w->lines; i++)
|
||||
{
|
||||
widget_move (w, i, 0);
|
||||
if (i != line)
|
||||
tty_print_char ('|');
|
||||
else
|
||||
tty_print_char ('+');
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
scrollbar_draw (WScrollBar * scrollbar)
|
||||
{
|
||||
// const gboolean disabled = (scrollbar->parent->options & W_DISABLED) != 0;
|
||||
// const int normalc = disabled ? DISABLED_COLOR : scrollbar->parent->color[DLG_COLOR_NORMAL];
|
||||
const int normalc = DISABLED_COLOR;
|
||||
|
||||
if (*scrollbar->total <= scrollbar->parent->lines)
|
||||
return;
|
||||
|
||||
tty_setcolor (normalc);
|
||||
|
||||
switch (scrollbar->type)
|
||||
{
|
||||
case SCROLLBAR_VERTICAL:
|
||||
scrollbar_draw_vertical (scrollbar);
|
||||
break;
|
||||
default:
|
||||
scrollbar_draw_horizontal (scrollbar);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static cb_ret_t
|
||||
scrollbar_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
|
||||
{
|
||||
WScrollBar *scrollbar = SCROLLBAR (w);
|
||||
cb_ret_t ret = MSG_HANDLED;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case MSG_INIT:
|
||||
// w->pos_flags = WPOS_KEEP_RIGHT | WPOS_KEEP_BOTTOM;
|
||||
return MSG_HANDLED;
|
||||
|
||||
case MSG_RESIZE:
|
||||
scrollbar_set_size (scrollbar);
|
||||
return MSG_HANDLED;
|
||||
|
||||
case MSG_FOCUS:
|
||||
return MSG_NOT_HANDLED;
|
||||
|
||||
case MSG_ACTION:
|
||||
ret = MSG_NOT_HANDLED;
|
||||
|
||||
case MSG_DRAW:
|
||||
scrollbar_draw (scrollbar);
|
||||
return ret;
|
||||
|
||||
case MSG_DESTROY:
|
||||
return MSG_HANDLED;
|
||||
|
||||
default:
|
||||
return widget_default_callback (w, sender, msg, parm, data);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Create new WScrollBar object.
|
||||
*
|
||||
* @param parent parent widget
|
||||
* @param type type of scrollbar (vertical or horizontal)
|
||||
* @return new WScrollBar object
|
||||
*/
|
||||
|
||||
WScrollBar *
|
||||
scrollbar_new (Widget * parent, scrollbar_type_t type)
|
||||
{
|
||||
WScrollBar *scrollbar;
|
||||
Widget *widget;
|
||||
|
||||
scrollbar = g_new (WScrollBar, 1);
|
||||
scrollbar->type = type;
|
||||
|
||||
widget = WIDGET (scrollbar);
|
||||
widget_init (widget, 1, 1, 1, 1, scrollbar_callback, NULL);
|
||||
|
||||
scrollbar->parent = parent;
|
||||
scrollbar_set_size (scrollbar);
|
||||
|
||||
widget_want_cursor (widget, FALSE);
|
||||
widget_want_hotkey (widget, FALSE);
|
||||
|
||||
return scrollbar;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Set total count of items.
|
||||
*
|
||||
* @param scrollbar WScrollBar object
|
||||
* @param total total count of items
|
||||
*/
|
||||
|
||||
void
|
||||
scrollbar_set_total (WScrollBar * scrollbar, int *total)
|
||||
{
|
||||
if (scrollbar != NULL)
|
||||
scrollbar->total = total;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Set current position of item.
|
||||
*
|
||||
* @param scrollbar WScrollBar object
|
||||
* @param current current position of item
|
||||
*/
|
||||
|
||||
void
|
||||
scrollbar_set_current (WScrollBar * scrollbar, int *current)
|
||||
{
|
||||
if (scrollbar != NULL)
|
||||
scrollbar->current = current;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Set position of first displayed item.
|
||||
*
|
||||
* @param scrollbar WScrollBar object
|
||||
* @param first_displayed position of first displayed item
|
||||
*/
|
||||
|
||||
void
|
||||
scrollbar_set_first_displayed (WScrollBar * scrollbar, int *first_displayed)
|
||||
{
|
||||
if (scrollbar != NULL)
|
||||
scrollbar->first_displayed = first_displayed;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
44
lib/widget/scrollbar.h
Normal file
44
lib/widget/scrollbar.h
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
/** \file scrollbar.h
|
||||
* \brief Header: WScrollBar widget
|
||||
*/
|
||||
|
||||
#ifndef MC__WIDGET_SCROLLBAR_H
|
||||
#define MC__WIDGET_SCROLLBAR_H
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
#define SCROLLBAR(x) ((WScrollBar *)(x))
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCROLLBAR_VERTICAL,
|
||||
SCROLLBAR_HORISONTAL
|
||||
} scrollbar_type_t;
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Widget widget;
|
||||
scrollbar_type_t type;
|
||||
int *total;
|
||||
int *current;
|
||||
int *first_displayed;
|
||||
Widget *parent;
|
||||
} WScrollBar;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
WScrollBar *scrollbar_new (Widget * parent, scrollbar_type_t type);
|
||||
void scrollbar_set_total (WScrollBar * scrollbar, int *total);
|
||||
void scrollbar_set_current (WScrollBar * scrollbar, int *current);
|
||||
void scrollbar_set_first_displayed (WScrollBar * scrollbar, int *first_displayed);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__WIDGET_SCROLLBAR_H */
|
Loading…
Reference in New Issue
Block a user