← index
MasterX_System/system/src/mx_menu.cpp
Source: MasterX_System/system/src/mx_menu.cpp
#include "mx_menu.hpp"

#include "mx_window.hpp"


namespace mx {

        Menu_Header create_header(const std::string &text) {
            Menu_Header header;
            header.enabled = true;
            header.text = text;
            return header;
        }
        Menu_Item<menuCallback>   create_menu_item(const std::string &text, menuCallback callback) {
            Menu_Item<menuCallback> item;
            item.callback = callback;
            item.text = text;
            item.enabled = true;
            item.icon = -1;
            return item;
        }


        Menu_Header::Menu_Header() {
            visible = false;
         }
        
        Menu_Header::~Menu_Header() {

        }

        void Menu::setWindowPos(int w, int h) {

        }

        Menu::Menu(mxApp &app, Window *w) : win{w} {
            Menu_Header header;
            header.enabled = true;
            header.text = "Window";
            header.window_menu =true;
            Menu_ID id = addHeader(header);
            Menu_Item<menuCallback> item_;
            item_.item_rect = {0};
            item_.callback = [](mxApp &app, Window *win, SDL_Event &e) -> bool {
                win->show(false);
                return true;
            };
            item_.text = "Quit";
            addItem(id, addIcon(loadTexture(app, "images/xicon.png")), item_);
            hide();
        }
        int Menu::addIcon(SDL_Texture *tex) {
            icons.push_back(tex);
            return icons.size()-1;
        }

        void Menu::hide() {
            menu_active = false;
            for(auto &i : menu) {
                i.visible = false;
                for (auto &mi: i.items) {
                    mi.underline = false;
                }
            }
        }

        void Menu::draw(mxApp &app) {
            TTF_SetFontStyle(app.font, TTF_STYLE_BOLD);
            SDL_Rect rc = {0, 0, app.width, 30};
            SDL_SetRenderDrawBlendMode(app.ren, SDL_BLENDMODE_BLEND);
            SDL_SetRenderDrawColor(app.ren, 200, 200, 200, 200);
            SDL_RenderFillRect(app.ren, &rc);
            SDL_SetRenderDrawBlendMode(app.ren, SDL_BLENDMODE_NONE);
            SDL_Rect rci = {10,7,20,20};
            SDL_RenderCopy(app.ren, win->icon != nullptr ? win->icon : app.icon,nullptr,&rci);
            int padding = 25;
            int x = 15 + padding; 
            int y = 7;  
            for (auto &header : menu) {
                SDL_Surface* headerSurface = TTF_RenderText_Blended(app.font, header.window_menu ? win->title.c_str() : header.text.c_str(), {0, 0, 0, 255});
                SDL_Texture* headerTexture = SDL_CreateTextureFromSurface(app.ren, headerSurface);
                SDL_QueryTexture(headerTexture, NULL, NULL, &header.header_rect.w, &header.header_rect.h);
                header.header_rect.x = x;
                header.header_rect.y = y;
                if(header.is_messagebox == false) {
                    SDL_RenderCopy(app.ren, headerTexture, NULL, &header.header_rect);
                    header.text_rect = header.header_rect;
                }
                SDL_FreeSurface(headerSurface);
                SDL_DestroyTexture(headerTexture);
                header.header_rect.x -= 5;
                x += header.header_rect.w + padding;
                
                
                if (header.visible) {
                    int itemY = 30;  
                    for (auto &item : header.items) {
                        SDL_Color col;
                        if(item.underline) {
                            TTF_SetFontStyle(app.font,TTF_STYLE_UNDERLINE | TTF_STYLE_BOLD);
                            cursor_shown = true;
                            col = {0,0,255,255};
                        } else {
                            col = {0,0,0,255};
                            TTF_SetFontStyle(app.font, TTF_STYLE_BOLD);
                        }
                        
                        SDL_Surface* itemSurface = TTF_RenderText_Blended(app.font, item.text.c_str(), col);
                        SDL_Texture* itemTexture = SDL_CreateTextureFromSurface(app.ren, itemSurface);
                        SDL_QueryTexture(itemTexture, NULL, NULL, &item.item_rect.w, &item.item_rect.h);
                        item.item_rect.x = header.header_rect.x+30;
                        item.item_rect.y = itemY+5;
                        SDL_Rect rcx = {header.header_rect.x, itemY, 175, 30};
                        SDL_SetRenderDrawBlendMode(app.ren, SDL_BLENDMODE_BLEND);
                        SDL_SetRenderDrawColor(app.ren, 200, 200, 200, 200);
                        SDL_RenderFillRect(app.ren, &rcx); 
                        SDL_SetRenderDrawBlendMode(app.ren, SDL_BLENDMODE_NONE);
                        SDL_RenderCopy(app.ren, itemTexture, NULL, &item.item_rect);
                        TTF_SetFontStyle(app.font, TTF_STYLE_BOLD);
                        SDL_FreeSurface(itemSurface);
                        SDL_DestroyTexture(itemTexture);
                        if(item.icon != -1) {
                            SDL_Rect ico_rect = {header.header_rect.x + 5, itemY + 5, 20, 20};  
                            SDL_RenderCopy(app.ren, icons[item.icon], nullptr, &ico_rect);
                        }

                        itemY += 30; 
                    }
                }
            }
            TTF_SetFontStyle(app.font, TTF_STYLE_NORMAL);
        }

        bool Menu::event(mxApp &app, SDL_Event &e) {
            if (menu_active) {
                if (e.type == SDL_MOUSEMOTION) {
                    SDL_Point p = {e.motion.x, e.motion.y};
                    for (auto &header : menu) {
                        if (SDL_PointInRect(&p, &header.text_rect)) {
                            for (auto &h : menu) { h.visible = false; }
                            header.visible = true;
                            return true;
                        }
                    }
                }

                if (e.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT) {
                    SDL_Point p = {e.button.x, e.button.y};
                    bool clicked_outside = true;
                    for (auto &header : menu) {
                        if (header.visible && header.is_messagebox == false) {
                            for (auto &item : header.items) {
                                if (SDL_PointInRect(&p, &item.item_rect)) {
                                    if (item.callback) {
                                        if (item.callback(app, win, e)) {
                                            menu_active = false;
                                            hide();
                                            return true;
                                        }
                                    }
                                }
                            }
                        }
                        if (SDL_PointInRect(&p, &header.text_rect)) {
                            clicked_outside = false;
                        }
                    }
                    if (clicked_outside) {
                        menu_active = false;
                        hide();
                    }
                }
            }

            if (e.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT) {
                SDL_Point p = {e.button.x, e.button.y};
                for (auto &header : menu) {
                    if (SDL_PointInRect(&p, &header.text_rect)) {
                        menu_active = true;
                        for (auto &h : menu) { h.visible = false; }
                        header.visible = true;
                        return true;
                    }
                }
            }

            if (e.type == SDL_MOUSEMOTION) {
                SDL_Point p = {e.motion.x, e.motion.y};
                for (auto &header : menu) {
                    if (header.visible) {
                        for (auto &item : header.items) {
                            if (SDL_PointInRect(&p, &item.item_rect)) {
                                item.underline = true;
                            } else {
                                item.underline = false;
                            }
                        }
                    }
                }
            }
            return false;
    }


    Menu_ID Menu::addHeader(const Menu_Header &h) {
        menu.push_back(h);
        return menu.size()-1;
    }
    
    Menu_ID Menu::addItem(int header, int id, const Menu_Item<menuCallback> &i) {
        menu[header].items.push_back(i);
        menu[header].items.back().icon = id;
        return menu[header].items.size()-1;
    }
    
    
    
}