Skip to content

Commit 347c50a

Browse files
K2GO-426 feat(modules): show each module icon and align rows with a fixed leading slot
Module management rows had a checkbox in the leading slot only when a module was selectable; installed / unknown / failed / selector rows and the Dashboard card had nothing there, so the left edge was ragged and there was no per-module cue. The leading slot is now a fixed-width bullet, checkbox XOR icon: the selection checkbox when the module is selectable, otherwise the module icon (tinted from the theme primary). Every row's title starts at the same x. Applies to both the module rows (cardRow) and the Dashboard (REST API) system card (addSystemDashboardCard). - ModuleCards: map imageRes to each module's real icon (kolibri->courses, calibreweb->book, kiwix->wikipedia, code->code, forgejo->forgejo, maps->maps). - New ic_card_matomo (Material bar_chart, the glyph the box index already uses) and ic_card_dashnode (Material dashboard) for the Dashboard card.
1 parent 7e7b621 commit 347c50a

4 files changed

Lines changed: 64 additions & 16 deletions

File tree

‎controller/app/src/main/java/org/appdevforall/k2go/redesign/ModuleCards.java‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,25 @@ public boolean runsOnThisRuntime() {
6262
private static final Card[] CATALOG = {
6363
new Card("kolibri", R.string.k2go_mod_kolibri_title, R.string.k2go_mod_kolibri_title,
6464
R.string.k2go_mod_kolibri_sub, R.string.k2go_mod_kolibri_desc,
65-
R.drawable.k2go_module_placeholder, false),
65+
R.drawable.ic_card_courses, false),
6666
new Card("calibreweb", R.string.k2go_mod_calibreweb_title, R.string.k2go_mod_calibreweb_title,
6767
R.string.k2go_mod_calibreweb_sub, R.string.k2go_mod_calibreweb_desc,
68-
R.drawable.k2go_module_placeholder, false),
68+
R.drawable.ic_card_book, false),
6969
new Card("kiwix", R.string.k2go_mod_kiwix_title, R.string.k2go_mod_kiwix_detail_title,
7070
R.string.k2go_mod_kiwix_sub, R.string.k2go_mod_kiwix_desc,
71-
R.drawable.k2go_module_placeholder, false),
71+
R.drawable.ic_card_wikipedia, false),
7272
new Card("code", R.string.k2go_mod_code_title, R.string.k2go_mod_code_title,
7373
R.string.k2go_mod_code_sub, R.string.k2go_mod_code_desc,
74-
R.drawable.k2go_module_placeholder, false),
74+
R.drawable.ic_card_code, false),
7575
new Card("forgejo", R.string.k2go_mod_forgejo_title, R.string.k2go_mod_forgejo_title,
7676
R.string.k2go_mod_forgejo_sub, R.string.k2go_mod_forgejo_desc,
77-
R.drawable.k2go_module_placeholder, false),
77+
R.drawable.ic_card_forgejo, false),
7878
new Card("matomo", R.string.k2go_mod_matomo_title, R.string.k2go_mod_matomo_title,
7979
R.string.k2go_mod_matomo_sub, R.string.k2go_mod_matomo_desc,
80-
R.drawable.k2go_module_placeholder, false),
80+
R.drawable.ic_card_matomo, false),
8181
new Card("maps", R.string.k2go_mod_maps_title, R.string.k2go_mod_maps_title,
8282
R.string.k2go_mod_maps_sub, R.string.k2go_mod_maps_desc,
83-
R.drawable.k2go_module_placeholder, true), // ADFA-4958: proot module WITH a content selector
83+
R.drawable.ic_card_maps, true), // ADFA-4958: proot module WITH a content selector
8484
};
8585

8686
/** All presentable module cards (roster-backed), in display order. */

‎controller/app/src/main/java/org/appdevforall/k2go/redesign/ModuleHubFragment.java‎

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.appdevforall.k2go.redesign;
1717

1818
import android.content.Context;
19+
import android.content.res.ColorStateList;
1920
import android.os.Bundle;
2021
import android.os.Handler;
2122
import android.os.Looper;
@@ -24,6 +25,8 @@
2425
import android.view.View;
2526
import android.view.ViewGroup;
2627
import android.widget.Button;
28+
import android.widget.FrameLayout;
29+
import android.widget.ImageView;
2730
import android.widget.LinearLayout;
2831
import android.widget.TextView;
2932

@@ -101,6 +104,37 @@ public class ModuleHubFragment extends Fragment {
101104

102105
private int px(int dp) { return Math.round(dp * getResources().getDisplayMetrics().density); }
103106

107+
// K2GO-426: one fixed-width leading slot for every row (checkbox XOR icon) so a selectable row
108+
// and an installed row share the exact same indentation.
109+
private static final int LEAD_SLOT_DP = 40;
110+
111+
private LinearLayout.LayoutParams leadSlotLp() {
112+
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
113+
px(LEAD_SLOT_DP), LinearLayout.LayoutParams.WRAP_CONTENT);
114+
lp.rightMargin = px(4);
115+
return lp;
116+
}
117+
118+
// Wrap a leading element (checkbox or icon) so leadSlotLp() gives every row the same fixed-width
119+
// slot with the child centered. One place builds the slot, so both paths cannot drift.
120+
private FrameLayout leadSlot(View child, int childW, int childH) {
121+
FrameLayout slot = new FrameLayout(requireContext());
122+
FrameLayout.LayoutParams clp = new FrameLayout.LayoutParams(childW, childH);
123+
clp.gravity = Gravity.CENTER;
124+
slot.addView(child, clp);
125+
return slot;
126+
}
127+
128+
// The module icon as a small centered bullet, tinted from the theme primary (parity with the box
129+
// index, whose cards tint their glyph with the primary colour).
130+
private FrameLayout leadIconSlot(int iconRes) {
131+
ImageView iv = new ImageView(requireContext());
132+
iv.setImageResource(iconRes);
133+
iv.setImageTintList(ColorStateList.valueOf(
134+
ContextCompat.getColor(requireContext(), R.color.k2go_teal)));
135+
return leadSlot(iv, px(24), px(24));
136+
}
137+
104138
@Nullable
105139
@Override
106140
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle s) {
@@ -364,6 +398,11 @@ private void addHiddenSection() {
364398
rlp.bottomMargin = px(12);
365399
row.setLayoutParams(rlp);
366400

401+
// K2GO-426: hidden rows are listed too; the same leading icon slot aligns their titles with
402+
// the rest of the screen. The weight-1 col absorbs the slot, so the Restore button is not
403+
// crowded.
404+
row.addView(leadIconSlot(c.imageRes), leadSlotLp());
405+
367406
LinearLayout col = new LinearLayout(requireContext());
368407
col.setOrientation(LinearLayout.VERTICAL);
369408
TextView name = new TextView(requireContext());
@@ -422,11 +461,10 @@ private View cardRow(final ModuleCards.Card c, final boolean isInstalled,
422461
}
423462
});
424463

425-
// ADFA-5104: no tick on an installed module. There is nothing to schedule — installing it
426-
// again is not an action the app offers, and a checkbox that does nothing is worse than
427-
// no checkbox. The row still opens its detail, which is where "what is this" lives.
428-
// ADFA-5104: and no tick when the flags could not be read either. Ticking would bank an
429-
// order we have no grounds to take.
464+
// ADFA-5104: no tick on an installed module (nothing to schedule; a checkbox that does
465+
// nothing is worse than none), nor when the flags could not be read. K2GO-426: the leading
466+
// slot is a fixed-width bullet either way: the checkbox when the module is selectable, else
467+
// the module icon, so installed and not-installed rows share one indentation.
430468
if (!isInstalled && !unknown && !failed && !c.hasSelector) { // ADFA-4958: tick to schedule several at once (maps uses its own selector). ADFA-4898: a failed module shows Retry, not the checkbox.
431469
com.google.android.material.checkbox.MaterialCheckBox cb =
432470
new com.google.android.material.checkbox.MaterialCheckBox(requireContext());
@@ -436,10 +474,10 @@ private View cardRow(final ModuleCards.Card c, final boolean isInstalled,
436474
else ModuleWishlist.remove(requireContext(), c.key());
437475
refreshProceed();
438476
});
439-
LinearLayout.LayoutParams cblp = new LinearLayout.LayoutParams(
440-
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
441-
cblp.rightMargin = px(4);
442-
row.addView(cb, cblp);
477+
row.addView(leadSlot(cb, FrameLayout.LayoutParams.WRAP_CONTENT,
478+
FrameLayout.LayoutParams.WRAP_CONTENT), leadSlotLp());
479+
} else {
480+
row.addView(leadIconSlot(c.imageRes), leadSlotLp());
443481
}
444482

445483
LinearLayout col = new LinearLayout(requireContext());
@@ -511,6 +549,10 @@ private void addSystemDashboardCard() {
511549
lp.bottomMargin = px(12);
512550
row.setLayoutParams(lp);
513551

552+
// K2GO-426: dash-node is the one core entry in this list; give it the same leading icon slot
553+
// as the module rows so its title aligns with theirs.
554+
row.addView(leadIconSlot(R.drawable.ic_card_dashnode), leadSlotLp());
555+
514556
LinearLayout col = new LinearLayout(requireContext());
515557
col.setOrientation(LinearLayout.VERTICAL);
516558
TextView title = new TextView(requireContext());
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="40dp" android:height="40dp" android:viewportWidth="24" android:viewportHeight="24">
2+
<path android:fillColor="#000000" android:pathData="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z" />
3+
</vector>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="40dp" android:height="40dp" android:viewportWidth="24" android:viewportHeight="24">
2+
<path android:fillColor="#000000" android:pathData="M5 9.2h3V19H5zM10.5 5h3v14h-3zM16 13h3v6h-3z" />
3+
</vector>

0 commit comments

Comments
 (0)