kategoria: ANSI C
[#31] Re: Problemy z inicjalizacją GUI

@sand, post #27

Czy jest możliwość sprawdzenia wysokości tej ramki?

Window->BorderTop nie działa?

Ostatnia aktualizacja: 12.11.2024 07:43:15 przez Krashan
1
[#32] Re: Problemy z inicjalizacją GUI

@Krashan, post #31

Window->BorderTop nie działa?

Właśnie nie działało, bo okno u mnie jest jeszcze niezainicjowane. Więc użyłem:

border_height = s->WBorTop + s->Font->ta_YSize + 1;
gdzie s to screen.
Wrzuciłem nowa kompilacje w to samo miejsce:
[#33] Re: Problemy z inicjalizacją GUI

@sand, post #29

Wrzuciłeś nową wersję? Pobrałem teraz i pod oboma systemami działa dobrze. Normalnie można zapisać ustawienia i nic się nie zawiesza, znikło również okno debugowania.
[#34] Re: Problemy z inicjalizacją GUI

@Ponki1986, post #33

Tak przepisałem od nowa zapisywanie ustawień i zmieniłem ten topborder.
1
[#35] Re: Problemy z inicjalizacją GUI

@sand, post #34

Mam małą prośbę, abyś zaczął numerować wersję binarki bo już miałem pisać, że na MorphOS dalej jest problem z oknem, aż tu nagle wrzuciłeś nową kompilacje. Teraz jest ok, pola tekstowe Name i Tags nie wjeżdżają już na ramkę okna.
[#36] Re: Problemy z inicjalizacją GUI

@Ponki1986, post #35

Hmmm, jak na razie jest za dużo zmian, żeby to numerować. Ale może się postaram, moge użyć hasha żeby to rozroznic. Zrobiłem pare zmian w interface i teraz jest to projekt jednookienny. Jak chcesz proszę rzuć okiem. Nowa wersja





Ostatnia aktualizacja: 13.11.2024 03:30:50 przez sand
1
[#37] Re: Problemy z inicjalizacją GUI

@sand, post #36

Sprawdziłem wersję jednookienkową i ogólnie działa dobrze, ale nie są zapisywane ustawienia limitu. Podaje wartość 0 wyświetla się komunikat, że ustawienia zostały zapisane, ale ponownym uruchomieniu nadal jest ustawione na 100. Pod MOSem okienko ustawień ma podobny problem jak wcześniej, pierwsze pole tekstowe rysowane jest na ramce okna.

W tej jenooienkowek wersji była by możliwość podświetlenia wybranej stacji?
[#38] Re: Problemy z inicjalizacją GUI

@Ponki1986, post #37

Dzieki, okno i zapisywanie poprawione. Co do podświetlania to musiłbym napisać nowy gadget bo listview, z tego co wiem nie obsługuje podświetlania.
[wyróżniony] [#39] Re: Problemy z inicjalizacją GUI

@sand, post #38

Co do podświetlania to musiłbym napisać nowy gadget bo listview, z tego co wiem nie obsługuje podświetlania.

Podświetlanie aktywnego wpisu na liście ListView jest możliwe ustawiając tag GTLV_ShowSelected na NULL. Za pomocą tego tagu można też wyświetlać aktywny wpis pod gadżetem.

Ponadto, w razie potrzeby, jest możliwość własnego rysowania elementów listy w ListView za pomocą funkcji typu CallBack. Służy do tego tag GTLV_CallBack.

P.S. Odnosząc się do wcześniejszego wątku, to gadżet ListView wyświetla etykietę w wybranym we flagach (ng_Flags) miejscu (PLACETEXT_LEFT itp.). Widzę, że u Ciebie nie ma tej etykiety. Od położenia etykiety zależy położenie gadżetu ListView.
1
[#40] Re: Problemy z inicjalizacją GUI

@Hexmage960, post #39

Super dzięki GTLV_ShowSelected działa znakomicie. W wolnej chwili zobaczę GTLV_CallBack. Czy masz może jakiś przykład uzywajacy GTLV_CallBack ? Jedyny jaki znalazłem to rysowanie penem po listview.
[#41] Re: Problemy z inicjalizacją GUI

@sand, post #40

Czy masz może jakiś przykład uzywajacy GTLV_CallBack ? Jedyny jaki znalazłem to rysowanie penem po listview.

Pełny przykład wykorzystania tego tagu znajdziesz w Native Developer Kit 3.1 w Examples1/Gadtools/ListView.c.
[#42] Re: Problemy z inicjalizacją GUI

@sand, post #40

Potwierdzam, że podświetlenie wybranej stacji działa prawidłowo pod MOSem i OS3.9. Problem z rysowaniem pola tekstowego na belce tytułowej okna ustawień również znikł. Ustawienia także są zapisywane i po kliknięciu SAVE używane do póki program nie zostanie zamknięty. Po ponownym uruchomieniu limit nadal ustawiony jest na 100 tak jakby ten zapisany w ustawieniach był ignorowany.

Wrzuciłem ikonkę w formacie Glow3.5/3.9 może się komuś spodoba. Jest to miks zmontowany w PPaint-cie z dwóch ikon zawartych na płytach GlowIcons Collection 1 & 2.

Ostatnia aktualizacja: 13.11.2024 19:15:09 przez Ponki1986
[#43] Re: Problemy z inicjalizacją GUI

@Ponki1986, post #42

Dzięki za raport, wczytywanie poprawione i wrzuciłem poprawiona, wersje w to samo miejsce gdzie poprzednie. Na razie już mi wystarczy tych zmian. Następne będą jak ogarnę poprawnie tego Hooka.
[#44] Re: Problemy z inicjalizacją GUI

@sand, post #43

Sprawdzone i jest wszystko OK. Świetna robota OK
[#45] Re: Problemy z inicjalizacją GUI

@sand, post #43

Następne będą jak ogarnę poprawnie tego Hooka.

Jakiego używasz kompilatora?

Jeżeli chcesz wykorzystać tego Hooka do narysowania elementów listy, to wystarczy że napiszesz odpowiednią funkcję typu CallBack w języku wysokiego poziomu (C) z odpowiednimi parametrami, a następnie podepniesz ją pod składową h_SubEntry struktury Hook.

Trzeba jeszcze podpiąć stuba HookEntry (np. z amiga.lib), który przekłada argumenty z rejestrów na stos, pod składową h_Entry i gotowe. Teraz tworzysz gadżet ListView podając GTLV_CallBack i adres Hooka.

Pole h_Data możesz wykorzystać do przekazywania dowolnych swoich danych do tej funkcji.

Ostatnia aktualizacja: 14.11.2024 11:55:01 przez Hexmage960
[#46] Re: Problemy z inicjalizacją GUI

@Hexmage960, post #45

Hej, zacząłem pisać zgodnie z przykładem, ale na razie efekty są słabe. Aplikacja się nie zawiesza, ale też nie działa poprawnie – ramka jest pusta, chociaż można w nią kliknąć. Podejrzewam, że coś jest nie tak z rysowaniem. Używam GCC 6.5, więc sam przykład sprawił trochę problemów przy adaptacji. W weekend będę miał więcej czasu, żeby dokładniej się tym zająć. Gdybyś mógł rzucić okiem na poniższy kod, byłoby super!


struct ExtNode {
    struct Node node;
    char *displayText;
    char *name;
    char *url;
    char *codec;
    char *country;
    int bitrate;
};
static UWORD GhostPattern[2] = {
    0x4444,
    0x1111
};

static VOID Ghost(struct RastPort *rp, UWORD pen, UWORD x0, UWORD y0, UWORD x1, UWORD y1)
{
    SetABPenDrMd(rp, pen, 0, JAM1);
    SetAfPt(rp, GhostPattern, 1);
    RectFill(rp, x0, y0, x1, y1);
    SetAfPt(rp, NULL, 0);
}
static ULONG RenderHook(register struct Hook *hook,
                       register struct Node *node,
                       register struct LVDrawMsg *msg)
{
    struct RastPort *rp;
    struct DrawInfo *drawInfo;
    UWORD *pens;
    struct ExtNode *ext;
    char buffer[32];
    WORD x, y, columnWidth;
    
    if (msg->lvdm_MethodID != LV_DRAW)
        return LVCB_UNKNOWN;
        
    rp = msg->lvdm_RastPort;
    drawInfo = msg->lvdm_DrawInfo;
    pens = drawInfo->dri_Pens;
    ext = (struct ExtNode *)node;  
    
    if (!rp || !drawInfo || !ext)
        return LVCB_UNKNOWN;
    
    // Set up pens and drawing mode -( trying TEXTPEN  not  FILLTEXTPEN )
    SetABPenDrMd(rp, pens[TEXTPEN], pens[BACKGROUNDPEN], JAM2);

    // Calculate column widths (divide space into 4 columns)
    columnWidth = (msg->lvdm_Bounds.MaxX - msg->lvdm_Bounds.MinX) / 4;
    
    // Clear the background
    SetAPen(rp, pens[BACKGROUNDPEN]);
    RectFill(rp, msg->lvdm_Bounds.MinX, msg->lvdm_Bounds.MinY,
             msg->lvdm_Bounds.MaxX, msg->lvdm_Bounds.MaxY);
             
    // Set text color
    SetAPen(rp, pens[FILLTEXTPEN]);
    
    // Draw vertical separators
    for (int i = 1; i < 4; i++) {
        x = msg->lvdm_Bounds.MinX + (columnWidth * i);
        Move(rp, x, msg->lvdm_Bounds.MinY);
        Draw(rp, x, msg->lvdm_Bounds.MaxY);
    }
    
    // Calculate vertical centering
    y = msg->lvdm_Bounds.MinY + ((msg->lvdm_Bounds.MaxY - msg->lvdm_Bounds.MinY - rp->TxHeight) / 2) + rp->TxBaseline;
    
    // Draw name
    if (ext->name) {
        Move(rp, msg->lvdm_Bounds.MinX + 4, y);
        Text(rp, ext->name, strlen(ext->name));
    }
    
    // Draw codec
    if (ext->codec) {
        Move(rp, msg->lvdm_Bounds.MinX + columnWidth + 4, y);
        Text(rp, ext->codec, strlen(ext->codec));
    }
    
    // Draw bitrate
    sprintf(buffer, "%ld kbps", ext->bitrate);
    Move(rp, msg->lvdm_Bounds.MinX + (columnWidth * 2) + 4, y);
    Text(rp, buffer, strlen(buffer));
    
    // Draw country
    if (ext->country) {
        Move(rp, msg->lvdm_Bounds.MinX + (columnWidth * 3) + 4, y);
        Text(rp, ext->country, strlen(ext->country));
    }
    
    // Ghost the item if disabled
    if (msg->lvdm_State == LVR_NORMALDISABLED || msg->lvdm_State == LVR_SELECTEDDISABLED) {
        Ghost(rp, pens[BLOCKPEN], msg->lvdm_Bounds.MinX, msg->lvdm_Bounds.MinY,
              msg->lvdm_Bounds.MaxX, msg->lvdm_Bounds.MaxY);
    }
    
    return LVCB_OK;
}
renderHook.h_Entry = *(HOOKFUNC)RenderHook;  
renderHook.h_SubEntry = NULL;
renderHook.h_Data = NULL;
    listView = CreateGadget(LISTVIEW_KIND, searchButton, &ng,
                            GTLV_Labels, site_labels,
                            GTLV_ShowSelected, NULL, 
                            GTLV_CallBack, &renderHook,
                            GTLV_ScrollWidth, 16,
                            GTLV_ItemHeight,   12,
                            GTLV_Selected,     0,
                            GTLV_MaxPen,       255,
                            GTLV_ReadOnly, FALSE,
                            TAG_DONE);
[#47] Re: Problemy z inicjalizacją GUI

@sand, post #46

Procedura w języku C (która standardowo pobiera parametry ze stosu) powinna być podpięta pod h_SubEntry.

Natomiast w h_Entry umieszczasz procedurę, która wstawi rejestry na stos.

Biblioteka linkowalna amiga.lib dostarcza taką funkcję o nazwie HookEntry (zobacz np. plik nagłówkowy clib/alib_protos.h).

I tutaj nie wiem, czy w GCC możesz w prosty sposób załączyć amiga.lib. Zapewne trzeba zbudować/pozyskać plik libamiga.a. Co nieco informacji znajdziesz w dokumentacji libnix.guide.

Pamiętaj też, że jeżeli Twoja funkcja CallBack stosuje jakiekolwiek zmienne globalne (w tym odwołania do baz bibliotek), by użyć funkcji geta4() na początku. Być może istnieje odpowiednia dyrektywa, ale nie mam tutaj praktyki z GCC.

W SAS/C czy DICE jest to prostsze - wykorzystanie amiga.lib i zaznaczenie funkcji jako callback.

Co do funkcji rysowania - najpewniej wykonujesz prawidłowo.

P.S. Jeszcze drobna uwaga: nie trzeba wyłuskiwać danej spod adresu. Wystarczy podać adres funkcji.

h_SubEntry = (HOOKFUNC)RenderHook;


Ostatnia aktualizacja: 14.11.2024 15:52:31 przez Hexmage960
[#48] Re: Problemy z inicjalizacją GUI

@Hexmage960, post #47

Udało się ;]


Jakby ktoś jeszcze mógł przetestować u siebie :)
1
[#49] Re: Problemy z inicjalizacją GUI

@Hexmage960, post #47

Procedura w języku C (która standardowo pobiera parametry ze stosu) powinna być podpięta pod h_SubEntry.
W GCC można wykorzystać możliwość wskazania argumentom funkcji konkretnych rejestrów procesora. Jeżeli korzystamy z adresowania danych globalnych względem rejestru A4, (-fbaserel), to zamiast geta4 dodajemy funkcji atrybut __saveds__. Wtedy można funkcję dać jako h_Entry.
__saveds__  static ULONG RenderHook(struct Hook *hook asm("a2"), struct Node *node asm("a0"), struct LVDrawMsg *msg asm("a1"))

To działa w GCC 2.95.3 (chyba że piszemy w C++). W nowych to nie mam pojęcia, tam się autorom nie chciało paru amigowo przydatnych rzeczy zaimplementować...
1
[#50] Re: Problemy z inicjalizacją GUI

@Krashan, post #49

Ja zrobiłem to trochę po metoda prób i błędów, bo przykłady są głównie do SAS/C. Wrzucę poniżej może się komuś przyda:

static ULONG RenderFunc(struct Hook *hook, struct Node *node, struct LVDrawMsg *msg)
{
    geta4();
    
    struct RastPort *rp;
    struct DrawInfo *drawInfo;
    UWORD *pens;
    struct ExtNode *ext;
    char buffer[32];
    char nameBuffer[MAX_STATION_NAME + 1];
    WORD x, y;
    WORD totalWidth;
    WORD nameWidth, codecWidth, bitrateWidth, countryWidth;
    UWORD bgColor, fgColor;  
    
    if (!msg || msg->lvdm_MethodID != LV_DRAW)
        return LVCB_UNKNOWN;
        
    rp = msg->lvdm_RastPort;
    drawInfo = msg->lvdm_DrawInfo;
    pens = drawInfo->dri_Pens;
    ext = (struct ExtNode *)node;
    
    if (!rp || !drawInfo || !ext)
        return LVCB_UNKNOWN;
    
    // Set colors  
    if (msg->lvdm_State == LVR_SELECTED || msg->lvdm_State == LVR_SELECTEDDISABLED) {
        bgColor = pens[FILLPEN];
        fgColor = pens[FILLTEXTPEN];
    } else {
        bgColor = pens[BACKGROUNDPEN];
        fgColor = pens[TEXTPEN];
    }
    
    // Set up pens and drawing mode
    SetABPenDrMd(rp, fgColor, bgColor, JAM2);

    // Calculate column widths
    totalWidth = msg->lvdm_Bounds.MaxX - msg->lvdm_Bounds.MinX;
    nameWidth = (totalWidth * 75) / 100;
    codecWidth = (totalWidth * 10) / 100;
    bitrateWidth = (totalWidth * 10) / 100;
    countryWidth = totalWidth - nameWidth - codecWidth - bitrateWidth;
    
    // Clear the background  
    SetAPen(rp, bgColor);
    RectFill(rp, msg->lvdm_Bounds.MinX, msg->lvdm_Bounds.MinY,
             msg->lvdm_Bounds.MaxX, msg->lvdm_Bounds.MaxY);
             
    // Set text color
    SetAPen(rp, fgColor);
    
    // Draw vertical separators at new positions
    x = msg->lvdm_Bounds.MinX + nameWidth;
    Move(rp, x, msg->lvdm_Bounds.MinY);
    Draw(rp, x, msg->lvdm_Bounds.MaxY);
    
    x += codecWidth;
    Move(rp, x, msg->lvdm_Bounds.MinY);
    Draw(rp, x, msg->lvdm_Bounds.MaxY);
    
    x += bitrateWidth;
    Move(rp, x, msg->lvdm_Bounds.MinY);
    Draw(rp, x, msg->lvdm_Bounds.MaxY);
    
    // Calculate v. centering
    y = msg->lvdm_Bounds.MinY + ((msg->lvdm_Bounds.MaxY - msg->lvdm_Bounds.MinY - rp->TxHeight) / 2) + rp->TxBaseline;
    
    // Draw name
    if (ext->name) {
        cleanNonAscii(nameBuffer, ext->name, MAX_STATION_NAME + 1);
        Move(rp, msg->lvdm_Bounds.MinX + 4, y);
        Text(rp, nameBuffer, strlen(nameBuffer));
    }
    
    // Draw codec
    if (ext->codec) {
        ULONG textLength = strlen(ext->codec);
        ULONG textWidth = TextLength(rp, ext->codec, textLength);
        Move(rp, msg->lvdm_Bounds.MinX + nameWidth + codecWidth - textWidth - 4, y);
        Text(rp, ext->codec, textLength);
    }
    
    // Draw bitrate
    sprintf(buffer, "%ld", ext->bitrate);  
    ULONG textLength = strlen(buffer);
    ULONG textWidth = TextLength(rp, buffer, textLength);
    Move(rp, msg->lvdm_Bounds.MinX + nameWidth + codecWidth + bitrateWidth - textWidth - 4, y);
    Text(rp, buffer, textLength);
    // Draw country
    if (ext->country) {
        Move(rp, msg->lvdm_Bounds.MinX + nameWidth + codecWidth + bitrateWidth + 4, y);
        Text(rp, ext->country, strlen(ext->country));
    }
    
    // Ghost if disabled
    if (msg->lvdm_State == LVR_NORMALDISABLED || msg->lvdm_State == LVR_SELECTEDDISABLED) {
        Ghost(rp, pens[BLOCKPEN], msg->lvdm_Bounds.MinX, msg->lvdm_Bounds.MinY,
              msg->lvdm_Bounds.MaxX, msg->lvdm_Bounds.MaxY);
    }
    
    return LVCB_OK;
}
I to renderhook dla listy 
renderHook.h_Entry = (HOOKFUNC)HookEntry;  // Standard entry stub
renderHook.h_SubEntry = (HOOKFUNC)RenderFunc;


Oczywiście funkcja liczenia szerokości do poprawienia, bo powinienem na początku obliczyć ile max mogą zająć codec, bitrate i country przyjmując szerokość fontu jako podstawę a resztę przeznaczyć dla nazwy. Ale to później.

Ostatnia aktualizacja: 15.11.2024 08:29:53 przez sand

Ostatnia aktualizacja: 15.11.2024 08:30:49 przez sand
[#51] Re: Problemy z inicjalizacją GUI

@Krashan, post #49

Tak, zdawałem sobie sprawę, że w GCC też istnieje dyrektywa saveds, która zastępuje geta4() oraz można przekazywać argumenty do funkcji przez konkretne rejestry. Tylko wygląda to troszkę inaczej niż w SAS/C, czy DICE. Dzięki za podanie sposobu.

@Sand

Fajnie, że to działa. Czy miałeś jakiś problem z załączeniem amiga.lib? Ciekawym, bo sam chciałbym poszerzyć swoją wiedzę praktyczną o GCC.

Ostatnia aktualizacja: 15.11.2024 11:14:54 przez Hexmage960
[#52] Re: Problemy z inicjalizacją GUI

@Hexmage960, post #51

Fajnie, że to działa. Czy miałeś jakiś problem z załączeniem amiga.lib? Ciekawym, bo sam chciałbym poszerzyć swoją wiedzę praktyczną o GCC.

Zupelnie to tylko kwestia nagłówków i -lamiga przy linkowaniu.
[#53] Re: Problemy z inicjalizacją GUI

@sand, post #48

U mnie dział OK, tylko nie działają strzałki w górę i w dół poniżej suwaka. Sam suwak działa prawidłowo.
[#54] Re: Problemy z inicjalizacją GUI

@Ponki1986, post #53

Ja tylko zasugeruję, że jeżeli jest problem ze strzałkami to być może brakuje flagi IDCMP (np. ARROWIDCMP).

Należy załączyć LISTVIEWIDCMP.

Tu definicja z pliku libraries/gadtools.h:

#define LISTVIEWIDCMP	(IDCMP_GADGETUP | IDCMP_GADGETDOWN |\
	IDCMP_MOUSEMOVE | ARROWIDCMP)
[#55] Re: Problemy z inicjalizacją GUI

@Hexmage960, post #54

Należy załączyć LISTVIEWIDCMP.


To już wykluczyłem, niestety dodanie tej definicji nic nie pomogło. Wieczorem wrócę do tego problemu.

@Ponki1986 czy to kiedykolwiek działało? Bo poprzednia wersja bez tego Hooka, tez jest głucha na klawiature.

Ostatnia aktualizacja: 15.11.2024 17:43:36 przez sand
[#56] Re: Problemy z inicjalizacją GUI

@sand, post #55

Jeszcze jedno przypuszczenie: może chodzi o nadanie atrybutów GA_Immediate, TRUE i GA_RelVerify, TRUE przy tworzeniu gadżetu typu ListView. To są atrybuty z pliku intuition/gadgetclass.h.

P.S. Rozumiem, że obsługujesz wiadomości IntuiMessage za pomocą GT_GetIMsg() i GT_ReplyIMsg()?

Ostatnia aktualizacja: 15.11.2024 18:25:09 przez Hexmage960
[#57] Re: Problemy z inicjalizacją GUI

@sand, post #55

Ale ja miałem na myśli graficzne przyciski że strzałkami w górę i w dół, nie klawisze na klawiaturze.
[#58] Re: Problemy z inicjalizacją GUI

@Ponki1986, post #57

Ahh to więcej roboty, ale da się na bank tego scrolla kontrolować. Pomyślę o tym w następnej wersji. Na razie udało mi się właściwie skończyc wszystko co zamierzałem dodać w następnej wersji.
[#59] Re: Problemy z inicjalizacją GUI

@sand, post #58

W Listview scrollery same sie obsluguja wiec nie zwraca on innych msg oprocz gadgetup
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem