X Picavbg: ecco come ho risolto.
Semplicemente adattando il codice trovato negli esempi di Gambas:
Public Sub Fiches_MouseDrag()
With Last
If Mouse.left Then
If Capitale.value >= CInt(.tag) Then
Drag.icon = .picture
.drag(.picture.image)
Else
Message.Info("Non hai abbastanza soldi.\nAumenta il capitale")
Return
Endif
Endif
End With
End
Tutto qui. E funziona benissimo. ;)
Dopo il drag, arriva il drop.
Public Sub Tavolo_Drop()
fiches.Add(drag.source)
With Last
.
.
'altre istruzioni
.
.
End
Fondamentalmente funziona, ma il problema è nella prima istruzione.
Le picturebox, una volta droppate sulle label che compongono il tavolo (comodissimi i gruppi :ok:), entrano a far parte di un array di picturebox, il guaio è che a me serve una copia della picturebox, invece viene usato l'originale che sparisce dalla posizione originale per finire sul tavolo.
Ho provato varie cose ma questa è l'unica che non mi da errore. :-\
L'array non mi serve per le picturebox originali, quelle sono già dentro in un gruppo e questo è sufficiente. Mi serve per le copie, è su quelle che devo lavorare, le originali devono essere di "sola lettura". Il problema è che non riesco a duplicarle, mi lavora sulle originali.
Ho provato pure ad usare un oggetto temporaneo:
Dim tmp As Object
tmp = New PictureBox(drag.source)
fiches.Add(tmp)
Ma mi da errore, si aspetta una picturebox e invece gli do un contenitore. Boh...
Spero di essermi spiegato.
Niente da fare:
fichestmp.Add(drag.Source)
fiches = fichestmp.Copy
Type mismatch: vuole una picturebox, gli do invece una funzione. Uff... :hatecomputer:
E' stata colpa di una mia imprecisione nel mio precedente suggerimento. :-X
Bisogna assegnare i valori richiesti al metodo .Copy.
Prova così:
Public Sub Tavolo_Drop()
fichestmp.Add(drag.Source)
fiches = fichestmp.Copy(0, fichestmp.Count)
...etc...etc....
Quello non c'è più, ma il problema rimane. Ho idea che dovrò inventarmi qualcosa d'altro. :-\
Poiché avviene uno spostamento fisico dell'oggetto in questione, proporrei di rigenerare l'oggetto (nel nostro caso: la fiche) nel posto e con le medesime caratteristiche di quello spostato con il mouse.
Una cosa di 'sto genere:
Public Sub Fiches_MouseDown() ' Quando si clicca sull'immagine di una fiche...
'...viene generata in sostanza una nuova fiche...
Dim picB As New PictureBox(Me) As "Fiches"
'...avente le caratteristiche di quella sulla quale si è cliccato:
With picB
.X = Last.X
.Y = Last.Y
.W = Last.W
.H = Last.H
.Picture = Last.Picture
.Tag = Last.Tag
End With
End
In questo caso, inoltre, non serve creare una copia dell'array. Quindi avremo:
Public Sub Tavolo_Drop()
fichestmp.Add(drag.Source)
With Last
fichestmp[fichestmp.max].x = Panel1.x + .x + (.width - fichestmp[fichestmp.max].width) \ 2
fichestmp[fichestmp.max].y = Panel1.y + .y + (.height - fichestmp[fichestmp.max].height) \ 2
...etc...etc....
ma addirittura, se non serve ad altro, potresti eliminare l'array stesso:
Public Sub Tavolo_Drop()
With Last
Drag.Source.X = Panel1.x + .x + (.width - Drag.Source.width) \ 2
Drag.Source.Y = Panel1.y + .y + (.height - Drag.Source.height) \ 2
....etc...etc.....etc...
... ma mi sa che è una cosa troppo complicata....
...complicato cambiare le coordinate X e Y di un oggetto ?!
Potrei suggerirti, magari, di introdurre le fiches all'interno del riquadro del numero, scelto dal giocatore, in una posizione casuale. Quindi, volendo vedere le varie fiches lì depositate, si potrebbero spostare - ovviamente all'interno del loro riquadro - sempre in modo casuale, cliccando sopra ciascuna di esse.
Faccio un esempio banale. Poniamo in un form un ampio Panel ed un Button, poi:
Private c As Byte
Public Sub Button1_Click()
Dim tl As TextLabel
Dim a, x, y As Byte
a = Rnd(30, 50)
x = Rnd(Panel1.X, Panel1.W - a)
y = Rnd(Panel1.Y, Panel1.H - a)
With tl = New TextLabel(Frame1) As "tl"
.X = x
.Y = y
.W = a
.H = a
.Text = c
.Border = Border.Sunken
.Background = Color.RGB(a + x, x + y, y + a)
End With
Inc c
End
Public Sub tl_MouseDown()
With Last
.X = Rnd(Panel1.X, Panel1.W - Last.W)
.Y = Rnd(Panel1.Y, Panel1.H - Last.H)
End With
End
Dopo aver creato alcune TextLabel colorate, cliccando varie volte sul Button, se clicchiamo su una TextLabel, la vedremo spostarsi altrove all'interno del Panel.
Non è quello il problema. Quello che vorrei fare è che le fiches piccole appaiano SOPRA quella grandi.
Capisco, suppongo si debba modificare l'ordine gerarchico delle fiches.... ma devi considerare anche il caso in cui nello stesso riquadro di un numero vengano poste due fiches della medesima dimensione.
In questo caso devi poter spostare la fiche che sta sopra per vedere quella sottostante; e così può risultare utile il mio precedente suggerimento.
......oppure potresti, più semplicemente, spostarle trascinandole con il mouse nuovamente con un Drag&Drop.
Entrambi i miei precedenti suggerimenti prevedono un intervento manuale con il mouse sulle fiches per ottenere il loro spostamento; mentre tu - sembra - preferisci un riordino automatico delle fiches ponendo in fondo quelle più grandi. Si potrebbe in questo caso operare sulla falsariga del banale esempio che segue. Poniamo sul form l'una sull'altra in pila 4 TextLabel aventi diverse dimensioni orizzontali e magari diversi colori:
Public Sub Form_Open()
Dim cl As Control
Dim j As Byte
With FMain
' Verifichiamo la dimensione orizzontale di ciascuna "TextLabel" con le altre:
For Each cl In .Children
For j = 0 To .Children.Count - 1
' Se la dimesione orizzontale della "TextLabel" in questione
' è maggiore dell'altra considerata per la verifica...
If cl.W > .Children[j].W Then
'...viene posta in posizione di livello visivo inferiore:
' ossia nella pila delle 4 "TextLabel" viene posta al di sotto:
cl.Lower
Endif
Next
Next
End With
End
Le TextLabel saranno riordinate in pila sulla base della loro dimensione orizzontale: quelle più grandi in fondo alla pila e quelle più piccole gradatamente in cima.
Nel tuo caso specifico, però, bisognerà comunque prevedere un leggero spostamento delle coordinate delle fiches aventi medesime dimensioni, poichè - seppur poste al di sopra di quelle più grandi - si disturberebbero ovviamente fra loro.
Idee per risolvere il problema?
In vero, non so come potresti colorare con le funzioni della Classe Paint escusivamente la parte dell'immagine rappresentante la vernice che esce fuori dal secchio.. :-\
Ad ogni modo io proporrei la ricostruzione di quella vernice attraverso la funzione Paint.Polygon()... 'na faticaccia m'hai fatto fare ! :violent:
Aggiungerei che potresti sintetizzare un po' il codice eliminando anche la PictureBox chiamata Iconasecchio.
Ecco, come io riscriverei la funzione Colori_MouseDrag() del tuo progetto:
Public Sub Colori_MouseDrag() 'draghiamo un colore
tmp = Image.Load("Secchiello.png")
With Last ' il riquadro da dove parte il drag
coloredrag = .Background 'il colore da usare
With Paint
.Begin(tmp)
.Brush = Paint.Color(coloredrag)
.Polygon([8, 6, 13, 11, 14, 10, 38, 18, 17]) '...il poligono può essere migliorato :-)
.Fill ' colora la "vernice che esce", ossia il poligono prima definito
.End
End With
If Mouse.Left Then ' il secchiello è l'icona del drag&drop
Drag.Icon = tmp.Picture
.Drag(tmp.Picture.Image)
Endif
End With
End
:-X