12 Control de deslizador

El uso más frecuente de un control de deslizamiento, o slider es mostrar el progreso de algún tipo de documento, y permitir al usuario modificar el punto de reproducción a discreción. Por ejemplo, en la reproducción de video, audio, o de un documento de texto. Cuando la reproducción está activada, su avance es automático, pero el usuario siempre puede detenerla, avanzar o retroceder, volver al principio, etc.
También se puede usar para leer un valor entero entre un rango determinado. El valor mínimo del rango no tiene que ser obligatoriamente 0. En este caso funciona como un control de volumen de sonido, por ejemplo.
Se encapsula en la clase wxSlider.
Visualmente es muy similar a un control de desplazamiento, aunque la barra puede estar acompañada de marcas (ticks), se permite añadir etiquetas con los valores máximo, mínimo y actual, y el cursor tiene un tamaño fijo, y es más pequeño, ya que no representa un fragmento del documento total, sino un punto dentro del rango establecido. Tampoco dispone de los botones en los extremos para mover el cursor una línea.
A nivel de funcionamiento también es muy similar a un control de desplazamiento, hasta el punto que comparte sus eventos, y usa la misma clase para manejar esos eventos.
Estilos
Algunos estilos afectan al aspecto del control como:
- wxSL_HORIZONTAL y wxSL_VERTICAL permiten elegir la orientación del control.
- wxSL_AUTOTICKS activa las marcas de ticks, que forman una escala graduada. Por defecto se muestra una marca por cada valor posible en el rango, aunque esto se puede modificar, al menos en algunas plataformas.
- wxSL_LEFT y wxSL_RIGHT muestra los ticks a izquierda o derecha y además fuerza el estilo wxSL_VERTICAL. wxSL_TOP y wxSL_BOTTOM muestra los ticks en la parte superior o inferior. wxSL_BOTH muestra los ticks en ambas partes.
- wxSL_MIN_MAX_LABELS muestra las etiquetas de mínimo y máximo. wxSL_VALUE_LABEL muestra la etiqueta de valor. Y wxSL_LABELS muestra ambas etiquetas.
- wxSL_INVERSE invierte las posiciones de los valores máximo y mínimo del rango, mostrando el máxima a la izquierda o arriba, dependiendo de la orientación.
Existe otro estilo, wxSL_SELRANGE, sólo disponible en Windows, que permite seleccionar un rango de valores, en lugar de un único valor. En este curso evitaremos usar características que no estén disponibles en todas las plataformas, de modo que no usaremos este estilo.
Eventos
Estos controles usan la misma clase para enviar eventos que wxScrollBar, wxScrollEvent de modo que lo dicho para esos controles se puede aplicar a los controles wxSlider con muy pocas diferencias
De nuevo, podemos dividir estas macros en dos grupos:
- Las que empiezan con EVT_SCROLL. Estas macros no diferencian el control que emite el evento. Todos los controles wxSlider, si hay más de uno, se procesarán usando las mismas funciones para cada evento.
- Las que empiezan con EVT_COMMAND_SCROLL. Estas macros asignan funciones diferentes para cada wxSlider, de modo que se usarán funciones separadas para cada control y evento.
No existen eventos separados para diferentes estilos de controles. Por ejemplo, la dirección hacia arriba corresponde a la dirección izquierda si el control tiene orientación horizontal. El tope superior corresponde al tope izquierdo en controles horizontales, etc.
A su vez, cada uno de esos grupos se puede dividir en otros:
Eventos que se emiten cuando el cursor llega a las posiciones en el extremo del control: EVT_SCROLL_TOP y EVT_SCROLL_BOTTOM, y sus equivalentes EVT_COMMAND_SCROLL_TOP y EVT_COMMAND_SCROLL_BOTTOM.
Eventos por desplazamientos de una línea, que como estos controles no tienen los botones en los extremos del control, se envían cuando se pulsan las teclas de dirección: EVT_SCROLL_LINEUP y EVT_SCROLL_LINEDOWN, y sus equivalentes EVT_COMMAND_SCROLL_LINEUP y EVT_COMMAND_SCROLL_LINEDOWN.
Eventos por desplazamiento de una página, cuando se activa una de las áreas junto al cursor, o mediante las teclas de avance y retroceso de página: EVT_SCROLL_PAGEUP y EVT_SCROLL_PAGEDOWN y sus equivalentes EVT_COMMAND_SCROLL_PAGEUP y EVT_COMMAND_SCROLL_PAGEDOWN.
Eventos cuando el usuario arrastra el cursor. Estos eventos se envían con más frecuencia mientras se produce ese arrastre: EVT_SCROLL_THUMBTRACK y EVT_COMMAND_SCROLL_THUMBTRACK.
Eventos cuando el usuario libera el cursor: EVT_SCROLL_THUMBRELEASE y EVT_COMMAND_SCROLL_THUMBRELEASE.
Sólo en Windows existe otro evento, EVT_SCROLL_CHANGED, que se emite cada vez que el valor del control cambia, y su equivalente EVT_COMMAND_SCROLL_CHANGED.
En general podemos optar por usar sólo la macro EVT_SCROLL, que agrupará todos los eventos anteriores en una única función, o su equivalente EVT_COMMAND_SCROLL.
Cuando optemos por usar EVT_SCROLL, necesitaremos diferenciar qué tipo de evento hemos recibido. Para ello podemos usar el método GetEventType, heredado de wxEvent, necesitaremos determinar qué control ha enviado el evento. Para ello podemos usar el método GetId, también heredado de wxEvent.
Probablemente sea preferible, para que el código quede más claro, usar el evento EVT_SLIDER cuando queramos procesar todos los eventos usando el mismo método. En ese caso, el valor del control se puede recuperar usando el método GetInt de wxCommandEvent.
Para terminar, la clase wxScrollEvent también dispone de un método para obtener el valor del control, GetPosition.
Evento EVT_SLIDER
La única diferencia en lo que respecta a eventos con wxScrollBar es que estos controles también generan un evento EVT_SLIDER, que se genera cada vez que el control cambia su valor. Además, estos eventos usan un objeto wxCommandEvent en lugar de un wxScrollEvent.
Insertar controles slider
El constructor tiene diez parámetros. Después de los habituales, ventana padre y identificador, se puede especificar el valor actual, el rango mínimo y el máximo. Después siguen la posición, tamaño, estilos, validador y nombre.
m_slider = new wxSlider(this, idSlider, 0, -100, 100, wxDefaultPosition, wxSize(500,50), wxSL_HORIZONTAL | wxSL_AUTOTICKS | wxSL_TOP | wxSL_LABELS | wxSL_SELRANGE, slValidator(&datos.valor));
A la hora de personalizar el control, podemos modificar algunas de sus propiedades. Por ejemplo, si hemos activado el estilo wxSL_AUTOTICKS, dependiendo de los valores de rango, es probable que las marcas estén demasiado juntas. Podemos establecer cada cuantos valores se añadirá una marca usando el método SetTickFreq. O añadir marcas individuales con SetTick.
m_slider->SetTickFreq(5);
Los tamaños de línea y página también se pueden modificar usando los métodos SetLineSize y SetPageSize.
Si fuese necesario, también podemos modificar el rango, mediante SetMin y SetMax, o ambos a la vez con SetRange.
Para establecer la posición disponemos de SetValue, y para recuperarla GetValue.
Validadores
Como disponemos de un parámetro para asignar un valor inicial, nuestro validador sólo necesitaría implementar el método TransferFromWindow. Y para el método TrasnferToWindow simplemente retornamos true:
class slValidator : public wxValidator { public: slValidator(int *v = nullptr) : m_valor(v) {} virtual wxObject* Clone() const { return new slValidator(*this); } virtual bool TransferFromWindow(); virtual bool TransferToWindow() { return true; } virtual bool Validate(wxWindow * parent) { return true; } private: int* m_valor; DECLARE_DYNAMIC_CLASS( slValidator ) DECLARE_EVENT_TABLE() };
La implementación es simple:
IMPLEMENT_DYNAMIC_CLASS( slValidator, wxValidator ) BEGIN_EVENT_TABLE( slValidator, wxValidator ) END_EVENT_TABLE() bool slValidator::TransferFromWindow() { try { wxSlider *sb = dynamic_cast<wxSlider*>(m_validatorWindow); *m_valor = sb->GetValue(); } catch (...) { wxFAIL_MSG( _T("slValidator sólo funciona con wxSlider")); return false; } return true; }
Procesar eventos
Todo lo dicho para el procesado de eventos en controles wxScrollBar es aplicable a controles wxSlider.
Sólo añadir que también disponemos del evento EVT_SLIDER, que se genera cada vez que el control cambia su valor:
wxBEGIN_EVENT_TABLE(slider, wxDialog) EVT_CLOSE(slider::OnClose) EVT_SLIDER(idSlider, slider::OnSlider) wxEND_EVENT_TABLE() ... void slider::OnSlider(wxCommandEvent& event) { wxString cad; cad << "Valor: " << event.GetInt(); wxMessageBox(cad, _T("Slider")); }
Ejemplo 12
Nombre | Fichero | Fecha | Tamaño | Contador | Descarga |
---|---|---|---|---|---|
Ejemplo 12 | wx012.zip | 2024-12-03 | 5102 bytes | 9 |