Añadir Popup Menu A Text Box


Goto page 1, 2  Next

Subject: Añadir Popup Menu A Text Box
Hola a todos.
Estoy haciendo un programa con una BD y al añadir un popup menu al textbox me remplaza el menu por defecto del textbox por el que yo añado

PUBLIC SUB txtId_cliente_Menu()

ME.Menu4.Popup()

END



alquien sabe como añadir mi ME.Menu4.Popup() al menu que trae por defecto el textbox el copy paste, redo, undo etc.

No quiero perder Undo y Redo que trae por defecto el textbox

Profile PM  
Subject: Re: Añadir Popup Menu A Text Box
angelnu, me trajiste a la mente vagos recuerdos sobre las capacidades de fusión de los menús en Delphi 1.0

No sé si habrá otra forma de hacerlo, pero una manera es que incluyas en tu menú personalizado todas las opciones que necesites, luego escribas manejadores de evento para cada opción del menú y en cada uno de ellos las llamadas a métodos que sean necesarias (o tus propios algoritmos). Ejemplo:
PUBLIC SUB mnuContextualDoSomething_Click()
txtCliente.SelectAll
END

Respecto de Undo y Redo creo que no existen en TextBox, sino en TextArea, TextEdit y Editor.

Last edited by fabianfv on Thursday, 21 October 2010, 20:38; edited 1 time in total
Subject: Re: Añadir Popup Menu A Text Box
Citar:
Respecto de Undo y Redo creo que no existen en TextBox, sino en TextArea, TextEdit y Editor

Pero se pueden implementar con cierta facilidad

Primero hago una clase para un nuevo control TextBox que tendrá la posibilidad de undo. Para facilitar la comprensión pondré que el undo pueda hacerse a un solo nivel (que solo recuerde el último cambio).

Me creo la clase Utextbox y en ella pongo:
inherits textbox

Property Undo as string
dim $Undo as string

function Undo_read() as string
return $Undo
end

sub Undo_write(valor as string)
$Undo=valor
end


Se puede complicar mas para hacerlo mas funcional (por ejemplo la propiedad undo podría ser de solo lectura) y podría haber varios niveles si $Undo fuera un array pero interesa entenderlo.

El caso es que si yo tengo una clase como esta en mi proyecto cuando quisiera un textbox con undo lo que haría es

'crear el nuevo objeto
Dim T as NEW Utextbox


'darle las propiedades que quiera.
T.Top=xx
T.left=xx
T.width=xx
T.height=xx
...

'definirle el evento change
public sub T_change()
T.Undo=T.text
end


Y ahora definir el evento keypress de tal manera que si se pulsa CTRL-U se haga el undo
public sub T_keypress()
IF Key.Code = Key["U"] AND IF Key.Control THEN
T.text=T.Undo
END IF
end


Sobre esto todo lo que se quiera trabajar. Por ejemplo se le puede convertir en un componente y tenerlo disponible como un componente mas de gambas, ...

Last edited by soplo on Thursday, 21 October 2010, 23:22; edited 1 time in total
Profile PM  
Subject: Re: Añadir Popup Menu A Text Box
Muy interesante lo de deshacer, intentare hacerlo para mas de un paso.

Saludos

Subject: Re: Añadir Popup Menu A Text Box
Gracias por responder.

Creo que no me he explicado bien, en efecto el control textbox no tiene la propiedad redo ni undo, pero en tiempo de ejecución al hacer ckik con el boton derecho tienes un menu con redo undo copy paste etc. (en gb.qt) en gb.gtk ya no tienes redo y undo.


Mi pregunta era que si al menú en tiempo de ejecucion se le podria añadir un nuevo menu (sin que este nuevo menu substituya al menú que sale por defecto en tiempo de ejecucion) , para aprovechar esas propiedades sin tener que implementar código para redo y undo.



Un saludo

Angel

Profile PM  
Subject: Re: Añadir Popup Menu A Text Box
Citar:

Creo que no me he explicado bien, en efecto el control textbox no tiene la propiedad redo ni undo, pero en tiempo de ejecución al hacer ckik con el boton derecho tienes un menu con redo undo copy paste etc. (en gb.qt) en gb.gtk ya no tienes redo y undo.

Sí te has explicado bien. Efectivamente, hasta hace algunas versiones el control TextBox del componente gb.qt sí tenía incorporados los métodos Redo y Undo. Parece que fueron eliminados en las versiones más actuales, con lo que el estado es un poco inconsistente porque como bien dices aún aparece el menú contextual con dichas opciones; también puedes hacer Undo/Redo pulsando Control + Z y Control + Mayusculas + Y.

Citar:

Mi pregunta era que si al menú en tiempo de ejecucion se le podria añadir un nuevo menu (sin que este nuevo menu substituya al menú que sale por defecto en tiempo de ejecucion) , para aprovechar esas propiedades sin tener que implementar código para redo y undo.


No conozco que exista ninguna característica para mezclar menús. Pero en primer lugar el problema sería como acceder desde el código a ese menú contextual. Me parece que la existencia de ese menú muestra que hay algo que los desarrolladores olvidaron manejar desde el componente gb.qt. Creo que dicho menú es provisto directamente por QT y que no hay una forma de acceder a el desde el código de gambas.

De todos modos, esas opciones Undo y Redo del menú contextual (o la alternativa de pulsar las combinaciones de teclas correspondientes) tienen un par de problemas:

  • Las opciones del menú están en inglés y no las puedes traducir si desde gambas no tienes acceso a dicho menú.
  • El funcionamiento de esas opciones me parece un poco extraño, ¿las probaste? No está claro cuál es la unidad de texto que permite Deshacer/Rehacer ¿caracteres, palabras, líneas? Pruébalo y verás de qué estoy hablando. Me parece que funciona con un timer, es decir toma el contenido del TextBox cada cierto tiempo (lo que me parece una locura).

Entonces, podrías crear tu propio menú con todas las opciones que necesites y escribir los correspondientes manejadores de eventos para las opciones del menú. En el caso de las opciones Deshacer/Rehacer escribir en sus manejadores de evento algo así (requiere gb.desktop):

PUBLIC SUB Deshacer_Click()
Desktop.SendKeys("{[Control_L]U}")
END

PUBLIC SUB Rehacer_Click()
Desktop.SendKeys("{[Control_L][Shift_R]Y}")
END


Para simular que se pulsan las combinaciones de teclas Control + U y Control + Mayusculas + Y.

Pero me parece que la solución pasa por que crees tu propio menú contextual con todas las opciones que necesitas e implementes la funcionalidad para ellas.

Para tener la características de Deshacer/Rehacer primero debes definir a qué nivel quieres permitir tales operaciones, por ejemplo:

* Por caracter (deberías usar el evento Keypress para capturar cada caracter)
* Por palabra (deberías usar el evento Change para capturar cada palabra)
* Por línea (me parece que tu caso no tiene sentido)

Luego, todo lo que necesitas es un array de tipo String donde guardar el contenido del TextBox, que recorrerás hacia adelante o hacia atrás dependiendo de la opción elegida en el menú (o de la combinación de teclas pulsada).

Subject: Re: Añadir Popup Menu A Text Box
erer

EXPORT

INHERITS TextBox

PRIVATE MiTexto AS String[] 'almacena el texto
PRIVATE indice AS Integer ' numero de elementos del array
PRIVATE DondeEstoy AS Integer ' posicion dentro del array
PRIVATE $hObserver AS Observer ' interceptar el evento change del textbox
PRIVATE BolDeshago AS Boolean ' bandera para no disparar el evento change cada vez que deshacemos o rehacemos

PUBLIC SUB _new()


MiTexto = NEW String[]
MiTexto.Add(SUPER.Text, 0)
$hObserver = NEW Observer(ME) AS "TextBox"

END

PUBLIC SUB TextBox_Change()

IF BolDeshago THEN
STOP EVENT
ELSE
indice += 1
MiTexto.Add(SUPER.Text, indice)
DondeEstoy = indice
ENDIF

END

PUBLIC SUB Deshacer()

IF indice > 0 AND DondeEstoy > 0 THEN
BolDeshago = TRUE
DondeEstoy -= 1
SUPER.Text = MiTexto[DondeEstoy]
BolDeshago = FALSE
ENDIF

END

PUBLIC SUB Rehacer()

IF indice > 0 AND DondeEstoy < indice THEN
BolDeshago = TRUE
DondeEstoy += 1
SUPER.Text = MiTexto[DondeEstoy]
BolDeshago = FALSE
ENDIF

END

Profile PM  
Subject: Re: Añadir Popup Menu A Text Box
Ese código de AngelNu es muy interesante. Va varios pasos mas allá del simplón que puse para explicar como se hace el undo. Fijaos como crea un nuevo control de clase textbox y le crea sus propios eventos con su propio observador de eventos y con varios niveles de undo.

Muy adaptable a otros casos. Por ejemplo se me ocurre hacer un listbox con su propio itemdata como en vB. En este caso querían un undo. En otro puedes querer agregar o cambiar cualquier cualidad de otro control.

Como veis no es ni largo ni complicado. Solo es tener claros algunos coneptos y aplicarlos debidamente. Ese código es bien pequeñito pero muy útil.

¡Estupendo!

Profile PM  
Subject: Re: Añadir Popup Menu A Text Box
Perdón envié una prueba por error ya que no sabia como resaltar el código en los mensajes.
Ante todo dar las gracias por vuestras respuestas a fabianfv a soplo me habéis aclarado algunos conceptos y a jsbsan que en su blog tiene un ejemplo supergridviews2.
He creado un nuevo control y parece que funciona pero en tiempo de diseño en la caja de herramientas sale un signo de interrogación en vez del icono del textbox y al poner el control en el formulario el texto que se ve es el nombre del control no la propiedad text, supongo que me falta algo poro como estees mi primer control pues no tengo ni idea.

Al código de antes hay que añadirle un método para limpiar el array ya que crece indefinidamente.

El código se quedaría así

EXPORT

INHERITS TextBox

PRIVATE MiTexto AS String[] 'almacena el texto
PRIVATE indice AS Integer ' numero de elementos del array
PRIVATE DondeEstoy AS Integer ' posicion dentro del array
PRIVATE $hObserver AS Observer ' interceptar el evento change del textbox
PRIVATE BolDeshago AS Boolean ' bandera para no disparar el evento change cada vez que deshacemos o rehacemos

PUBLIC SUB _new()


MiTexto = NEW String[]
MiTexto.Add(SUPER.Text, 0)
$hObserver = NEW Observer(ME) AS "TextBox"

END

PUBLIC SUB TextBox_Change()

IF BolDeshago THEN
STOP EVENT
ELSE
indice += 1
MiTexto.Add(SUPER.Text, indice)
DondeEstoy = indice
ENDIF

END

PUBLIC SUB Deshacer()

IF indice > 0 AND DondeEstoy > 0 THEN
BolDeshago = TRUE
DondeEstoy -= 1
SUPER.Text = MiTexto[DondeEstoy]
BolDeshago = FALSE
ENDIF

END

PUBLIC SUB Rehacer()

IF indice > 0 AND DondeEstoy < indice THEN
BolDeshago = TRUE
DondeEstoy += 1
SUPER.Text = MiTexto[DondeEstoy]
BolDeshago = FALSE
ENDIF

END

PUBLIC SUB Limpiar_Deshacer()

MiTexto.Clear
MiTexto.Add("", 0) 'Añadimos un elemento vacio
indice = 0
BolDeshago = FALSE
DondeEstoy = 0

END


Creo que hay que cambiar el titulo por otro mas descriptivo

Profile PM  
Subject: Re: Añadir Popup Menu A Text Box
Citar:

He creado un nuevo control y parece que funciona pero en tiempo de diseño en la caja de herramientas sale un signo de interrogación en vez del icono del textbox

Debes crear una carpeta llamada "control" dentro de la carpeta del proyecto (puedes hacerlo desde el mismo IDE) y colocar allí un icono para el control en formato png que debe llevar el mismo nombre que la clase en minúsculas.
Citar:

y al poner el control en el formulario el texto que se ve es el nombre del control no la propiedad text, supongo que me falta algo

Eso no importa, porque en tiempo de ejecución funcionará como es de esperar. Pero si quieres que se dibuje como un TextBox:
'Para que el control se dibuje como un TextBox
PUBLIC CONST _DrawWith AS String = "TextBox"

Citar:

Al código de antes hay que añadirle un método para limpiar el array ya que crece indefinidamente.

O podrías ponerle un límite, es decir que sólo se pueda Deshacer/Rehacer x cantidad de acciones, permitiendo que sea configurable, es decir que ese límite se establezca por medio de una variable de instancia.

Por otra parte, fíjate que si quisieras incorporar esta característica a otros programas/clases/controles, te verías obligado a copiar y pegar el código. Esto es contrario a la POO. Observa que si creas una clase que tenga la responsabilidad de proveer esta característica, podrías simplemente agregarla como un componente (Gambas2) o biblioteca (Gambas3) y su reutilización sería más sencilla (no tendrías que copiar y pegar código). Es decir, que cuando quieras añadir esta característica en una clase, simplemente deberías crear una variable de instancia que tenga como tipo de dato la clase contenida en dicho componente. Ejemplo:

'Clase NecesitoUndoRedo

'Renunciando a la originalidad, la clase que provee las facilidades para deshacer/rehacer se llama UndoRedo
PRIVATE myUndoRedo AS UndoRedo

PUBLIC SUB _New()
myUndoRedo = NEW UndoRedo()
END

...

myUndoRedo.Undo()


Goto page 1, 2  Next

Page 1 of 2


  
You cannot post new topics
You cannot reply to topics
You cannot edit your posts
You cannot delete your posts
You cannot vote in polls
You cannot attach files
You can download files
You cannot post calendar events

   

This is a "Lo-Fi" version of our main content. To view the full version with more information, formatting and images, please click here.

Powered by Icy Phoenix based on phpBB
Design by DiDiDaDo

Generation Time: 0.1608s (PHP: -18% SQL: 118%)
SQL queries: 24 - Debug Off - GZIP Enabled