IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Boutons qui ne marchent qu'en debug (maintenant aide création mini gui SDL2) [SDL 2.0]


Sujet :

SDL

  1. #21
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    un exemple pour les callback par pointeurs de fonctions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    bool resume(int x, int y)  {
        cout << "resume" << endl;
        return true;
    }
    bool abort(int x, int y) {
        cout << "abort" << endl;
        return true;
    }
     
    typedef bool (*clickable_t)(int, int);
     
    int main() {
        std::vector<clickable_t>> clickables;
        clickables.push_back(resume);
        clickables.push_back(abort);
     
        for (std::vector<clickable_t>>::const_iterator it = clickables.begin();  it != clickables.end(); ++it) {
            (*it)(1, 4);
        }
        return 0;
    }
    edit: j'avais oublié une paire de parenthèse dans le typedef, merci Medinoc de l'avoir vu
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  2. #22
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    @skeud, en fait, moi je veux bien une piste de code, si tu en as à portée de main.

    Ça fait une bonne douzaine de fois que j'aide des gens sur ce genre de problème, et j'aimerai bien voir un code bien fait.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #23
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    mais dans Qt par exemple y'a pas de widget manager si ?
    (quand je dis thread je veut pas parler de la gestion de plusieurs coeurs du processeur mais de plusieurs processus je pense que vous aviez compris mais bon je suis pas sur de m'exprimer correctement donc je le dit au cas ou)
    pour le pointeur de fonction il faut qu'il puisse gérer n'importe quel type d'argument (int, double, char, button*...)

  4. #24
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    La solution la pire serait le void*, la bonne, c'est de faire correspondre à chaque situation une (liste de) callback adaptée, qui ont chacun des arguments bien choisi.
    Cela signifie par exemple des clic_cb, keyboard_cb, schtroumf_cb etc, chacun avec son type bien déterminé.

    Quand on arrive à ce genre de problème de "entasser des trucs différents", je recommande le retour au papier.
    écrire une liste de fonctionnalité, et en déduire les éléments de code à assembler.

    un bouton "resume" = une classe de bouton (dans ui: et une classe de clickable (dans event:, le bouton resume recevent un clic_clickable.

    à mon sens, il peut y avoir EventManager qui détecte le clic (via SDL_pollevent), ui::button qui dit s'il l'accepte (accepts_clic(x, y)) et event::clickable qui est une interface définissant operator()(int x, int y)

    à toi de voir si veux mélanger gestion du clic et de l'affichage (uniquement bouton, et vecteur de bouton) ou non (map<bouton, clickable*>)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #25
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    donc je suis obligé de passer par un widgetManager ?
    et pourquoi le void* est la pire solution ?

  6. #26
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    void* est une manière de violer le typage.


    Rappelle toi qu'on code est meilleur quand chaque classe et fonction ne fait qu'une seule chose, mais le fait bien.
    D'où ma séparation ui::button et event::clickable
    Certes un bouton est clickable (ui::button peut contenir un event::clickable), mais ce n'est pas à la classe d'objets button de définir ce que fais chaque bouton.

    Dans cet esprit, donc, une fonction fait une transformation. Si elle en fais plusieurs, que celles-ci soient des sous-fonctions.
    Et de même une classe gère une fonctionnalité: affichage, réactivité, capsule (RAII autour d'une ressource), donnée, respect de règles de jeu, etc

    Un widget manager, ou EventManager (dans ce que j'ai proposé) est une classe qui a la responsabilité de la propagation des événements
    Il n'est pas forcément apparent, il peut être caché dans une bibliothèque. C'est le cas de EDT (event dispatch thread) de swing en Java, je crois que c'est la même chose en Qt (que je ne connais pas assez)

    Grâce à lui, le widget n'a pas besoin de savoir comment chercher l’événement. Il ne définira que sa manière de réagir.
    Et toujours grâce à lui, main n'a pas à gérer la manière de transmettre les événements.

    Nous pouvons t'aider mieux, mais il faudrait que tu nous donnes une maquette de ton code, ou au minimum une description précise de ce que tu veux faire (j'ai bien dit faire, pas coder)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #27
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    je veut (grace a la sdl) faire un système de bouton spécialisés pour les jeux qui interagissent quand on passe la souris dessus et quand on clique (comme les boutons normaux) et les relier a une fonction (n'importe laquelle d'où le void*), qu'ils aient une texture, une couleur spécifique quand on met la souris dessus, une autre quand on clique, puis peut-être plus tard qu'ils puissent jouer des sons et rajouter des infobulles.
    et aussi qu'il y ait juste a construire un bouton avec certains paramettres pour qu'il soit fonctionnel

  8. #28
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Bon beh petite piste de code développé à la main dans le message, je suis au boulot, j'ai pas mes codes sous la main .
    En aucun cas je garanti le fonctionnement tel quel, c'est une idée d'implémentation, surement des ajustements seront à faire.

    Tout d'abord notre gestionnaire d'application:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    #include "Widget.hpp"
     
    class App
    {
      public:
        App(int winx, int winy, std::string name);
        ~App();
        bool Init(); // Fonction qui va initialiser notre application
        void Run(); // Fonction qui va lancer l'application
        void AddWidget(Widget* widget);
        void RemoveWidget(Widget* widget);
        void Close(); // Arrete l'application
      private:
        int _winx;
        int _winy;
        std::string _name;
        std::list<Widget*> _Widgets; // Liste des widget de notre application
        bool _running;
        SDL_Surface _screen; // Ecran où l'on affiche les widget (utile pour le double buffering, que je n'implémente pas ici, il y a des tuto pour ça)
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include "App.hpp"
     
    App::App(int winx, int winy, std::string name):
    _winy(winy),
    _winx(winx),
    _name(name),
    _running(false)
    {
    }
     
    App::~App()
    {
    }
     
    bool App::Init()
    {
        //initialisation de la SDL, la flemme de tout mettre
    }
     
    void App::AddWidget(Widget* widget)
    {
       _Widgets.push_back(widget);
    }
     
    void App::RemoveWidget(Widget* widget)
    {
      _Widgets.remove(widget);
    }
     
    void App::Run()
    {
      SDL_Event event;
      _running = true;
      while (running)
      {
        SDL_PollEvent(&event);
        // Mettre ici la gestion des evenement principaux (alt+F4, esc .....)
        std::list<Widget*>::Iterator it = _Widgets.begin();
        bool continue = true;
        // On parcour la liste des widget pour leur signaler l'evenement
        while (it != _Widgets.end() && continue)
        {
            // Si la widget intercepte l'event, on arrete de boucler
            if ((*it)->AcceptEvent(&event))
              continue = false;
            it++;
        }
        it = _Widgets.begin();
        // On parcour la liste des widget pour qu'elles s'affichent
        while (it != _Widgets.end())
        {
           (*it)->Draw(_Screen);
           it++;
        }
      }
    }
    Notre classe widget:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Widget
    {
      public:
        Widget(int x, int y, int width, int height);
        virtual ~Widget();
        virtual void Draw(SDL_Surface* painter) = 0; // L'argument est la SDL_Surface sur laquelle on va dessiner.
        virtual bool AcceptEvent(SDL_Event* event) = 0; // Return true si notre widget capte l'event sinon false
      protected:
        int _X;
        int _Y;
        int _width;
        int _height;
    }
    Notre classe button:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Class Button : public Widget
    {
      public:
        Button(int x, int y, int width, int height, SDL_Surface *clicked, SDL_Surface *notClicked, ButtonGestion gestion);
        virtual ~Button();
        virtual void Draw(SDL_Surface* painter); // on laisse en virtual si on doit faire une classe fille (un bouton on/off par exemple)
        virtual bool AcceptEvent(SDL_Event* event);
      private:
        SDL_Surface* _imgClicked;
        SDL_Surface* _imgNotClicked;
        bool _clicked;
        ButtonGestion *_gestion;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include "Button.hpp"
     
    Button::Button(int x, int y, int width, int height, SDL_Surface *clicked, SDL_Surface *notClicked):
    Widget(x, y, width, height),
    _imgClicked(clicked),
    _imgNotClicked(notClicked),
    _clicked(false),
    _gestion(gestion)
    {
    }
     
    Button::~Button()
    {
    }
     
    void Button::Draw(SDL_Surface* painter)
    {
       // A vous de dessiner votre bouton dans cette fonction :)
      // Utilisez la variable _clicked pour savoir si le bouton est enfoncé ou non
    }
     
    bool Button::AcceptEvent(SDL_Event* event)
    {
      if( event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) 
      {
        SDL_Rect inter(_x, _y, _x+_width, _y+_height);
        if (inter.contains(event.button.x, event.button.y))
        {
            if (_clicked == false && event.type == SDL_MOUSEBUTTONDOWN)
              _clicked = true;
            else if (_clicked && event.type == SDL_MOUSEBUTTONUP)
            {
               _clicked = false;
               _gestion->buttonClicked();
            }
            return (true);
        }
      }
      return (false);
    }
    notre gestionnaire de bouton:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class ButtonGestion
    {
      public:
        ButtonGestion();
        virtual ~ButtonGestion();
        buttonClicked(); // Cette callback sera appelé lorsque le bouton qui possède cet objet sera clicker.
    }
    La classe qui effectura les action lorsqu'on appuie sur le bouton config:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class GestionConfig: public ButtonGestion
    {
      public:
        GestionConfig();
        ~GestionConfig();
        buttonClicked(); // Cette callback sera appelé lorsque le bouton config est clicker
    }
    et pour finir le main:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include "App.hpp"
    #include "Button.hpp"
     
    int main(int ac, char** av)
    {
      App app(800, 600, "test");
      if (app.Init())
      {
         GestionConfig* gestionConfig();
         Button boutonCFG(0, 0, 50, 50, imageClick, imageNotClick, &gestionconfig);
         app.AddWidget(&boutonCFG);
         app.run();
      }
    }
    Voila une base pour un gestionnaire (ultra mega giga simple) ui qui permet de detecter le click sur un bouton et d'appeler une callback d'un manager.
    Ensuite il suffit simplement d'hériter de la classe GestionButton et d'implémenter la fonction buttonClicked pour que n'importe quel classe reçoive la callback d'un bouton, et oui la magie de l'héritage .

    Il y a bien sur d'autre manière de faire, mais celle-ci est la plus simple pour commencer.
    Pour plus d'info tu peux regarder sur internet, il y a des tutos simpa qui décortiquent les fonctionnements de QT par exemple.

    N'hésitez pas à critiquer le code, je sais qu'il n'est pas parfait et que je peux faire mieux, mais ce n'est qu'une approche codé dans cet éditeur de texte :p.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  9. #29
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Donc, ton système doit fournir:
    • plusieurs boutons.
    • chacun ayant la possibilité de faire quelque chose quand la souris entre dedans
    • (bonus chacun ayant la possibilité de faire quelque chose quand la souris en sort
    • chacun ayant la possibilité de faire quelque chose quand on clique dessus


    il faut donc trois méthodes de déclenchement dans la classe bouton.

    Pour ton problème de fonction, tu te complique la tache. Quels arguments peuvent-ils recevoir?
    quelque chose relatif à l'événement déclencheur: l'événement, ou simplement la position souris, par exemple.

    Par exemple les types suivants permettent de déclarer des pointeurs de fonctions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    namespace events {
    typedef void (*mouse_action_cb)(int x, int y);
    typedef void (*mouse_move_cb)(int x, int y, int dx, int dy);
    }
    Du coup, il suffit de stocker proprement ces pointeurs, et c'est fini.

    Voici un exemple avec un bouton théoriquement fonctionnel, mais sans affichage ni filtrage des coordonnées.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Button {
    private:
    	mouse_action_cb onClick_cb;
    	mouse_move_cb onMouseOver_cb, onMouseOut_cb;
     
    public:
    	Button& onClick(mouse_action_cb cb) {
    		this->onClick_cb = cb;
    		return *this;
    	}
     
    	Button& onMouseOver(mouse_move_cb cb) {
    		this->onMouseOver_cb = cb;
    		return *this;
    	}
     
    	Button& onMouseOut(mouse_move_cb cb) {
    		this->onMouseOut_cb = cb;
    		return *this;
    	}
     
    	void click(int x, int y) const {
    		if (onClick_cb!=std::nullptr) onClick_cb(x,y);
    	}
     
    	void mouseOver(int x, int y, int dx, int dy) const {
    		if (onMouseOver_cb!=std::nullptr) onMouseOver_cb(x,y, dx,dy);
    	}
     
    	void mouseOut(int x, int y, int dx, int dy) const {
    		if (onMouseOut_cb!=std::nullptr) onMouseOut_cb(x,y, dx,dy);
    	}
     
    };
    Ne reste alors qu'a l'utiliser par exemple ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void bingo(int, int) { cout << "bingo" << endl;}
    void bingo(int, int, int, int) { cout << "bye!" << endl;}
     
    int main() {
    	Button b = Button().onClick(bingo).onMouseOut(leave);
     
    	b.click(0,0);
    	b.mouseOver(1,1, 1,1);
    	b.mouseOut(0,0, 1,1);
     
    	return 0;
    }

    edit: c'est marrant de découvrir un nouveau message de skeud à chaque fois que je poste dans ce sujet...
    Dommages qu'ils apparaissent quand j'écris.

    Merci pour ton code, j'en ferai un bon usage
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  10. #30
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    J'ai quelques remarques sur le code de skeud:
    il manque les relations d'héritage (telle que class Button: public Widget)
    il y a des soucis avec la virtualité des destructeurs publics.
    dommage qu'il y ait des new sans delete. (les new sont d'ailleurs inutiles, une simple prise d'adresse suffirait)

    Merci tout de même pour ton code, c'est un super point de départ.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  11. #31
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    merci bien je vais aller voir ce que je peut faire avec vos code et le fonctionnement de Qt

  12. #32
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par leternel Voir le message
    J'ai quelques remarques sur le code de skeud:
    il manque les relations d'héritage (telle que class Button: public Widget)
    il y a des soucis avec la virtualité des destructeurs publics.
    dommage qu'il y ait des new sans delete. (les new sont d'ailleurs inutiles, une simple prise d'adresse suffirait)

    Merci tout de même pour ton code, c'est un super point de départ.
    J'ai modifié ça dans le code que j'ai proposé, il manque plein de chose comme la création des sdl_surface, l'implémentation de certaine fonction ... mais bon j'allais pas tout mettre d'un coup non plus .
    Pour les new inutile, oui c'est vrai mais bon j'ai toujours préféré mettre des new que renvoyer une addresse local, ça évite les soucis de scope etc ....

    Et effectivement, marrant de trouvé un message de l'autre, mais bon vu les messages on dit à peu près la meme chose (c++11 pour toi en différence) ça permet d'avoir deux point de vue différent, c'est plutot une bonne chose .

    Et ptite remarque sur ton code, les setter de callback qui retourne un objet ne sont pas une bonne pratique :p. (Dans cet exemple ça fonctionne, mais en multi-thread, ton objet peut avoir été modifié entre les deux appels, donc pas top.
    La lecture est d'ailleur plus compliqué avec ce système que deux lignes bien distinct .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  13. #33
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    je pense avoir eut une idée pour dissimuler le widget manager grace a une macro mais je voudrais savoir si en faisant #define ptr = fonction(); si j'utilise ptr ça va appeler la fonction à chaque fois ?
    et aussi est-ce qu'il y a un moyen a partir d'un objet d’accéder à ptr a partir d'un pointeur this dans le main ?

    mon idée :
    une macro (par exemple INIT_WIDGET) appelle la fonction de widgetManager createWM() (qui n'a pas besoin d'objet crée pour être appelée) qui va créer un wm en renvoyer un pointeur dessus.
    quand on crée un bouton, on récupère ce pointeur par X moyen, puis le constructeur via le pointeur va appeler la fonction addWidget(widget*) du wm avec en argument un this.
    dans le wm une fonction threadée va parcourir une boucle qui va enregistrer les événements et appeler la fonction check(SDL_Event*) de chaque widget.

    ce qui me semble le plus dur est : "récupérer ce pointeur par X moyen" et je ne suis même pas sur que ce soit possible.

    EDIT : je viens de trouver ça dans le code QAbstractButton de Qt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #ifndef QT_NO_BUTTONGROUP
        QButtonGroup *group() const;
    #endif
    peut-on utiliser les macro comme des sortes de variable globale pour tout le programme (ou via un autre moyen) si oui même plus besoin de macro dans le main ni de fonction createWM() on peut faire un truc comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifndef WM
        windowManager *wm();
        #define WM mw
    #endif
    EDIT 2 : en y repensant les macro ne sont que des préprocesseurs donc j'ai marqué n'importe quoi mais y a-t-il un moyen d'avoir des variable utilisables dans tout le programme ? (sans devoir les passer par des fonctions)

  14. #34
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Ce que tu veux faire s'appelle un singleton, voici un code d'exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class WindowManager
    {
      public:
        static WindowManager getInstance();
        ~WindowManager();
      private:
        WindowManager();
        static WindowManager* _INSTANCE;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include "WindowManager.hpp"
     
    WindowManager* WindowManager::_INSTANCE = NULL;
     
    WindowManager::WindowManager()
    {
    }
     
    WindowManager::~WindowManager()
    {
    }
     
    WindowManager* WindowManager::getInstance()
    {
      if (_INSTANCE == NULL)
        _INSTANCE = new WindowManager();
      return (_INSTANCE);
    }
    et depuis le constructeur du bouton:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Button::Button(...)
    {
      WindowManager* wm = WindowManager::getInstance();
      wm->addWidget(this);
    }
    C'est ce que tu veux faire?
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  15. #35
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    sa en a l'air je veut juste pas qu'il soit nécéssaire de créer un wm dans le main (enfin la ou on créer les boutons)
    EDIT : (encore) oui c'est bien ça mais il faudrais que si le bouton n'arrive pas a créer le wm il rejoigne celui déjà existant (si il le fait déjà c'est parfait mais alors comment tu fait pour qu'un objet puisse accéder a une variable crée par un autre objet ?)

  16. #36
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Le bouton n'aura pas besoin de créer le WM, avec cette technique, il ne peut exister qu'un seul WM dans tout ton code, l'unicité se faisant grace à la fonction getInstance (si une instance est déjà existante, on en créer pas une autre).

    Pas besoin de créer l'objet WM pour accédé à la fonction getInstance car elle est déclaré static .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  17. #37
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    le premier bouton qu'on crée va créer un WM et les autres juste le rejoindre c'est ça ?
    mais surtout comment tu fait pour que instance soit la même variable pour tous les objets et su'ils n'aient pas chacun leur variable instance.
    edit : ha non c'est bon je viens de comprendre comment sa marche
    en tout cas merci pour tout c'est sympa de pouvoir demander de l'aide à des développeurs pro ça apprend plein de trucs comme ce design pattern magique je pense qu'il me reservira plusieurs fois

  18. #38
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Pro, c'est vite dis.XD.

    Sinon pour le singleton, fait attention, en général quand on le découvre, on veut en mettre partout, du coup ça devient vite le bordel, et au final on en met plus du tout sauf quand ça devient nécessaire.

    Regarde un peu sur internet les différent design pattern qui existe.

    Dans un moteur de widget, tu utilise surtout le singleton et le factory.

    Renseigne toi un peu sur ces deux là, tu auras surement besoin de les utilisés .

    Si tu as besoin n'hésite pas à poster tes questions dans ce thread, je te répondrais (sauf le weekend et jour férié, faut pas déconner non plus ^^).
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  19. #39
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    j'était justement entrain d'aller voir les design paterns et je me suis aussi dit que j'aurais surement tendance a en mettre partout et qu'il fallait pas en abuser X)

  20. #40
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 183
    Points : 60
    Points
    60
    Par défaut
    ha oui j'ai un problème avec la fonction de call back que tu m'avais donné :
    error: invalid conversion from 'void (*)()' to 'void (*)(void*)' [-fpermissive]|

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [swing][JButton] Des boutons qui disparaissent!
    Par soulhouf dans le forum Débuter
    Réponses: 12
    Dernier message: 19/08/2005, 12h51
  2. Api Win32 : boutons "qui bougent" au passage de la
    Par Spartan03 dans le forum Windows
    Réponses: 9
    Dernier message: 06/06/2005, 23h52
  3. Réponses: 10
    Dernier message: 10/06/2004, 16h20
  4. Réponses: 2
    Dernier message: 26/09/2003, 16h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo