File size: 3,998 Bytes
b0c3a57
 
 
 
 
 
 
1f7c87f
b0c3a57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f7c87f
b0c3a57
 
 
 
 
5979537
 
b0c3a57
 
 
 
 
 
 
 
 
 
 
 
5979537
 
b0c3a57
 
 
 
 
 
 
 
 
5979537
 
 
 
 
 
 
 
b0c3a57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f7c87f
b0c3a57
 
 
 
 
1f7c87f
b0c3a57
 
 
 
1f7c87f
b0c3a57
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""OphthalmoCapture — Image Gallery Component

Renders a thumbnail strip of all uploaded images with labeling-status
badges and click-to-select behaviour.
"""

import streamlit as st
from i18n import t
from services import session_manager as sm


def _label_badge(label):
    """Return a coloured status indicator for the label value."""
    if label is None:
        return "🔴"   # unlabeled
    return "🟢"       # labeled (any value)


def render_gallery():
    """Draw the horizontal thumbnail gallery with status badges.

    Returns True if the user clicked on a thumbnail (triggers rerun).
    """
    images = st.session_state.images
    order = st.session_state.image_order
    current_id = st.session_state.current_image_id

    if not order:
        return False

    # ── Progress bar ─────────────────────────────────────────────────────
    labeled, total = sm.get_labeling_progress()
    progress_text = f"{t('progress')}: **{labeled}** / **{total}** {t('labeled_suffix')}"
    st.markdown(progress_text)
    st.progress(labeled / total if total > 0 else 0)

    # ── Thumbnail strip ──────────────────────────────────────────────────
    # Show up to 8 thumbnails per row; wrap if there are more.
    COLS_PER_ROW = 6
    THUMB_HEIGHT = 120  # fixed thumbnail height in pixels
    num_images = len(order)

    # Paginate the gallery if many images
    if "gallery_page" not in st.session_state:
        st.session_state.gallery_page = 0

    total_pages = max(1, -(-num_images // COLS_PER_ROW))  # ceil division
    page = st.session_state.gallery_page
    start = page * COLS_PER_ROW
    end = min(start + COLS_PER_ROW, num_images)
    visible_ids = order[start:end]

    # Always use fixed number of columns so thumbnails keep consistent size
    cols = st.columns(COLS_PER_ROW)

    clicked = False
    for i, img_id in enumerate(visible_ids):
        img = images[img_id]
        badge = _label_badge(img["label"])
        is_selected = (img_id == current_id)

        with cols[i]:
            # Visual border to highlight the selected thumbnail
            border_color = "#4CAF50" if is_selected else "transparent"
            st.markdown(
                f"<div style='border:3px solid {border_color}; border-radius:8px; "
                f"padding:2px; text-align:center;'>",
                unsafe_allow_html=True,
            )
            st.image(img["bytes"], width=THUMB_HEIGHT)
            st.markdown("</div>", unsafe_allow_html=True)

            # Label + filename
            short_name = img["filename"]
            if len(short_name) > 18:
                short_name = short_name[:15] + "…"

            if st.button(
                f"{badge} {short_name}",
                key=f"thumb_{img_id}",
                use_container_width=True,
            ):
                sm.set_current_image(img_id)
                clicked = True

    # ── Gallery pagination ───────────────────────────────────────────────
    if total_pages > 1:
        gc1, gc2, gc3 = st.columns([1, 3, 1])
        with gc1:
            if page > 0:
                if st.button(t("gallery_prev"), key="gal_prev"):
                    st.session_state.gallery_page -= 1
                    clicked = True
        with gc2:
            st.markdown(
                f"<div style='text-align:center; padding-top:6px;'>"
                f"{t('page')} {page + 1} / {total_pages}</div>",
                unsafe_allow_html=True,
            )
        with gc3:
            if page < total_pages - 1:
                if st.button(t("gallery_next"), key="gal_next"):
                    st.session_state.gallery_page += 1
                    clicked = True

    return clicked