# data[].attributes.attachment_link.readable_text
from tkinter import *

from math import cos, sin, pi


class OscilloGraphe(Canvas):

    "Canevas spécialisé, pour dessiner des courbes élongation/temps"

    def __init__(self, boss =None, larg=200, haut=150):

        "Constructeur du graphique : axes et échelle horiz."

        # construction du widget parent :

        Canvas.__init__(self)                           # appel au constructeur 

        self.configure(width=larg, height=haut)         # de la classe parente 

        self.larg, self.haut = larg, haut                        # mémorisation

        # tracé des axes de référence :

        self.create_line(10, haut/2, larg, haut/2, arrow=LAST)   # axe X

        self.create_line(10, haut-5, 10, 5, arrow=LAST)          # axe Y

        # tracé d'une échelle avec 8 graduations :

        pas = (larg-25)/8.          # intervalles de l'échelle horizontale

        for t in range(1, 9):

            stx = 10 + t*pas        # +10 pour partir de l'origine

            self.create_line(stx, haut/2-4, stx, haut/2+4)

        

    def traceCourbe(self, freq=1, phase=0, ampl=10, coul='red'):

        "tracé d'un graphique élongation/temps sur 1 seconde"

        curve =[]                       # liste des coordonnées

        pas = (self.larg-25)/1000.      # l'échelle X correspond à 1 seconde

        for t in range(0,1001,5):       # que l'on divise en 1000 ms.

            e = ampl*cos(2*pi*freq*t/1000 + phase)

            x = 10 + t*pas

            y = self.haut/2 - e*self.haut/25

            curve.append((x,y))

        n = self.create_line(curve, fill=coul, smooth=1)

        return n                        # n = numéro d'ordre du tracé


#### Code pour tester la classe : ####


if __name__ == '__main__':

    root = Tk()

    gra = OscilloGraphe(root, 250, 180)

    gra.pack()

    gra.configure(bg ='ivory', bd =2, relief=SUNKEN)

    gra.traceCourbe(2, 1.2, 10, 'purple')

    root.mainloop()

# data[].attributes.attachment_link.readable_text
from tkinter import *

from math import pi


class ChoixVibra(Frame):

    """Curseurs pour choisir fréquence, phase & amplitude d'une vibration"""

    def __init__(self, boss =None, coul ='red'):

        Frame.__init__(self)        # constructeur de la classe parente

        # Initialisation de quelques attributs d'instance :

        self.freq, self.phase, self.ampl, self.coul = 0, 0, 0, coul

        # Variable d'état de la case à cocher :

        self.chk = IntVar()                 # 'objet-variable' Tkinter        

        Checkbutton(self, text='Afficher', variable=self.chk,

                    fg = self.coul, command = self.setCurve).pack(side=LEFT)

        # Définition des 3 widgets curseurs :

        Scale(self, length=150, orient=HORIZONTAL, sliderlength =25,

              label ='Fréquence (Hz) :', from_=1., to=9., tickinterval =2,

              resolution =0.25,

              showvalue =0, command = self.setFrequency).pack(side=LEFT)

        Scale(self, length=150, orient=HORIZONTAL, sliderlength =25,

              label ='Phase (radian) :', from_=-3.1416, to=3.1416, tickinterval =3.1416/2,

              showvalue =0, command = self.setPhase).pack(side=LEFT)

        Scale(self, length=150, orient=HORIZONTAL, sliderlength =25,

              label ='Amplitude :', from_=1, to=9, tickinterval =2,

              showvalue =0, command = self.setAmplitude).pack(side=LEFT)

        

    def setCurve(self):

        self.event_generate('<Control-Z>')


    def setFrequency(self, f):

        self.freq = float(f)

        self.event_generate('<Control-Z>')

                              

    def setPhase(self, p):

        pp =float(p)

        self.phase = pp        # conversion degrés -> radians

        self.event_generate('<Control-Z>')


    def setAmplitude(self, a):

        self.ampl = float(a)

        self.event_generate('<Control-Z>')


#### Code pour tester la classe : ###

        

if __name__ == '__main__':

    def afficherTout(event=None):

        lab.configure(text = '%s - %s - %s - %s' %

                         (fra.chk.get(), fra.freq, fra.phase, fra.ampl))                

    root = Tk()

    fra = ChoixVibra(root,'navy')

    fra.pack(side =TOP)

    lab = Label(root, text ='test')

    lab.pack()

    root.bind('<Control-Z>', afficherTout)

    root.mainloop()

# data[].attributes.attachment_link.readable_text
from oscillo import *

from curseurs import *


class ShowVibra(Frame):

    """Démonstration de mouvements vibratoires harmoniques"""

    def __init__(self, boss =None):

        Frame.__init__(self)        # constructeur de la classe parente

        self.couleur = ['dark green', 'red', 'purple']

        self.trace = [0]*3          # liste des tracés (courbes à dessiner)

        self.controle = [0]*3       # liste des panneaux de contrôle


        # Instanciation du canevas avec axes X et Y : 

        self.gra = OscilloGraphe(self, larg =400, haut=200)

        self.gra.configure(bg ='white', bd=2, relief=SOLID)

        self.gra.pack(side =TOP, pady=5)


        # Instanciation de 3 panneaux de contrôle (curseurs) : 

        for i in range(3):

            self.controle[i] = ChoixVibra(self, self.couleur[i])

            self.controle[i].pack()


        # Désignation de l'événement qui déclenche l'affichage des tracés :    

        self.master.bind('<Control-Z>', self.montreCourbes)

        self.master.title('Mouvements vibratoires harmoniques')

        self.pack()

        

    def montreCourbes(self, event):

        """(Ré)Affichage des trois graphiques élongation/temps"""   

        for i in range(3):


            # D'abord, effacer le tracé précédent (éventuel) :

            self.gra.delete(self.trace[i])


            # Ensuite, dessiner le nouveau tracé :  

            if self.controle[i].chk.get():

                self.trace[i] = self.gra.traceCourbe(

                                    coul = self.couleur[i],

                                    freq = self.controle[i].freq,

                                    phase = self.controle[i].phase,

                                    ampl = self.controle[i].ampl)                    

            

#### Code pour tester la classe : ###

        

if __name__ == '__main__':    

    ShowVibra().mainloop()