GUIDA [C++][BETA] Libreria open-source per creare interfacce ai tuoi programmi SU WINDOWS ikarusgl BETA

Ikarus_

Nuovo Utente
1
4
Salve ragazzi,

Mi sto occupando di sviluppare una libreria open source per creare interfacce ai programmi su Windows.
Ho appositamente creato una repository su github e sto continuando a lavorarci, facendo nuovi tests e aggiungendo nuove features.

Magari qualcuno è interessato a provarla/usarla (dato che è già funzionale) e ad aiutarmi con i tests e magari potrebbe anche essere utile a qualcuno di voi.
Nel file test.cpp è possibile vedere un esempio di utilizzo molto semplice che crea una interfaccia molto basilare (un pò bruttina, ma è giusto per capire come va usata la libreria).
Ho scritto una documentazione che credo sia abbastanza dettagliata per aiutare chi prova la libreria a comprendere come usarla.

Link alla documentazione
Link alla repository

Specifico che la libreria è ottimizzata usando il multi-threading.
Oltre al thread principale che lancia il message loop possiede anche 2 altri thread che sono appositamente utilizzati rispettivamente per il rendering e l'updating dell'interfaccia.
E' possibile settare sia gli fps (frames per second) che gli ups (updates per second).
I tipi di widget che possiede sono al momento ancora il minimo indispensabile, ma presto aggiungerò molti altri widgets che renderanno la libreria molto rapida nella costruzione delle interfacce.

attuali widgets:
1. window (container di altri widget, tutta via possiede una sua size e position. Può acquistare anche un aspetto grafico settando il background della window)
2. text (testo stampato su schermo, derivando dal widget window ha anche esso size, position, background ed è possibile settare il colore ed il font del testo)
3. button (bottone che possiede i tre stati up, over, down che esegue una callback quando cliccato, anche esso deriva dal widget window ed ha quindi le proprietà di cui prima. Inoltre è possibile settare la cover del bottone o semplicemente il colore da mostrare in base allo stato del bottone. Ha anche la proprietà 'text' che mostra un testo nel bottone)
4. input (una input box nella quale l'utente puà scrivere del testo. Essendo derivato dall'oggetto text ha anche esso font e colore personalizzabile, oltre che il background)
5. image ( un immagine che si può aprire sia da file che da buffer. Supporta molti formati (gli stessi supportati da Gdiplus::Image che potete trovare sulle documentazioni di microsoft) ed ha proprietà differenti come la rect scale che può troncare l immagine o ripeterla più volte in fila e in colonna, l'apply color che applica un colore all'immagine, ed è possibile ridimensionarla a piacimento)
6.scrollbar (una barra di scorrimento che l'utente può usare per la navigazione eccetera)
7.animation (una serie di immagini aperte singolarmente e caricate in una animazione che come anche le image è totalmente ridimenzionabile e scalabile, inoltre è possibile regolare il frame rate dell'animazione)

Tutti questi widgets hanno una lunga lista di callback settabili usando funzioni o lambda appositamente dichiarate.
Sostanzialmente quello a cui mira la libreria è dare modo di creare l'interfaccia già completamente funzionante tramite le callbacks che sono usate poi automaticamente durante il message loop.

E' possibile registrare nell'oggetto 'gui' degli handler ai messaggi che sono inviati alla finestra dell'applicazione (per conoscere i messaggi inviati alla finestra si può leggere la documentazione Microsoft)

Spero qualcuno possa trovarla utile.
Lo scopo per il quale ho scritto la libreria è semplicemente imparare.
La libreria utilizza Gdi+ per il rendering, cosa che mi ha permesso con poco di utilizzare effetti molto carini con le trasparenze e il rendering delle immagini ma che mi ha anche allungato parecchio il rendering time.

La prima versione che usava GDI (senza +) raggiungeva anche 1200 fps senza problemi, ora invece arriva circa a 110 con il mio umile computer.


piccolo spoiler con un esempio di come costruire interfacce con questa libreria:
C++:
//Creare una gui:


ikgl::bool_t create_gui(ikgl::hinstance_t hInstance, ikgl::gui& gui) {





    ikgl::create_gui_infow_t info;

    ikgl::make_default_create_info(hInstance , &info);



    info.window_name = L"ikarusgl-test";

    info.x = 0;

    info.y = 0;

    info.width = 800;

    info.height = 600;

    info.wc.lpszClassName = L"ikarusgl-test";

    info.style = WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX ;



    if (!gui.create(&info)) {

        ikgl::utilities::error("cannot create gui!");

        return false;

    }



    else {

        g_guiptr = &gui;

        gui.set_window_min_resize({800,600});

        gui.maximize();

        insert_widgets();

        return true;

    }

}




//Creare una title bar :


void insert_titlebar(ikgl::gui& gui, ikgl::window* mainwindow) {

    //* creating the title bar

    auto titlebar = mainwindow->create_element<ikgl::window>();

    titlebar->set_background(&ikgl::background_info_t({ 0.15f, 0.15f, 0.18f, 1.0f }));

    titlebar->set_position(0, 0);

    titlebar->set_size(mainwindow->get_width(), 30);

    titlebar->set_window_name(L"title-bar");

    titlebar->set_on_resize_gui(__ikgl_wevent_lambda({

        c->set_size(c->get_gui()->get_size().width, c->get_height());

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));



    //* creating a color to set on the buttons

    ikgl::button_color_info_t button_colors;

    button_colors.border_color = { 0.0f, 0.0f, 0.0f, 1.0f };

    button_colors.border_width = 1;

    button_colors.default_color = { 0.35f, 0.35f, 0.38f, 1.0f };

    button_colors.over_color = { 0.42f, 0.42f, 0.45f, 1.0f };

    button_colors.down_color = { 0.30f, 0.30f, 0.38f, 1.0f };



    //* creating close and minimize button

    auto minimizebutton = titlebar->create_element<ikgl::button>();

    minimizebutton->set_position(0, 0);

    minimizebutton->set_size(27, 20);

    minimizebutton->move_vertical_center();

    minimizebutton->move_to_right();

    minimizebutton->move_left(6 + 6 +6 + 27 + 27);

    minimizebutton->set_text(std::wstring({0x2578, 0x0})); //* <-- unicode for "-" larger than the basic one '-'

    minimizebutton->set_colors(&button_colors);

    minimizebutton->set_window_name(L"minimize-button");

    minimizebutton->set_on_click_event(__ikgl_wevent_lambda({

        ikgl::external::show_window(c->get_gui()->get_hwnd(), SW_MINIMIZE);

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));

    minimizebutton->set_on_resize_gui(__ikgl_wevent_lambda({

        c->move_vertical_center();

        c->move_to_right();

        c->move_left(6 + 6 + 6 + 27 + 27);

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));



    //* creating close and minimize button

    auto closebutton = titlebar->create_element<ikgl::button>();

    closebutton->set_position(0, 0);

    closebutton->set_size(27, 20);

    closebutton->move_vertical_center();

    closebutton->move_to_right();

    closebutton->move_left(8);

    closebutton->set_text(L"X");

    closebutton->set_colors(&button_colors);

    closebutton->set_window_name(L"close-button");

    closebutton->set_on_click_event(__ikgl_wevent_lambda({

        c->get_gui()->quit();

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));

    closebutton->set_on_resize_gui(__ikgl_wevent_lambda({

        c->move_vertical_center();

        c->move_to_right();

        c->move_left(8);



        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));



    static ikgl::widget_size_t resize_size = { 800,600 };

    static ikgl::widget_pos_t resize_pos = { 0,0 };



    //* creating maximizebutton

    auto maximizebutton = titlebar->create_element<ikgl::button>();

    maximizebutton->set_position(0, 0);

    maximizebutton->set_size(27, 20);

    maximizebutton->move_vertical_center();

    maximizebutton->move_to_right();

    maximizebutton->move_left(8 + 6 + 27);

    maximizebutton->set_text(std::wstring({ 0x2610, 0x0}));

    maximizebutton->set_colors(&button_colors);

    maximizebutton->set_window_name(L"maximize-button");

    maximizebutton->set_on_click_event(__ikgl_wevent_lambda({

        resize_size = c->get_gui()->get_size();

        resize_pos = c->get_gui()->get_position();

        c->get_gui()->maximize();

        c->get_gui()->get_window_by_name(L"resize-button")->show();

        c->hide();



        auto hwnd = c->get_gui()->get_hwnd();

        auto flags = ikgl::external::get_window_long_ptr(hwnd, GWL_STYLE) & ~WS_THICKFRAME;

        ikgl::external::set_window_long_ptr(hwnd, GWL_STYLE, flags);

        ikgl::external::update_framemode(hwnd);

  

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));

    maximizebutton->set_on_resize_gui(__ikgl_wevent_lambda({

        c->move_vertical_center();

        c->move_to_right();

        c->move_left(8 + 6 + 27);

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));

    maximizebutton->hide();



    //* creating resizebutton

    auto resizebutton = titlebar->create_element<ikgl::button>();

    resizebutton->set_position(0, 0);

    resizebutton->set_size(27, 20);

    resizebutton->move_vertical_center();

    resizebutton->move_to_right();

    resizebutton->move_left(8 + 6 + 27);

    resizebutton->set_text(std::wstring({ 0x25F3, 0x0 }));

    resizebutton->set_colors(&button_colors);

    resizebutton->set_window_name(L"resize-button");

    resizebutton->set_on_click_event(__ikgl_wevent_lambda({

        c->get_gui()->get_window_by_name(L"maximize-button")->show();

        c->hide();

        c->get_gui()->resize_window(resize_size);

        c->get_gui()->move_window(resize_pos);



        auto hwnd = c->get_gui()->get_hwnd();

        auto flags = ikgl::external::get_window_long_ptr(hwnd, GWL_STYLE) | WS_THICKFRAME;

        ikgl::external::set_window_long_ptr(hwnd, GWL_STYLE, flags);

        ikgl::external::update_framemode(hwnd);

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));

    resizebutton->set_on_resize_gui(__ikgl_wevent_lambda({

        c->move_vertical_center();

        c->move_to_right();

        c->move_left(8 + 6 + 27);



        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));



    //* creating a font to set to the title

    ikgl::font_t font;

    ikgl::make_default_font(font);

    font.font_family = L"Corbel";

    font.size = 8;



    //* create the title text

    auto titletext = titlebar->create_element<ikgl::text>();

    titletext->set_position(0, 0);

    titletext->set_text("IKARUSGL-TEST : SAMPLE WINDOW", true);

    titletext->move_horizontal_center();

    titletext->move_vertical_center();

    titletext->set_horizontal_alignment(ikgl::text_halign_t::TEXT_HALIGN_CENTER);

    titletext->set_vertical_alignment(ikgl::text_valign_t::TEXT_VALIGN_CENTER);

    titletext->set_on_resize_gui(__ikgl_wevent_lambda({

        c->move_horizontal_center();

        return ikgl::widget_event_return_t::KEEP_CALLBACK;

    }));



    //* creating icon to set on the titlebar

    auto iconimage = titlebar->create_element<ikgl::image>();

    iconimage->load_image("resources/ikgl-icon.png");

    iconimage->set_size(12, 20);

    iconimage->move_to_left();

    iconimage->move_vertical_center();

    iconimage->move_right(7);

    iconimage->set_window_name(L"icon-image");



    //* used to set as movable window the interface

    set_movewindow_parts({ mainwindow, titlebar, titletext, iconimage });

}







//Creare una popup window:



void make_popup(const char* fmt, ...) {

    static char text[400];



    va_list args;

    va_start(args, fmt);

    vsnprintf_s(text, sizeof(text), fmt, args);

    va_end(args);



    auto popup = g_guiptr->get_window_by_name(L"popup-error");

    auto popup_text = (ikgl::text*) g_guiptr->get_window_by_name(L"popup-error-text");

    auto popup_close = (ikgl::button*) g_guiptr->get_window_by_name(L"popup-error-close");



    popup_text->set_text(text, true);

    auto size = popup_text->get_size();



    popup->set_size(size.width + 30, popup->get_height());

    popup->move_horizontal_center();

    popup->show();

    popup_text->move_horizontal_center();





    popup_close->move_horizontal_center();

    popup_close->set_on_click_event([] __ikgl_wevent_lambda_type_func{

        g_guiptr->get_window_by_name(L"popup-error")->hide();

        g_guiptr->call_render();

        return ikgl::widget_event_return_t::UNSET_CALLBACK;

    });

}





void insert_popup_window(ikgl::gui& gui, ikgl::window* mainwindow) {

    ikgl::button_color_info_t selected_colors = {

        { 0.1f, 0.1f, 0.1f, 1.0f },

        { 0.11f, 0.11f, 0.11f, 1.0f },

        { 0.05f, 0.05f, 0.05f, 1.0f },

        {},0

    };



    ikgl::button_color_info_t normal_colors = {

        { 0.05f, 0.05f, 0.05f, 1.0f },

        { 0.08f, 0.08f, 0.08f, 1.0f },

        { 0.05f, 0.05f, 0.05f, 1.0f },

        {},0

    };



    auto popup = mainwindow->create_element<ikgl::window>();

    popup->set_window_name(L"popup-error");

    popup->set_size(250, 150);

    popup->move_vertical_center();

    popup->move_horizontal_center();

    popup->set_background(ikgl::background_info_t({ normal_colors.default_color }));

    popup->hide();



    auto text = popup->create_element<ikgl::text>();

    text->set_text("no text", true);

    text->move_vertical_center();

    text->set_window_name(L"popup-error-text");

    text->set_horizontal_alignment(ikgl::text_halign_t::TEXT_HALIGN_CENTER);







    auto button = popup->create_element<ikgl::button>();

    button->set_colors(&selected_colors);

    button->set_text(L"Ok");

    button->set_size(65, 25);

    button->set_position(0, 110);

    button->move_horizontal_center();

    button->set_window_name(L"popup-error-close");



}

Per completezza aggiungerei che ho replicato con successo l'interfaccia di skype (solo la parte grafica ovviamente, senza essere realmente collegato ad alcun server) per paragonare le prestazioni in termini di consumo cpu, rendering time, etc. ed ho potuto notare con meraviglia che l'interfaccia replicata era circa 12 volte più efficiente.
 
Ultima modifica:

Entra

oppure Accedi utilizzando

Discussioni Simili

Hot del momento