diff options
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r-- | src/ui/documentwidget.c | 235 |
1 files changed, 118 insertions, 117 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 573cd3e3..e8287751 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -142,7 +142,12 @@ struct Impl_OutlineItem { | |||
142 | 142 | ||
143 | /*----------------------------------------------------------------------------------------------*/ | 143 | /*----------------------------------------------------------------------------------------------*/ |
144 | 144 | ||
145 | static const int smoothSpeed_DocumentWidget_ = 120; /* unit: gap_Text per second */ | 145 | static void animatePlayingAudio_DocumentWidget_(void *); |
146 | |||
147 | static const int smoothSpeed_DocumentWidget_ = 120; /* unit: gap_Text per second */ | ||
148 | static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */ | ||
149 | static const int outlineMaxWidth_DocumentWidget_ = 65; /* times gap_UI */ | ||
150 | static const int outlinePadding_DocumentWidget_ = 3; /* times gap_UI */ | ||
146 | 151 | ||
147 | enum iRequestState { | 152 | enum iRequestState { |
148 | blank_RequestState, | 153 | blank_RequestState, |
@@ -251,8 +256,6 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
251 | addAction_Widget(w, navigateForward_KeyShortcut, "navigate.forward"); | 256 | addAction_Widget(w, navigateForward_KeyShortcut, "navigate.forward"); |
252 | } | 257 | } |
253 | 258 | ||
254 | static void animatePlayingAudio_DocumentWidget_(void *); | ||
255 | |||
256 | void deinit_DocumentWidget(iDocumentWidget *d) { | 259 | void deinit_DocumentWidget(iDocumentWidget *d) { |
257 | removeTicker_App(animatePlayingAudio_DocumentWidget_, d); | 260 | removeTicker_App(animatePlayingAudio_DocumentWidget_, d); |
258 | delete_VisBuf(d->visBuf); | 261 | delete_VisBuf(d->visBuf); |
@@ -270,6 +273,24 @@ void deinit_DocumentWidget(iDocumentWidget *d) { | |||
270 | deinit_Model(&d->mod); | 273 | deinit_Model(&d->mod); |
271 | } | 274 | } |
272 | 275 | ||
276 | static void requestUpdated_DocumentWidget_(iAnyObject *obj) { | ||
277 | iDocumentWidget *d = obj; | ||
278 | const int wasUpdated = exchange_Atomic(&d->isRequestUpdated, iTrue); | ||
279 | if (!wasUpdated) { | ||
280 | postCommand_Widget(obj, "document.request.updated doc:%p request:%p", d, d->request); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static void requestTimedOut_DocumentWidget_(iAnyObject *obj) { | ||
285 | iDocumentWidget *d = obj; | ||
286 | postCommandf_App("document.request.timeout doc:%p request:%p", d, d->request); | ||
287 | } | ||
288 | |||
289 | static void requestFinished_DocumentWidget_(iAnyObject *obj) { | ||
290 | iDocumentWidget *d = obj; | ||
291 | postCommand_Widget(obj, "document.request.finished doc:%p request:%p", d, d->request); | ||
292 | } | ||
293 | |||
273 | static void resetSmoothScroll_DocumentWidget_(iDocumentWidget *d) { | 294 | static void resetSmoothScroll_DocumentWidget_(iDocumentWidget *d) { |
274 | d->smoothSpeed = 0; | 295 | d->smoothSpeed = 0; |
275 | d->smoothScroll = 0; | 296 | d->smoothScroll = 0; |
@@ -320,24 +341,6 @@ static iInt2 documentPos_DocumentWidget_(const iDocumentWidget *d, iInt2 pos) { | |||
320 | return addY_I2(sub_I2(pos, topLeft_Rect(documentBounds_DocumentWidget_(d))), d->scrollY); | 341 | return addY_I2(sub_I2(pos, topLeft_Rect(documentBounds_DocumentWidget_(d))), d->scrollY); |
321 | } | 342 | } |
322 | 343 | ||
323 | static void requestUpdated_DocumentWidget_(iAnyObject *obj) { | ||
324 | iDocumentWidget *d = obj; | ||
325 | const int wasUpdated = exchange_Atomic(&d->isRequestUpdated, iTrue); | ||
326 | if (!wasUpdated) { | ||
327 | postCommand_Widget(obj, "document.request.updated doc:%p request:%p", d, d->request); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | static void requestTimedOut_DocumentWidget_(iAnyObject *obj) { | ||
332 | iDocumentWidget *d = obj; | ||
333 | postCommandf_App("document.request.timeout doc:%p request:%p", d, d->request); | ||
334 | } | ||
335 | |||
336 | static void requestFinished_DocumentWidget_(iAnyObject *obj) { | ||
337 | iDocumentWidget *d = obj; | ||
338 | postCommand_Widget(obj, "document.request.finished doc:%p request:%p", d, d->request); | ||
339 | } | ||
340 | |||
341 | static iRangei visibleRange_DocumentWidget_(const iDocumentWidget *d) { | 344 | static iRangei visibleRange_DocumentWidget_(const iDocumentWidget *d) { |
342 | const int margin = !hasSiteBanner_GmDocument(d->doc) ? gap_UI * d->pageMargin : 0; | 345 | const int margin = !hasSiteBanner_GmDocument(d->doc) ? gap_UI * d->pageMargin : 0; |
343 | return (iRangei){ d->scrollY - margin, | 346 | return (iRangei){ d->scrollY - margin, |
@@ -484,27 +487,6 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | |||
484 | } | 487 | } |
485 | } | 488 | } |
486 | 489 | ||
487 | const iString *bookmarkTitle_DocumentWidget(const iDocumentWidget *d) { | ||
488 | iStringArray *title = iClob(new_StringArray()); | ||
489 | if (!isEmpty_String(title_GmDocument(d->doc))) { | ||
490 | pushBack_StringArray(title, title_GmDocument(d->doc)); | ||
491 | } | ||
492 | if (!isEmpty_String(d->titleUser)) { | ||
493 | pushBack_StringArray(title, d->titleUser); | ||
494 | } | ||
495 | if (isEmpty_StringArray(title)) { | ||
496 | iUrl parts; | ||
497 | init_Url(&parts, d->mod.url); | ||
498 | if (!isEmpty_Range(&parts.host)) { | ||
499 | pushBackRange_StringArray(title, parts.host); | ||
500 | } | ||
501 | } | ||
502 | if (isEmpty_StringArray(title)) { | ||
503 | pushBackCStr_StringArray(title, "Blank Page"); | ||
504 | } | ||
505 | return collect_String(joinCStr_StringArray(title, " \u2014 ")); | ||
506 | } | ||
507 | |||
508 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { | 490 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { |
509 | iLabelWidget *tabButton = tabPageButton_Widget(findWidget_App("doctabs"), d); | 491 | iLabelWidget *tabButton = tabPageButton_Widget(findWidget_App("doctabs"), d); |
510 | if (!tabButton) { | 492 | if (!tabButton) { |
@@ -576,10 +558,6 @@ static void invalidate_DocumentWidget_(iDocumentWidget *d) { | |||
576 | clear_PtrSet(d->invalidRuns); | 558 | clear_PtrSet(d->invalidRuns); |
577 | } | 559 | } |
578 | 560 | ||
579 | static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */ | ||
580 | static const int outlineMaxWidth_DocumentWidget_ = 65; /* times gap_UI */ | ||
581 | static const int outlinePadding_DocumentWidget_ = 3; /* times gap_UI */ | ||
582 | |||
583 | static int outlineWidth_DocumentWidget_(const iDocumentWidget *d) { | 561 | static int outlineWidth_DocumentWidget_(const iDocumentWidget *d) { |
584 | const iWidget *w = constAs_Widget(d); | 562 | const iWidget *w = constAs_Widget(d); |
585 | const iRect bounds = bounds_Widget(w); | 563 | const iRect bounds = bounds_Widget(w); |
@@ -865,18 +843,6 @@ static void updateTrust_DocumentWidget_(iDocumentWidget *d, const iGmResponse *r | |||
865 | } | 843 | } |
866 | } | 844 | } |
867 | 845 | ||
868 | iHistory *history_DocumentWidget(iDocumentWidget *d) { | ||
869 | return d->mod.history; | ||
870 | } | ||
871 | |||
872 | const iString *url_DocumentWidget(const iDocumentWidget *d) { | ||
873 | return d->mod.url; | ||
874 | } | ||
875 | |||
876 | const iGmDocument *document_DocumentWidget(const iDocumentWidget *d) { | ||
877 | return d->doc; | ||
878 | } | ||
879 | |||
880 | static void parseUser_DocumentWidget_(iDocumentWidget *d) { | 846 | static void parseUser_DocumentWidget_(iDocumentWidget *d) { |
881 | clear_String(d->titleUser); | 847 | clear_String(d->titleUser); |
882 | iRegExp *userPats[2] = { new_RegExp("~([^/?]+)", 0), | 848 | iRegExp *userPats[2] = { new_RegExp("~([^/?]+)", 0), |
@@ -918,57 +884,6 @@ static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { | |||
918 | return iFalse; | 884 | return iFalse; |
919 | } | 885 | } |
920 | 886 | ||
921 | void serializeState_DocumentWidget(const iDocumentWidget *d, iStream *outs) { | ||
922 | serialize_Model(&d->mod, outs); | ||
923 | } | ||
924 | |||
925 | void deserializeState_DocumentWidget(iDocumentWidget *d, iStream *ins) { | ||
926 | deserialize_Model(&d->mod, ins); | ||
927 | parseUser_DocumentWidget_(d); | ||
928 | updateFromHistory_DocumentWidget_(d); | ||
929 | } | ||
930 | |||
931 | void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { | ||
932 | if (cmpStringSc_String(d->mod.url, url, &iCaseInsensitive)) { | ||
933 | set_String(d->mod.url, url); | ||
934 | /* See if there a username in the URL. */ | ||
935 | parseUser_DocumentWidget_(d); | ||
936 | if (!isFromCache || !updateFromHistory_DocumentWidget_(d)) { | ||
937 | fetch_DocumentWidget_(d); | ||
938 | } | ||
939 | } | ||
940 | else { | ||
941 | postCommandf_App("document.changed url:%s", cstr_String(d->mod.url)); | ||
942 | } | ||
943 | } | ||
944 | |||
945 | iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) { | ||
946 | iDocumentWidget *d = new_DocumentWidget(); | ||
947 | delete_History(d->mod.history); | ||
948 | d->initNormScrollY = normScrollPos_DocumentWidget_(d); | ||
949 | d->mod.history = copy_History(orig->mod.history); | ||
950 | setUrlFromCache_DocumentWidget(d, orig->mod.url, iTrue); | ||
951 | return d; | ||
952 | } | ||
953 | |||
954 | void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) { | ||
955 | setUrlFromCache_DocumentWidget(d, url, iFalse); | ||
956 | } | ||
957 | |||
958 | void setInitialScroll_DocumentWidget(iDocumentWidget *d, float normScrollY) { | ||
959 | d->initNormScrollY = normScrollY; | ||
960 | } | ||
961 | |||
962 | void setRedirectCount_DocumentWidget(iDocumentWidget *d, int count) { | ||
963 | d->redirectCount = count; | ||
964 | } | ||
965 | |||
966 | iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) { | ||
967 | /*return d->state == fetching_RequestState || | ||
968 | d->state == receivedPartialResponse_RequestState;*/ | ||
969 | return d->request != NULL; | ||
970 | } | ||
971 | |||
972 | static void scroll_DocumentWidget_(iDocumentWidget *d, int offset) { | 887 | static void scroll_DocumentWidget_(iDocumentWidget *d, int offset) { |
973 | d->scrollY += offset; | 888 | d->scrollY += offset; |
974 | if (d->scrollY < 0) { | 889 | if (d->scrollY < 0) { |
@@ -1250,14 +1165,6 @@ static void allocVisBuffer_DocumentWidget_(const iDocumentWidget *d) { | |||
1250 | } | 1165 | } |
1251 | } | 1166 | } |
1252 | 1167 | ||
1253 | void updateSize_DocumentWidget(iDocumentWidget *d) { | ||
1254 | setWidth_GmDocument( | ||
1255 | d->doc, documentWidth_DocumentWidget_(d), forceBreakWidth_DocumentWidget_(d)); | ||
1256 | updateOutline_DocumentWidget_(d); | ||
1257 | updateVisible_DocumentWidget_(d); | ||
1258 | invalidate_DocumentWidget_(d); | ||
1259 | } | ||
1260 | |||
1261 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { | 1168 | static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { |
1262 | iWidget *w = as_Widget(d); | 1169 | iWidget *w = as_Widget(d); |
1263 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { | 1170 | if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { |
@@ -2618,6 +2525,100 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) { | |||
2618 | draw_Widget(w); | 2525 | draw_Widget(w); |
2619 | } | 2526 | } |
2620 | 2527 | ||
2528 | /*----------------------------------------------------------------------------------------------*/ | ||
2529 | |||
2530 | iHistory *history_DocumentWidget(iDocumentWidget *d) { | ||
2531 | return d->mod.history; | ||
2532 | } | ||
2533 | |||
2534 | const iString *url_DocumentWidget(const iDocumentWidget *d) { | ||
2535 | return d->mod.url; | ||
2536 | } | ||
2537 | |||
2538 | const iGmDocument *document_DocumentWidget(const iDocumentWidget *d) { | ||
2539 | return d->doc; | ||
2540 | } | ||
2541 | |||
2542 | const iString *bookmarkTitle_DocumentWidget(const iDocumentWidget *d) { | ||
2543 | iStringArray *title = iClob(new_StringArray()); | ||
2544 | if (!isEmpty_String(title_GmDocument(d->doc))) { | ||
2545 | pushBack_StringArray(title, title_GmDocument(d->doc)); | ||
2546 | } | ||
2547 | if (!isEmpty_String(d->titleUser)) { | ||
2548 | pushBack_StringArray(title, d->titleUser); | ||
2549 | } | ||
2550 | if (isEmpty_StringArray(title)) { | ||
2551 | iUrl parts; | ||
2552 | init_Url(&parts, d->mod.url); | ||
2553 | if (!isEmpty_Range(&parts.host)) { | ||
2554 | pushBackRange_StringArray(title, parts.host); | ||
2555 | } | ||
2556 | } | ||
2557 | if (isEmpty_StringArray(title)) { | ||
2558 | pushBackCStr_StringArray(title, "Blank Page"); | ||
2559 | } | ||
2560 | return collect_String(joinCStr_StringArray(title, " \u2014 ")); | ||
2561 | } | ||
2562 | |||
2563 | void serializeState_DocumentWidget(const iDocumentWidget *d, iStream *outs) { | ||
2564 | serialize_Model(&d->mod, outs); | ||
2565 | } | ||
2566 | |||
2567 | void deserializeState_DocumentWidget(iDocumentWidget *d, iStream *ins) { | ||
2568 | deserialize_Model(&d->mod, ins); | ||
2569 | parseUser_DocumentWidget_(d); | ||
2570 | updateFromHistory_DocumentWidget_(d); | ||
2571 | } | ||
2572 | |||
2573 | void setUrlFromCache_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isFromCache) { | ||
2574 | if (cmpStringSc_String(d->mod.url, url, &iCaseInsensitive)) { | ||
2575 | set_String(d->mod.url, url); | ||
2576 | /* See if there a username in the URL. */ | ||
2577 | parseUser_DocumentWidget_(d); | ||
2578 | if (!isFromCache || !updateFromHistory_DocumentWidget_(d)) { | ||
2579 | fetch_DocumentWidget_(d); | ||
2580 | } | ||
2581 | } | ||
2582 | else { | ||
2583 | postCommandf_App("document.changed url:%s", cstr_String(d->mod.url)); | ||
2584 | } | ||
2585 | } | ||
2586 | |||
2587 | iDocumentWidget *duplicate_DocumentWidget(const iDocumentWidget *orig) { | ||
2588 | iDocumentWidget *d = new_DocumentWidget(); | ||
2589 | delete_History(d->mod.history); | ||
2590 | d->initNormScrollY = normScrollPos_DocumentWidget_(d); | ||
2591 | d->mod.history = copy_History(orig->mod.history); | ||
2592 | setUrlFromCache_DocumentWidget(d, orig->mod.url, iTrue); | ||
2593 | return d; | ||
2594 | } | ||
2595 | |||
2596 | void setUrl_DocumentWidget(iDocumentWidget *d, const iString *url) { | ||
2597 | setUrlFromCache_DocumentWidget(d, url, iFalse); | ||
2598 | } | ||
2599 | |||
2600 | void setInitialScroll_DocumentWidget(iDocumentWidget *d, float normScrollY) { | ||
2601 | d->initNormScrollY = normScrollY; | ||
2602 | } | ||
2603 | |||
2604 | void setRedirectCount_DocumentWidget(iDocumentWidget *d, int count) { | ||
2605 | d->redirectCount = count; | ||
2606 | } | ||
2607 | |||
2608 | iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) { | ||
2609 | /*return d->state == fetching_RequestState || | ||
2610 | d->state == receivedPartialResponse_RequestState;*/ | ||
2611 | return d->request != NULL; | ||
2612 | } | ||
2613 | |||
2614 | void updateSize_DocumentWidget(iDocumentWidget *d) { | ||
2615 | setWidth_GmDocument( | ||
2616 | d->doc, documentWidth_DocumentWidget_(d), forceBreakWidth_DocumentWidget_(d)); | ||
2617 | updateOutline_DocumentWidget_(d); | ||
2618 | updateVisible_DocumentWidget_(d); | ||
2619 | invalidate_DocumentWidget_(d); | ||
2620 | } | ||
2621 | |||
2621 | iBeginDefineSubclass(DocumentWidget, Widget) | 2622 | iBeginDefineSubclass(DocumentWidget, Widget) |
2622 | .processEvent = (iAny *) processEvent_DocumentWidget_, | 2623 | .processEvent = (iAny *) processEvent_DocumentWidget_, |
2623 | .draw = (iAny *) draw_DocumentWidget_, | 2624 | .draw = (iAny *) draw_DocumentWidget_, |