diff --git a/src/app.c b/src/app.c

index ff5ec9b7..0916919e 100644

--- a/src/app.c

+++ b/src/app.c

@@ -649,12 +649,17 @@ iAny *findWidget_App(const char *id) {

 return findChild_Widget(app_.window->root, id);

}



-void addTicker_App(void (*ticker)(iAny *), iAny *context) {

+void addTicker_App(iTickerFunc ticker, iAny *context) {

 iApp *d = &app_;

 insert_SortedArray(&d->tickers, &(iTicker){ context, ticker });

 postRefresh_App();

}



+void removeTicker_App(iTickerFunc ticker, iAny *context) {

+ iApp *d = &app_;

+ remove_SortedArray(&d->tickers, &(iTicker){ context, ticker });

+}

+

iGmCerts *certs_App(void) {

 return app_.certs;

}

@@ -737,7 +742,8 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf, iBool switchToNe

     doc = new_DocumentWidget();

 }

 setId_Widget(as_Widget(doc), format_CStr("document%03d", ++d->tabEnum));

- appendTabPage_Widget(tabs, iClob(doc), "", 0, 0);

+ appendTabPage_Widget(tabs, as_Widget(doc), "", 0, 0);

+ iRelease(doc); /* now owned by the tabs */

 addChild_Widget(findChild_Widget(tabs, "tabs.buttons"), iClob(newTabButton));

 if (switchToNew) {

     postCommandf_App("tabs.switch page:%p", doc);

diff --git a/src/app.h b/src/app.h

index db22230e..bf310d98 100644

--- a/src/app.h

+++ b/src/app.h

@@ -73,8 +73,11 @@ iObjectList * listDocuments_App (void);

iDocumentWidget * document_Command (const char *cmd);

iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew);



+typedef void (*iTickerFunc)(iAny *);

+

iAny * findWidget_App (const char *id);

-void addTicker_App (void (*ticker)(iAny *), iAny *context);

+void addTicker_App (iTickerFunc ticker, iAny *context);

+void removeTicker_App (iTickerFunc ticker, iAny *context);

void postRefresh_App (void);

void postCommand_App (const char *command);

void postCommandf_App (const char *command, ...);

diff --git a/src/audio/player.c b/src/audio/player.c

index 5b9d0103..07f41f01 100644

--- a/src/audio/player.c

+++ b/src/audio/player.c

@@ -563,3 +563,9 @@ float streamProgress_Player(const iPlayer *d) {

 }

 return 0;

}

+

+iString *metadataLabel_Player(const iPlayer *d) {

+ return newFormat_String("%d-bit %s %d Hz", SDL_AUDIO_BITSIZE(d->decoder->inputFormat),

+ SDL_AUDIO_ISFLOAT(d->decoder->inputFormat) ? "float" : "integer",

+ d->spec.freq);

+}

diff --git a/src/audio/player.h b/src/audio/player.h

index c3552640..fe6717b0 100644

--- a/src/audio/player.h

+++ b/src/audio/player.h

@@ -45,3 +45,5 @@ iBool isPaused_Player (const iPlayer *);

float time_Player (const iPlayer *);

float duration_Player (const iPlayer *);

float streamProgress_Player (const iPlayer ); / normalized 0...1 */

+

+iString * metadataLabel_Player (const iPlayer *);

diff --git a/src/media.c b/src/media.c

index 253893fc..c447704b 100644

--- a/src/media.c

+++ b/src/media.c

@@ -75,8 +75,8 @@ void deinit_GmImage(iGmImage *d) {

}



void makeTexture_GmImage(iGmImage *d) {

- iBlock *data = &d->partialData;

- d->numBytes = size_Block(data);

+ iBlock *data = &d->partialData;

+ d->numBytes = size_Block(data);

 uint8_t *imgData = stbi_load_from_memory(

     constData_Block(data), size_Block(data), &d->size.x, &d->size.y, NULL, 4);

 if (!imgData) {

diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c

index 9d94f200..bbe5ccba 100644

--- a/src/ui/documentwidget.c

+++ b/src/ui/documentwidget.c

@@ -191,6 +191,7 @@ struct Impl_DocumentWidget {

 iAnim          outlineOpacity;

 iArray         outline;

 iWidget *      menu;

+ iWidget * playerMenu;

 iVisBuf *      visBuf;

 iPtrSet *      invalidRuns;

};

@@ -241,6 +242,7 @@ void init_DocumentWidget(iDocumentWidget *d) {

 init_Click(&d->click, d, SDL_BUTTON_LEFT);

 addChild_Widget(w, iClob(d->scroll = new_ScrollWidget()));

 d->menu = NULL; /* created when clicking */

+ d->playerMenu = NULL;

#if !defined (iPlatformApple) /* in system menu */

 addAction_Widget(w, reload_KeyShortcut, "navigate.reload");

 addAction_Widget(w, SDLK_w, KMOD_PRIMARY, "tabs.close");

@@ -249,7 +251,10 @@ void init_DocumentWidget(iDocumentWidget *d) {

 addAction_Widget(w, navigateForward_KeyShortcut, "navigate.forward");

}



+static void animatePlayingAudio_DocumentWidget_(void *);

+

void deinit_DocumentWidget(iDocumentWidget *d) {

+ removeTicker_App(animatePlayingAudio_DocumentWidget_, d);

 delete_VisBuf(d->visBuf);

 delete_PtrSet(d->invalidRuns);

 deinit_Array(&d->outline);

@@ -1626,7 +1631,7 @@ static void drawPlayerButton_(iPaint *p, iRect rect, const char *label) {

         adjusted_Rect(shrunk_Rect(frameRect, divi_I2(gap2_UI, 2)), zero_I2(), one_I2()),

         frame);

 }

- const int fg = isPressed ? uiBackground_ColorId : frame;

+ const int fg = isPressed ? (permanent_ColorId | uiBackground_ColorId) : uiHeading_ColorId;

 drawCentered_Text(uiContent_FontId, frameRect, iTrue, fg, "%s", label);

}



@@ -1704,6 +1709,11 @@ static iBool processAudioPlayerEvents_DocumentWidget_(iDocumentWidget *d, const

     ev->type != SDL_MOUSEMOTION) {

     return iFalse;

 }

+ if (ev->type == SDL_MOUSEBUTTONDOWN || ev->type == SDL_MOUSEBUTTONUP) {

+ if (ev->button.button != SDL_BUTTON_LEFT) {

+ return iFalse;

+ }

+ }

 const iInt2 mouse = init_I2(ev->button.x, ev->button.y);

 iConstForEach(PtrArray, i, &d->visiblePlayers) {

     const iGmRun *run = i.ptr;

@@ -1722,12 +1732,34 @@ static iBool processAudioPlayerEvents_DocumentWidget_(iDocumentWidget *d, const

             return iTrue;

         }

         else if (contains_Rect(ui.rewindRect, mouse)) {

- stop_Player(plr);

- start_Player(plr);

- setPaused_Player(plr, iTrue);

+ if (isStarted_Player(plr) && time_Player(plr) > 0.5f) {

+ stop_Player(plr);

+ start_Player(plr);

+ setPaused_Player(plr, iTrue);

+ }

             refresh_Widget(d);

             return iTrue;

         }

+ else if (contains_Rect(ui.menuRect, mouse)) {

+ /* TODO: Add menu items for:

+ - output device

+ - Save to Downloads

+ */

+ if (d->playerMenu) {

+ destroy_Widget(d->playerMenu);

+ d->playerMenu = NULL;

+ return iTrue;

+ }

+ d->playerMenu = makeMenu_Widget(

+ as_Widget(d),

+ (iMenuItem[]){

+ { cstrCollect_String(metadataLabel_Player(plr)), 0, 0, NULL },

+ },

+ 1);

+ openMenu_Widget(d->playerMenu,

+ localCoord_Widget(constAs_Widget(d), bottomLeft_Rect(ui.menuRect)));

+ return iTrue;

+ }

     }

 }

 return iFalse;

diff --git a/src/ui/util.c b/src/ui/util.c

index 13a7a7a2..89f71da2 100644

--- a/src/ui/util.c

+++ b/src/ui/util.c

@@ -498,9 +498,8 @@ iWidget *removeTabPage_Widget(iWidget *tabs, size_t index) {

 iWidget *button  = removeChild_Widget(buttons, child_Widget(buttons, index));

 iRelease(button);

 iWidget *page = child_Widget(pages, index);

- ref_Object(page);

 setFlags_Widget(page, hidden_WidgetFlag | disabled_WidgetFlag, iFalse);

- removeChild_Widget(pages, page);

+ removeChild_Widget(pages, page); /* page is now ours */

 if (tabCount_Widget(tabs) <= 1 && flags_Widget(buttons) & collapse_WidgetFlag) {

     setFlags_Widget(buttons, hidden_WidgetFlag, iTrue);

 }

diff --git a/src/ui/widget.c b/src/ui/widget.c

index 459c2ae1..ea2e3fe2 100644

--- a/src/ui/widget.c

+++ b/src/ui/widget.c

@@ -55,7 +55,6 @@ iPtrArray *onTop_RootData_(void) {

void destroyPending_Widget(void) {

 iForEach(PtrSet, i, rootData_.pendingDestruction) {

     iWidget *widget = *i.value;

- removeOne_PtrArray(onTop_RootData_(), widget);

     if (widget->parent) {

         iRelease(removeChild_Widget(widget->parent, widget));

     }

@@ -90,6 +89,9 @@ static void aboutToBeDestroyed_Widget_(iWidget *d) {

     setFocus_Widget(NULL);

     return;

 }

+ if (flags_Widget(d) & keepOnTop_WidgetFlag) {

+ removeOne_PtrArray(onTop_RootData_(), d);

+ }

 if (isHover_Widget(d)) {

     rootData_.hover = NULL;

 }

Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/release/pcdiff/bb7bc6fac4fec804846d11c7d77e1b553ba2be6a
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
25.331233 milliseconds
Gemini-to-HTML Time
2.726522 milliseconds

This content has been proxied by September (ba2dc).