Ein kleiner Aktionsrahmen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Ein kleiner Aktionsrahmen

Beitrag von Nino »

BSP hat geschrieben:Hallo Nino.
Ja; Deine Version ist vieleicht etwas einfacher: Aber:
Wenn Du in meiner Version mal die Delay vergrösserst
Delay(50) oder so, dann kannst Du sehen,
das mein Rahmen vom grossen auf das kleine Gadget läuft.
Nicht nur auf den Mauspunkt.
Der Button wird quasi "eingerahmt.
Dadurch ergeben sich ausbaufähige Möglichkeiten.
Hallo BSP,

da hast Du natürlich recht. Ich habe meinen Code jezt entsprechend geändert. Man kann jetzt ein "Startrechteck" und ein "Zielrechteck" übergeben, wobei sich der Mauszeiger als Rechteck mit der Ausdehnung Null interpretieren lässt. Auch das While WindowEvent(): Wend habe ich übernommen.

Trotzdem ist Dein Code unnötig kompliziert.
Statt der Structure "Rahmen" benötigt man nur die 4 Grenzen links, oben, rechts, unten (bzw. Breite und Höhe). Und es ist auch z.B. nicht erforderlich, in der Procedure "AktionsRahmen" Quadratwurzeln zu berechnen.
rolaf hat geschrieben:Nino, wenn man die Fenstergröße ändert wird dies beim Aktionsrahmen nicht berücksichtigt.
Das ist jetzt berücksichtigt. Ich sehe allerdings, dass Du inzwischen auch tätig warst. :)
rolaf hat geschrieben:Edit: Parameter "*start.Rect" oben entfernt.
Dadurch wird die Prozedur unflexibler, während meine folgende neue Version flexibler als die vorige ist.

Code: Alles auswählen

EnableExplicit

; ===== Ins Programm einbauen
CompilerIf Defined(Rect, #PB_Structure) = #False
   Structure Rect
      left.l
      top.l
      right.l
      bottom.l
   EndStructure
CompilerEndIf


Procedure AktionsRahmen (idWin.i, *start.Rect, *target.Rect, numSteps.i=100)
   Protected.i i
   Protected.f x, y, w, h
   Protected.f stepLeft, stepAbove, stepWidth, stepHeight
   
   x = *start\left
   y = *start\top
   w = *start\right  - *start\left
   h = *start\bottom - *start\top
   
   stepLeft   = (*target\left - *start\left) / numSteps
   stepAbove  = (*target\top  - *start\top)  / numSteps
   stepWidth  = (w - *target\right  + *target\left) / numSteps
   stepHeight = (h - *target\bottom + *target\top)  / numSteps
   
   StartDrawing(WindowOutput(idWin))
   DrawingMode(#PB_2DDrawing_XOr|#PB_2DDrawing_Outlined)
   For i = 1 To numSteps
      x + stepLeft
      y + stepAbove
      w - stepWidth
      h - stepHeight
      Box(x, y, w, h)
      Delay(4)
      ; Delay(50)      ; Test
      Box(x, y, w, h)
      While WindowEvent(): Wend
   Next
   StopDrawing()
EndProcedure


; ===== Hier beginnt das Demoprogramm
Procedure GetGadgetFrame (gadget.i, *frame.Rect)
   *frame\left   = GadgetX(gadget)
   *frame\top    = GadgetY(gadget)
   *frame\right  = GadgetX(gadget) + GadgetWidth(gadget)
   *frame\bottom = GadgetY(gadget) + GadgetHeight(gadget)
EndProcedure

Enumeration
   #Window
EndEnumeration

Enumeration
   #List
   #Button
EndEnumeration


Define.Rect rList, rButton, rMouse
Define.i flags, x, y, w, h, ende=0

flags = #PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget
OpenWindow(#Window, 0, 0, 800, 400, "Fenster", flags)

x = 4
y = 4
w = WindowWidth(#Window) - 8
h = WindowHeight(#Window) - 50
ListIconGadget(#List, x, y, w, h, "Test", w, #PB_ListIcon_GridLines|#PB_ListIcon_AlwaysShowSelection)
AddGadgetItem(#List, -1, "Eine Zeile")

x = WindowWidth(#Window)/4 - 25
y = WindowHeight(#Window) - 40
w = 100
h = 30
ButtonGadget(#Button, x, y, w, h, "ClipBoard")

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         ende = 1
         
      Case #PB_Event_Gadget
         Select EventGadget()
            Case #Button
               GetGadgetFrame(#List, @rList)
               GetGadgetFrame(#Button, @rButton)
               AktionsRahmen(#Window, @rList, @rButton)
               
            Case #List
               If EventType() = #PB_EventType_LeftClick
                  GetGadgetFrame(#List, @rList)
                  rMouse\left   = WindowMouseX(#Window)
                  rMouse\top    = WindowMouseY(#Window)
                  rMouse\right  = rMouse\left
                  rMouse\bottom = rMouse\top
                  AktionsRahmen(#Window, @rList, @rMouse)
               EndIf
         EndSelect
   EndSelect
Until ende
Grüße, Nino
Zuletzt geändert von Nino am 09.02.2012 21:13, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Ein kleiner Aktionsrahmen

Beitrag von NicTheQuick »

Mal 'ne blöde Frage: Wieso nutzt ihr hier durchgehend '#WM_CLOSE' anstatt der von PB bereit gestellten Konstanten '#PB_Event_CloseWindow'?

Ich sehe mal davon ab, dass unter Linux und Mac auch die Struktur 'Rect' nicht bekannt ist. Aber das mit der Konstanten ist echt unnötig.

Meine nächste Frage nach Implementierung von 'Rect' ist aber jetzt: Was soll bei dem Code passieren? Wenn ich auf den Button oder auf das ListIconGadget klicke, passiert gar nichts. Es dauert nur ca. eine Sekunde bis der Button von seinem gedrückten Status wieder in den nicht-gedrückten Status übergeht, nachdem ich drauf geklickt hatte. Aber ich sehe nirgendwo einen Rahmen. Ist das vielleicht wieder ein Fehler in der Linux-Version?
Benutzeravatar
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Re: Ein kleiner Aktionsrahmen

Beitrag von rolaf »

Nino, warum *start.Rect und *target.Rect? Übergib doch einfach die Gadget-Nummern und die weiteren Sachen folgen dann in der Prozedur. Das entmüllt die Ereignisschleife ernorm und sorgt für Übersichtlichkeit.

Edit: Und wenn man als Start-Gadget -1 übergibt wird statt der Start-Gadget-Position die Maus-Position in der Prozedur ermittelt. Dann haste den ganzen "Klump" aus der Ereignisschleife weg.
:::: WIN 10 :: PB 5.73 :: (x64) ::::
Benutzeravatar
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Re: Ein kleiner Aktionsrahmen

Beitrag von rolaf »

Hier mein Beispiel:

Code: Alles auswählen

EnableExplicit

Enumeration
  #Window
EndEnumeration

Enumeration
  #List
  #Button
EndEnumeration

Procedure AktionsRahmen(Window.i, StartGadget.i, ZielGadget.i)
  
  Protected.f x, y, w, h
  Protected.i x2, y2, w2, h2, A
  
  Protected.i x1 = GadgetX(StartGadget)
  Protected.i y1 = GadgetY(StartGadget)
  Protected.i w1 = GadgetWidth(StartGadget)
  Protected.i h1 = GadgetHeight(StartGadget)  
  
  If ZielGadget = -1
    x2 = WindowMouseX(Window) - 5
    y2 = WindowMouseY(Window) - 5
    w2 = 10
    h2 = 10
  Else  
    x2 = GadgetX(ZielGadget)
    y2 = GadgetY(ZielGadget)
    w2 = GadgetWidth(ZielGadget)
    h2 = GadgetHeight(ZielGadget)
  EndIf
  
  Protected.f Sx = (x2 - x1) / 100
  Protected.f Sy = (y2 - y1) / 100
  Protected.f Sw = (w2 - w1) / 100
  Protected.f Sh = (h2 - h1) / 100

  StartDrawing(WindowOutput(Window))
    DrawingMode(#PB_2DDrawing_XOr | #PB_2DDrawing_Outlined)
    For A = 0 To 99
      x = x1 + A * Sx
      y = y1 + A * Sy
      w = w1 + A * Sw
      h = h1 + A * Sh
      Box(x, y, w, h)
      Delay(4)
      Box(x, y, w, h)
      WindowEvent()
    Next
  StopDrawing()

EndProcedure

OpenWindow(#Window, 20, 20, 800, 400, "Fenster", #PB_Window_ScreenCentered | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
ListIconGadget(#List, 4, 4, 792, 350, "Test", 300, #PB_ListIcon_GridLines | #PB_ListIcon_AlwaysShowSelection)
AddGadgetItem(#List, -1, "Eine Zeile")
ButtonGadget(#Button, 400, 360, 100, 30, "ClipBoard")

Repeat
  Select WaitWindowEvent()

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button: AktionsRahmen(#Window, #List, #Button)
        Case #List
          If EventType() = #PB_EventType_LeftClick
            AktionsRahmen(#Window, #List, -1)
          EndIf
      EndSelect

    Case #PB_Event_CloseWindow: End
      
  EndSelect
ForEver
:::: WIN 10 :: PB 5.73 :: (x64) ::::
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Ein kleiner Aktionsrahmen

Beitrag von BSP »

@Nino.
Ja, sieht wirklich einfacher aus. Ich werd's heute abend noch genauer "erforschen".
Ich bin kein Profi und hatte zuletzt selber schon nen Knoten im Kopf. Grins.

Aber schon mal danke für die Hilfe.

@Nick
Ich gebs zu.
Das ich #WM_CLOSE benutze ist faulheit und unbedacht.
#WM_CLOSE ist kürzer und daher schneller getippt,
und das dass auf anderen Systemen nicht läuft, hatte ich nicht bedacht.
Obwohl ich bei meinen Progrämmchen schon auch an andere Systeme gedacht hatte.
Ich werde mich bessern. Smile.

@Rolaf.
Ich weiss nicht, wie Nino das sieht.
Bei meiner nicht veröffentlichen Version hatte ich anfangs auch die Gadgetnummern übergeben.
Aber dann fand ich, das sollte auch unabhängig von den Gadgets laufen,
damit man das auch für andere Ideen benutzen kann.
Ich habe zwar noch nichts ausprobiert, wollte die Möglichkeit aber offen halten.

Danke an Alle.
BSP
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Re: Ein kleiner Aktionsrahmen

Beitrag von rolaf »

BSP hat geschrieben:@Rolaf.
Ich weiss nicht, wie Nino das sieht.
Bei meiner nicht veröffentlichen Version hatte ich anfangs auch die Gadgetnummern übergeben.
Aber dann fand ich, das sollte auch unabhängig von den Gadgets laufen,
damit man das auch für andere Ideen benutzen kann.

Ich habe zwar noch nichts ausprobiert, wollte die Möglichkeit aber offen halten.
Das ist doch nun gar kein Problem mehr, ich hab das so weit vereinfacht und übersichtlich gemacht, das du mit kleinen Änderungen am Code das auch Pixelgenau nutzen kann. Vorher war ja Wüste, da wurde mir auch wuschig im Kopf... :lol:
:::: WIN 10 :: PB 5.73 :: (x64) ::::
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Ein kleiner Aktionsrahmen

Beitrag von BSP »

@Rolaf
Das ist doch nun gar kein Problem mehr, ich hab das so weit vereinfacht und übersichtlich gemacht, das du mit kleinen Änderungen am Code das auch Pixelgenau nutzen kann. Vorher war ja Wüste, da wurde mir auch wuschig im Kopf...
Stimmt.
Ich hatte Deine Version zu spät bemerkt. :)

Danke. BSP
PB 5.31 (x86) & (x64) Win10
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Ein kleiner Aktionsrahmen

Beitrag von Nino »

NicTheQuick hat geschrieben:Mal 'ne blöde Frage: Wieso nutzt ihr hier durchgehend '#WM_CLOSE' anstatt der von PB bereit gestellten Konstanten '#PB_Event_CloseWindow'?

Ich sehe mal davon ab, dass unter Linux und Mac auch die Struktur 'Rect' nicht bekannt ist. Aber das mit der Konstanten ist echt unnötig.
Ist in meinem letzten Code jetzt korrigiert.
NicTheQuick hat geschrieben:Meine nächste Frage nach Implementierung von 'Rect' ist aber jetzt: Was soll bei dem Code passieren? Wenn ich auf den Button oder auf das ListIconGadget klicke, passiert gar nichts. Es dauert nur ca. eine Sekunde bis der Button von seinem gedrückten Status wieder in den nicht-gedrückten Status übergeht, nachdem ich drauf geklickt hatte. Aber ich sehe nirgendwo einen Rahmen. Ist das vielleicht wieder ein Fehler in der Linux-Version?
Es soll ein animierter Rahmen dargestellt werden. Der Rahmen hat in meinem Beispiel zuerst die Größe des Listicongadgets, er läuft auf den Button oder den Mauszeiger zu und wird dabei immer kleiner.
rolaf hat geschrieben:Nino, warum *start.Rect und *target.Rect?
Weil die Prozedur dann allgemeiner, sprich vielseitiger verwendbar ist, wie ich schon geschrieben hatte.
rolaf hat geschrieben:Übergib doch einfach die Gadget-Nummern und die weiteren Sachen folgen dann in der Prozedur. Das entmüllt die Ereignisschleife ernorm und sorgt für Übersichtlichkeit.
In Deinem letzten Beispiel sehe ich v.a. einen Haufen möglicherweise überhaupt nicht benötigten "Müll", wie du es wohl nennen würdest, innerhalb der Prozedur ... :mrgreen:
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Ein kleiner Aktionsrahmen

Beitrag von BSP »

Hallo.
So, ich habe Eure Beispiele nun "gemixt".
Ich finde es schöner, die Positionen direkt an die Procedure zu übergeben.
Dadurch bleibt wenigstens mein Grundgedanke der Vielseitigkeit erhalten. Smile
Als Beispiele habe ich noch einen Rechtsklick im ListIcon
und das Resizen mit eingebaut.

Die Structure habe ich noch extra angelegt,
damit das auch bei Nick läuft. Smile.

Gruß: BSP

Code: Alles auswählen

EnableExplicit

Enumeration
  #Window
EndEnumeration

Enumeration
  #List
  #Button
EndEnumeration

Structure rahmen
  x.i
  y.i
  w.i
  h.i
EndStructure

Procedure AktionsRahmen(Window.i, *Start.rahmen, *Ziel.rahmen)
  
  Protected.f x, y, w, h
  Protected.i A, schritte= 100

  Protected.f Sx = (*ziel\x - *start\x) / schritte
  Protected.f Sy = (*ziel\y - *start\y) / schritte
  Protected.f Sw = (*ziel\w - *start\w) / schritte
  Protected.f Sh = (*ziel\h - *start\h) / schritte

  StartDrawing(WindowOutput(Window))
    DrawingMode(#PB_2DDrawing_XOr | #PB_2DDrawing_Outlined)
    For A = 0 To schritte-1
      x = *start\x + A * Sx
      y = *start\y + A * Sy
      w = *start\w + A * Sw
      h = *start\h + A * Sh
      Box(x, y, w, h)
      Delay(4)
      Box(x, y, w, h)
      While WindowEvent() : Wend
    Next
  StopDrawing()

EndProcedure

Procedure Get_RahmenGadget(*pos.rahmen,idgadg)
  *pos\x = GadgetX(idgadg)
  *pos\y = GadgetY(idgadg)
  *pos\w = GadgetWidth(idgadg)
  *pos\h = GadgetHeight(idgadg)
EndProcedure

Procedure Get_RahmenMaus(*pos.rahmen,idwin)
  *pos\x = WindowMouseX(idwin) - 1
  *pos\y = WindowMouseY(idwin) - 1
  *pos\w = 2
  *pos\h = 2
EndProcedure

Procedure Get_RahmenMitte(*pos.rahmen)
   *pos\x = *pos\w / 2
   *pos\y = *pos\h / 2
   *pos\w = 0
   *pos\h = 0
EndProcedure

Procedure SizeWindow(window)
  ResizeGadget(#List, 4, 4, WindowWidth(window) -8, WindowHeight(window) -GadgetHeight(#Button) *2 -4)
  ResizeGadget(#Button, WindowWidth(window) /2 - GadgetWidth(#Button) /2, WindowHeight(window) - GadgetHeight(#Button)-4,#PB_Ignore,#PB_Ignore)
EndProcedure

Define start.rahmen
Define ziel.rahmen
Define.i Winw, winw_alt

OpenWindow(#Window, 20, 20, 800, 400, "Fenster", #PB_Window_ScreenCentered | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
ListIconGadget(#List, 4, 4, 792, 350, "Test", 300, #PB_ListIcon_GridLines | #PB_ListIcon_AlwaysShowSelection)
AddGadgetItem(#List, -1, "Eine Zeile")
ButtonGadget(#Button, 400, 360, 100, 30, "ClipBoard")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_SizeWindow
      SizeWindow(#Window)
      winw = WindowWidth(#Window)
      If winw_alt<winw
        ziel\x = 0
        ziel\y = 0
        ziel\w = WindowWidth(#Window)-8
        ziel\h = WindowHeight(#Window)-8
        start = ziel
        Get_RahmenMitte(@start)
        AktionsRahmen(#Window, @start , @ziel)
      ElseIf winw_alt>winw
        start\x = 0
        start\y = 0
        start\w = WindowWidth(#Window)-8
        start\h = WindowHeight(#Window)-8
        ziel = start
        Get_RahmenMitte(@ziel)     
        AktionsRahmen(#Window, @start , @ziel)
      EndIf
      winw_alt = winw
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button
          Get_RahmenGadget(@start, #List)
          Get_RahmenGadget(@ziel, #Button)
          AktionsRahmen(#Window, @start , @ziel)
        
        Case #List
          Select EventType()
            Case #PB_EventType_LeftClick
              Get_RahmenGadget(@start, #List)
              Get_RahmenMaus(@ziel, #Window)
              AktionsRahmen(#Window, @start , @ziel)
          
            Case #PB_EventType_RightClick
              Get_RahmenGadget(@start, #List)
              Get_RahmenGadget(@ziel, #List)
              ;Get_RahmenGadget(@ziel, #Button)
              Get_RahmenMitte(@ziel)
              AktionsRahmen(#Window, @start , @ziel)
          
          EndSelect
      EndSelect

    Case #PB_Event_CloseWindow: End
      
  EndSelect
ForEver

PS. Habe den Teil im
Case #PB_Event_SizeWindow
noch gekürzt.
Hätte ich auch gleich dran denken müssen.
Habe ich aber nicht, weil Zeitdruck und daher unkonzentriert.
Und in der Procedure AktionsRahmen
das "While WindowEvent() : Wend" wieder eingesetzt.
Zuletzt geändert von BSP am 10.02.2012 20:25, insgesamt 1-mal geändert.
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Re: Ein kleiner Aktionsrahmen

Beitrag von rolaf »

Wir reden hier von der schönsten Nebensache der Welt, nämlich nix anderes als eine grafischen Aufhübschung eines Prozesses der ansonsten unsichtbar erfolgt. Die echte Funktionalität folgt also noch und eure Ereignisschleifen sind schon für diese Spielerei vollgeknallt. Mit Grausen stell ich mir vor wie die Schleife nach Einbau der kompletten Funktionalität aussieht, wenn schon für Spielereien solch ein Aufwand in der Schleife erfolgt. :freak:

Aber jeder soll ja nach seiner Facon selig werden. :allright: In diesem Sinne Peace. :)
:::: WIN 10 :: PB 5.73 :: (x64) ::::
Antworten