Skip to content

Commit 3935b00

Browse files
Piggy: use Intents to start new Activities
1 parent 8dddf28 commit 3935b00

File tree

2 files changed

+190
-26
lines changed

2 files changed

+190
-26
lines changed

internal_filesystem/apps/com.lightningpiggy.displaywallet/assets/displaywallet.py

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from mpos.apps import Activity
1+
from mpos.apps import Activity, Intent
22
import mpos.config
33
import mpos.ui
44

@@ -10,6 +10,7 @@ class MainActivity(Activity):
1010
def __init__(self):
1111
self.wallet = None
1212
self.receive_qr_data = None
13+
self.destination = None
1314
# widgets
1415
self.balance_label = None
1516
self.receive_qr = None
@@ -84,8 +85,9 @@ def onResume(self, main_screen):
8485
self.payments_label.set_text(f"Could not start {wallet_type} backend.")
8586

8687
def onStop(self, main_screen):
87-
if self.wallet:
88+
if self.wallet and self.destination != FullscreenQR:
8889
self.wallet.stop()
90+
self.destination = None
8991

9092
def redraw_balance_cb(self):
9193
# this gets called from another thread (the wallet) so make sure it happens in the LVGL thread using lv.async_call():
@@ -95,30 +97,20 @@ def redraw_payments_cb(self):
9597
# this gets called from another thread (the wallet) so make sure it happens in the LVGL thread using lv.async_call():
9698
lv.async_call(lambda l: self.payments_label.set_text(str(self.wallet.payment_list)), None)
9799

98-
99100
def settings_button_tap(self, event):
100-
settings_activity = SettingsActivity()
101-
settings_activity.onCreate()
101+
self.startActivity(Intent(activity_class=SettingsActivity))
102102

103103
def main_ui_set_defaults(self):
104104
self.balance_label.set_text(lv.SYMBOL.REFRESH)
105105
self.payments_label.set_text(lv.SYMBOL.REFRESH)
106-
self.receive_qr.update("EMPTY", len("EMPTY"))
106+
self.receive_qr.update("EMPTY PLACEHOLDER", len("EMPTY PLACEHOLDER"))
107107

108108
def qr_clicked_cb(self, event):
109+
print("QR clicked")
109110
if not self.receive_qr_data:
110111
return
111-
print("QR clicked")
112-
qr_screen = lv.obj()
113-
big_receive_qr = lv.qrcode(qr_screen)
114-
big_receive_qr.set_size(240) # TODO: make this dynamic
115-
big_receive_qr.set_dark_color(lv.color_black())
116-
big_receive_qr.set_light_color(lv.color_white())
117-
big_receive_qr.center()
118-
big_receive_qr.set_style_border_color(lv.color_white(), 0)
119-
big_receive_qr.set_style_border_width(3, 0);
120-
big_receive_qr.update(self.receive_qr_data, len(self.receive_qr_data))
121-
mpos.ui.load_screen(qr_screen)
112+
self.destination = FullscreenQR
113+
self.startActivity(Intent(activity_class=FullscreenQR).putExtra("receive_qr_data", self.receive_qr_data))
122114

123115
# Used to list and edit all settings:
124116
class SettingsActivity(Activity):
@@ -190,18 +182,19 @@ def onResume(self, screen):
190182
setting["cont"].remove_flag(lv.obj.FLAG.HIDDEN)
191183

192184
def startSettingActivity(self, setting):
193-
sa = SettingActivity(setting)
194-
sa.onCreate()
195-
185+
intent = Intent(activity_class=SettingActivity)
186+
intent.putExtra("setting", setting)
187+
self.startActivity(intent)
196188

197189
# Used to edit one setting:
198190
class SettingActivity(Activity):
199-
def __init__(self, setting):
191+
def __init__(self):
200192
super().__init__()
201193
self.prefs = mpos.config.SharedPreferences("com.lightningpiggy.displaywallet")
202-
self.setting = setting
194+
self.setting = None
203195

204196
def onCreate(self):
197+
setting = self.getIntent().extras.get("setting")
205198
settings_screen_detail = lv.obj()
206199
settings_screen_detail.set_style_pad_all(10, 0)
207200
settings_screen_detail.set_flex_flow(lv.FLEX_FLOW.COLUMN)
@@ -214,7 +207,7 @@ def onCreate(self):
214207
top_cont.set_style_flex_main_place(lv.FLEX_ALIGN.SPACE_BETWEEN, 0)
215208

216209
setting_label = lv.label(top_cont)
217-
setting_label.set_text(self.setting["title"])
210+
setting_label.set_text(setting["title"])
218211
setting_label.align(lv.ALIGN.TOP_LEFT,0,0)
219212
setting_label.set_style_text_font(lv.font_montserrat_22, 0)
220213

@@ -226,7 +219,7 @@ def onCreate(self):
226219
cambuttonlabel.center()
227220
cambutton.add_event_cb(self.cambutton_cb, lv.EVENT.CLICKED, None)
228221

229-
if self.setting["key"] == "wallet_type":
222+
if setting["key"] == "wallet_type":
230223
cambutton.add_flag(lv.obj.FLAG.HIDDEN)
231224
# Create container for radio buttons
232225
self.radio_container = lv.obj(settings_screen_detail)
@@ -249,7 +242,7 @@ def onCreate(self):
249242
self.textarea = lv.textarea(settings_screen_detail)
250243
self.textarea.set_width(lv.pct(100))
251244
self.textarea.set_height(lv.SIZE_CONTENT)
252-
self.textarea.set_text(self.prefs.get_string(self.setting["key"], ""))
245+
self.textarea.set_text(self.prefs.get_string(setting["key"], ""))
253246
self.textarea.add_event_cb(self.show_keyboard, lv.EVENT.CLICKED, None)
254247
self.textarea.add_event_cb(self.show_keyboard, lv.EVENT.FOCUSED, None)
255248
self.textarea.add_event_cb(self.hide_keyboard, lv.EVENT.DEFOCUSED, None)
@@ -275,7 +268,7 @@ def onCreate(self):
275268
save_label = lv.label(save_btn)
276269
save_label.set_text("Save")
277270
save_label.center()
278-
save_btn.add_event_cb(lambda e, s=self.setting: self.save_setting(s), lv.EVENT.CLICKED, None)
271+
save_btn.add_event_cb(lambda e, s=setting: self.save_setting(s), lv.EVENT.CLICKED, None)
279272
# Cancel button
280273
cancel_btn = lv.button(btn_cont)
281274
cancel_btn.set_size(lv.pct(45), lv.SIZE_CONTENT)
@@ -354,3 +347,18 @@ def save_setting(self, setting):
354347
setting["value_label"].set_text(new_value if new_value else "Not set")
355348
self.finish()
356349

350+
351+
class FullscreenQR(Activity):
352+
353+
def onCreate(self):
354+
receive_qr_data = self.getIntent().extras.get("receive_qr_data")
355+
qr_screen = lv.obj()
356+
big_receive_qr = lv.qrcode(qr_screen)
357+
big_receive_qr.set_size(240) # TODO: make this dynamic
358+
big_receive_qr.set_dark_color(lv.color_black())
359+
big_receive_qr.set_light_color(lv.color_white())
360+
big_receive_qr.center()
361+
big_receive_qr.set_style_border_color(lv.color_white(), 0)
362+
big_receive_qr.set_style_border_width(3, 0);
363+
big_receive_qr.update(receive_qr_data, len(receive_qr_data))
364+
self.setContentView(qr_screen)

internal_filesystem/lib/mpos/apps.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ def auto_connect():
193193

194194
class Activity:
195195

196+
def __init__(self):
197+
self.intent = None # Store the intent that launched this activity
198+
199+
def getIntent(self):
200+
return self.intent
201+
196202
def onCreate(self):
197203
pass
198204
def onStart(self, screen):
@@ -211,3 +217,153 @@ def setContentView(self, screen):
211217

212218
def finish(self):
213219
mpos.ui.back_screen()
220+
221+
def startActivity(self, intent):
222+
ActivityNavigator.startActivity(intent)
223+
224+
class Intent:
225+
def __init__(self, activity_class=None, action=None, data=None, extras=None):
226+
self.activity_class = activity_class # Explicit target (e.g., SettingsActivity)
227+
self.action = action # Action string (e.g., "view", "share")
228+
self.data = data # Single data item (e.g., URL)
229+
self.extras = extras or {} # Dictionary for additional data
230+
self.flags = {} # Simplified flags: {"clear_top": bool, "no_history": bool, "no_animation": bool}
231+
232+
def addFlag(self, flag, value=True):
233+
self.flags[flag] = value
234+
return self
235+
236+
def putExtra(self, key, value):
237+
self.extras[key] = value
238+
return self
239+
240+
241+
class ActivityNavigator:
242+
243+
def startActivity(intent):
244+
if not isinstance(intent, Intent):
245+
raise ValueError("Must provide an Intent")
246+
if intent.action: # Implicit intent: resolve handlers
247+
handlers = APP_REGISTRY.get(intent.action, [])
248+
if len(handlers) == 1:
249+
intent.activity_class = handlers[0]
250+
ActivityNavigator._launch_activity(intent)
251+
elif handlers:
252+
_show_chooser(intent, handlers)
253+
else:
254+
raise ValueError(f"No handlers for action: {intent.action}")
255+
else:
256+
# Explicit intent
257+
ActivityNavigator._launch_activity(intent)
258+
259+
def _launch_activity(intent):
260+
activity = intent.activity_class()
261+
activity.intent = intent
262+
activity.onCreate()
263+
264+
def _show_chooser(intent, handlers):
265+
chooser_intent = Intent(ChooserActivity, extras={"original_intent": intent, "handlers": [h.__name__ for h in handlers]})
266+
_launch_activity(chooser_intent)
267+
268+
269+
class ChooserActivity(Activity):
270+
def __init__(self):
271+
super().__init__()
272+
273+
def onCreate(self):
274+
screen = lv.obj()
275+
# Get handlers from intent extras
276+
original_intent = self.getIntent().extras.get("original_intent")
277+
handlers = self.getIntent().extras.get("handlers", [])
278+
label = lv.label(screen)
279+
label.set_text("Choose an app")
280+
label.set_pos(10, 10)
281+
282+
for i, handler_name in enumerate(handlers):
283+
btn = lv.btn(screen)
284+
btn.set_user_data(f"handler_{i}")
285+
btn_label = lv.label(btn)
286+
btn_label.set_text(handler_name)
287+
btn.set_pos(10, 50 * (i + 1) + 10)
288+
btn.add_event_cb(lambda e, h=handler_name, oi=original_intent: self._select_handler(h, oi), lv.EVENT.CLICKED)
289+
self.setContentView(screen)
290+
291+
def _select_handler(self, handler_name, original_intent):
292+
for handler in APP_REGISTRY.get(original_intent.action, []):
293+
if handler.__name__ == handler_name:
294+
original_intent.activity_class = handler
295+
navigator.startActivity(original_intent)
296+
break
297+
navigator.finish() # Close chooser
298+
299+
def onStop(self, screen):
300+
if self.getIntent() and self.getIntent().getStringExtra("destination") == "ChooserActivity":
301+
print("Stopped for Chooser")
302+
else:
303+
print("Stopped for other screen")
304+
305+
306+
class ViewActivity(Activity):
307+
def __init__(self):
308+
super().__init__()
309+
310+
def onCreate(self):
311+
screen = lv.obj()
312+
# Get content from intent (prefer extras.url, fallback to data)
313+
content = self.getIntent().extras.get("url", self.getIntent().data or "No content")
314+
label = lv.label(screen)
315+
label.set_user_data("content_label")
316+
label.set_text(f"Viewing: {content}")
317+
label.center()
318+
self.setContentView(screen)
319+
320+
def onStart(self, screen):
321+
content = self.getIntent().extras.get("url", self.getIntent().data or "No content")
322+
for i in range(screen.get_child_cnt()):
323+
if screen.get_child(i).get_user_data() == "content_label":
324+
screen.get_child(i).set_text(f"Viewing: {content}")
325+
326+
def onStop(self, screen):
327+
if self.getIntent() and self.getIntent().getStringExtra("destination") == "ViewActivity":
328+
print("Stopped for View")
329+
else:
330+
print("Stopped for other screen")
331+
332+
class ShareActivity(Activity):
333+
def __init__(self):
334+
super().__init__()
335+
336+
def onCreate(self):
337+
screen = lv.obj()
338+
# Get text from intent (prefer extras.text, fallback to data)
339+
text = self.getIntent().extras.get("text", self.getIntent().data or "No text")
340+
label = lv.label(screen)
341+
label.set_user_data("share_label")
342+
label.set_text(f"Share: {text}")
343+
label.set_pos(10, 10)
344+
345+
btn = lv.btn(screen)
346+
btn.set_user_data("share_btn")
347+
btn_label = lv.label(btn)
348+
btn_label.set_text("Share")
349+
btn.set_pos(10, 50)
350+
btn.add_event_cb(lambda e: self._share_content(text), lv.EVENT.CLICKED)
351+
self.setContentView(screen)
352+
353+
def _share_content(self, text):
354+
# Dispatch to another app (e.g., MessagingActivity) or simulate sharing
355+
print(f"Sharing: {text}") # Placeholder for actual sharing
356+
# Example: Launch another share handler
357+
navigator.startActivity(Intent(action="share", data=text))
358+
navigator.finish() # Close ShareActivity
359+
360+
def onStop(self, screen):
361+
if self.getIntent() and self.getIntent().getStringExtra("destination") == "ShareActivity":
362+
print("Stopped for Share")
363+
else:
364+
print("Stopped for other screen")
365+
366+
APP_REGISTRY = { # This should be handled by a new class PackageManager:
367+
"view": [ViewActivity], # Hypothetical activities
368+
"share": [ShareActivity]
369+
}

0 commit comments

Comments
 (0)