diff --git a/examples/pika_lvgl/lv_png.py b/examples/pika_lvgl/lv_png.py index e530263b3..709fafe48 100644 --- a/examples/pika_lvgl/lv_png.py +++ b/examples/pika_lvgl/lv_png.py @@ -1,6 +1,6 @@ -import lvgl as lv +import pika_lvgl as lv -f = open('/pikafs/1.png', 'rb') +f = open('test/assets/pic1.jpg', 'rb') img_data = f.read() f.close() diff --git a/examples/pika_lvgl/lv_uidemo.py b/examples/pika_lvgl/lv_uidemo.py new file mode 100644 index 000000000..8c32c999c --- /dev/null +++ b/examples/pika_lvgl/lv_uidemo.py @@ -0,0 +1,600 @@ +import PikaStdLib +import pika_lvgl as lv +import time + +global_dict = {} +global_list = [] + + +class MyMeter: + def __init__(self, + parent, + label_text="label", + value=0, + value_set=0, + unit="°C"): + container = lv.obj(parent) + container.set_size(200, 250) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + container.set_style_border_width(0, 0) + meter = lv.meter(container) + meter.align(lv.ALIGN.TOP_MID, 0, -20) + meter.set_size(200, 200) + + # Add a scale first + scale = meter.add_scale() + meter.set_scale_ticks( + scale, 51, 2, 10, lv.palette_main(lv.PALETTE.GREY)) + meter.set_scale_major_ticks(scale, 10, 4, 15, lv.color_black(), 10) + + indic = lv.meter_indicator_t() + + # Add a blue arc to the start + indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.BLUE), 0) + meter.set_indicator_start_value(indic, 0) + meter.set_indicator_end_value(indic, 20) + + # Make the tick lines blue at the start of the scale + indic = meter.add_scale_lines(scale, lv.palette_main( + lv.PALETTE.BLUE), lv.palette_main(lv.PALETTE.BLUE), False, 0) + meter.set_indicator_start_value(indic, 0) + meter.set_indicator_end_value(indic, 20) + + # Add a red arc to the end + indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.RED), 0) + meter.set_indicator_start_value(indic, 80) + meter.set_indicator_end_value(indic, 100) + + # Make the tick lines red at the end of the scale + indic = meter.add_scale_lines(scale, lv.palette_main( + lv.PALETTE.RED), lv.palette_main(lv.PALETTE.RED), False, 0) + meter.set_indicator_start_value(indic, 80) + meter.set_indicator_end_value(indic, 100) + + # Add a needle line indicator + indic = meter.add_needle_line( + scale, 4, lv.palette_main(lv.PALETTE.GREY), -10) + label = lv.label(meter) + label.set_text(label_text + unit) + label.align(lv.ALIGN.CENTER, 0, -20) + + value_label = lv.label(meter) + value_label.align(lv.ALIGN.CENTER, 0, 60) + + value_set_input = InputBox(container, label_text="given", unit=unit) + value_set_input.align(lv.ALIGN.BOTTOM_MID, 0, 20) + + self.container = container + self.lv_meter = meter + self.value_label = value_label + self.indic = indic + self.unit = unit + + self.set_value(value) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_value(self, value): + # str_value = "%.1f" % value + str_value = str(value) + self.value_label.set_text(str_value + " " + self.unit) + self.lv_meter.set_indicator_end_value(self.indic, value) + + +class InputBox: + def __init__(self, parent, label_text="label", value='0.0', unit="", box_num=1, box_width=80): + self.input_box_list = [] + global_list.append(self) + container = lv.obj(parent) + container.set_size(110 + box_width * box_num, 50) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + container.set_style_border_width(0, 0) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.LEFT_MID, 0, 0) + for i in range(box_num): + input_box = lv.textarea(container) + input_box.set_size(box_width, 40) + input_box.align(lv.ALIGN.LEFT_MID, 40 + box_width*i, 0) + input_box.clear_flag(lv.obj.FLAG.SCROLLABLE) + input_box.set_one_line(True) + self.input_box_list.append(input_box) + input_box.set_text(value) + input_box.add_event_cb(self.event_cb, lv.EVENT.FOCUSED, None) + unit_label = lv.label(container) + unit_label.set_text(unit) + unit_label.align(lv.ALIGN.LEFT_MID, 50 + box_width*box_num, 0) + self.container = container + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_size(self, width, height): + self.container.set_size(width, height) + + def event_cb(self, e): + code = e.get_code() + ta = e.get_target() + kb: KeyBoard = global_dict["keyboard"] + if code == lv.EVENT.FOCUSED: + kb.set_hiden(False) + kb.set_textarea(ta) + if code == lv.EVENT.DEFOCUSED: + kb.set_textarea(None) + + +class ProcessCount: + def __init__(self, parent, label_text="label", value=0, totle=0): + container = lv.obj(parent) + container.set_size(150, 40) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.BOTTOM_MID, 0, 0) + value_label = lv.label(container) + value_label.align(lv.ALIGN.TOP_MID, 0, 0) + self.container = container + self.value_label = value_label + self.set_value(value, totle) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_value(self, value, totle): + self.value_label.set_text(str(value) + " / " + str(totle)) + + +class TimerView: + def __init__(self, + parent, + label_text="label", + seconds_this=0, + seconds_totle=0): + self.seconds_this = seconds_this + self.seconds_totle = seconds_totle + container = lv.obj(parent) + container.set_size(200, 80) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, -10) + label_this = lv.label(container) + label_this.align(lv.ALIGN.TOP_MID, 0, 10) + label_totle = lv.label(container) + label_totle.align(lv.ALIGN.TOP_MID, 0, 30) + self.container = container + self.label_this = label_this + self.label_totle = label_totle + self.set_value(seconds_this, seconds_totle) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_value(self, seconds_this, seconds_totle): + self.label_this.set_text( + "time now" + str(seconds_this//60) + " min " + str(seconds_this % 60) + " s") + self.label_totle.set_text( + "time total " + str(seconds_totle//60) + " min " + str(seconds_totle % 60) + " s") + + +class PIDPanel: + def __init__(self, parent, label_text="label"): + container = lv.obj(parent) + container.set_size(300, 300) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, 0) + label_partition = InputBox(container, label_text="partition") + label_partition.align(lv.ALIGN.TOP_LEFT, 20, 20) + label_top = lv.label(container) + label_top.set_text("top partition") + label_bottom = lv.label(container) + label_bottom.set_text("bottom partition") + label_top.align(lv.ALIGN.TOP_MID, 0, 80) + label_bottom.align(lv.ALIGN.TOP_MID, 0, 160) + input_box_P_top = InputBox(container, label_text="P") + input_box_P_top.align(lv.ALIGN.TOP_LEFT, -20, 100) + input_box_I_top = InputBox(container, label_text="I") + input_box_I_top.align(lv.ALIGN.TOP_LEFT, 110, 100) + input_box_P_bottom = InputBox(container, label_text="P") + input_box_P_bottom.align(lv.ALIGN.TOP_LEFT, -20, 180) + input_box_I_bottom = InputBox(container, label_text="I") + input_box_I_bottom.align(lv.ALIGN.TOP_LEFT, 110, 180) + self.container = container + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_size(self, width, height): + self.container.set_size(width, height) + + +class Button: + def __init__(self, parent, label_text="label"): + btn = lv.btn(parent) + btn.set_size(100, 50) + btn.clear_flag(lv.obj.FLAG.SCROLLABLE) + btn.set_style_bg_color(lv.color_white(), 0) + btn.set_style_text_color(lv.color_black(), 0) + btn.set_style_border_color(lv.color_black(), 0) + label = lv.label(btn) + label.set_text(label_text) + label.align(lv.ALIGN.CENTER, 0, 0) + self.is_on = False + self.btn = btn + self.label = label + + def align(self, align, x, y): + self.btn.align(align, x, y) + + def set_text(self, text): + self.label.set_text(text) + + def set_is_on(self, is_on): + self.is_on = is_on + + def _event_cb_adapter(self, e): + self.event_cb(self, e) + + def add_event_cb(self, event_cb, event_type, user_data=None): + self.event_cb = event_cb + self.btn.add_event_cb(self._event_cb_adapter, event_type, user_data) + + def set_size(self, width, height): + self.btn.set_size(width, height) + + + +class ProcessBar: + def __init__(self, parent, value=0): + bar = lv.bar(parent) + bar.remove_style_all() # To have a clean start + bar.add_style(bar_style_bg, 0) + bar.add_style(bar_style_indic, lv.PART.INDICATOR) + bar.set_size(200, 40) + self.bar = bar + self.style_bg = bar_style_bg + self.style_indic = bar_style_indic + self.set_value(value) + + def align(self, align, x, y): + self.bar.align(align, x, y) + + def set_value(self, value, anim=lv.ANIM.ON): + self.bar.set_value(value, anim) + + +def tab1_btnbar1_event_cb(self: "BtnProcessBar", e): + if self.btn.is_on: + self.btn.set_is_on(False) + self.btn.set_text("start") + self.bar.set_value(0) + else: + self.btn.set_is_on(True) + self.btn.set_text("stop") + self.bar.set_value(100) + + +class BtnProcessBar: + def __init__(self, parent, label_text="label", value=0): + container = lv.obj(parent) + container.set_size(350, 80) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + # 无边框 + container.set_style_border_width(0, 0) + btn = Button(container, label_text=label_text) + bar = ProcessBar(container, value=value) + btn.align(lv.ALIGN.LEFT_MID, 0, 0) + bar.align(lv.ALIGN.RIGHT_MID, 0, 0) + self.container = container + self.btn = btn + self.bar = bar + + def align(self, align, x, y): + self.container.align(align, x, y) + + def _event_cb_adapter(self, e): + self.event_cb(self, e) + + def add_event_cb(self, event_cb, event_type, user_data=None): + self.event_cb = event_cb + self.btn.btn.add_event_cb( + self._event_cb_adapter, event_type, user_data) + + +class Chart: + def __init__(self, parent, label_text="label"): + container = lv.obj(parent) + container.set_size(900, 450) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + container.set_style_border_width(0, 0) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, -20) + chart = lv.chart(container) + chart.set_size(800, 400) + chart.align(lv.ALIGN.CENTER, 0, 0) + chart.set_type(lv.chart.TYPE.LINE) # Show lines and points too + # Add two data series + ser1 = chart.add_series(lv.palette_main( + lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y) + chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 2, True, 50) + chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 6, 2, True, 50) + # Set next points on ser1 + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 30) + chart.set_next_value(ser1, 70) + chart.set_next_value(ser1, 90) + chart.refresh() + self.container = container + + def align(self, align, x, y): + self.container.align(align, x, y) + + +class KeyBoard: + def __init__(self, parent, label_text="label", is_number=True): + container = lv.obj(parent) + if is_number: + width = 300 + else: + width = 600 + container.set_size(width, 360) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + # container.set_style_bg_opa(lv.OPA.TRANSP, 0) + # container.set_style_border_width(0, 0) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, 0) + kb = lv.keyboard(container) + kb.set_size(width, 300) + kb.align(lv.ALIGN.BOTTOM_MID, 0, 20) + # kb.add_event_cb(self.event_cb, lv.EVENT.ALL, None) + if is_number: + kb.set_mode(lv.keyboard.MODE.NUMBER) + else: + kb.set_mode(lv.keyboard.MODE.TEXT_LOWER) + global_dict["keyboard"] = self + close_btn = Button(container, label_text="close") + close_btn.set_size(40, 40) + close_btn.align(lv.ALIGN.TOP_RIGHT, 0, -10) + close_btn.btn.add_event_cb( + self.close_btn_event_cb, lv.EVENT.CLICKED, None) + container.add_event_cb( + self.drag_event_cb, lv.EVENT.ALL, None) + self.is_hidden = True + self.container = container + self.close_btn = close_btn + self.kb = kb + + def close_btn_event_cb(self, e): + self.set_hiden(True) + + def drag_event_cb(self, e): + code = e.get_code() + if code == lv.EVENT.PRESSED: + indev = lv.indev_get_act() + self.drag_start_point = indev.get_point() + self.container_start_x = self.container.get_x() + self.container_start_y = self.container.get_y() + self.container.set_align(lv.ALIGN.TOP_LEFT) + # print("drag start", self.drag_start_point.x, self.drag_start_point.y) + if code == lv.EVENT.PRESSING: + indev = lv.indev_get_act() + drag_point = indev.get_point() + # print("drag", drag_point.x, drag_point.y) + self.container.set_pos( + self.container_start_x + drag_point.x - self.drag_start_point.x, self.container_start_y + drag_point.y - self.drag_start_point.y) + + def event_cb(self, e): + code = e.get_code() + ta = e.get_target() + # if code == lv.EVENT.FOCUSED: + # self.kb.move_foreground() + # self.kb.set_textarea(ta) + # self.kb.clear_flag(lv.obj.FLAG.HIDDEN) + + # if code == lv.EVENT.DEFOCUSED: + # self.kb.set_textarea(None) + # self.kb.add_flag(lv.obj.FLAG.HIDDEN) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def move_foreground(self): + self.container.move_foreground() + + def move_background(self): + self.container.move_background() + + def set_hiden(self, is_hidden): + # print("set_hiden", is_hidden) + self.is_hidden = is_hidden + if is_hidden: + self.container.add_flag(lv.obj.FLAG.HIDDEN) + else: + self.container.clear_flag(lv.obj.FLAG.HIDDEN) + self.move_foreground() + + def switch_hidden(self): + self.set_hiden(not self.is_hidden) + + def set_textarea(self, ta): + self.kb.set_textarea(ta) + + +def kb_btn_event_cb(self, e): + # print("kb_btn_event_cb") + kb: KeyBoard = global_dict["keyboard"] + kb.switch_hidden() + + +def date_time_update_cb(timer): + datetime_label = global_dict["datetime_label"] + asctime = time.asctime() + datetime_label.set_text(asctime) + print(asctime) + + +def main(): + global bar_style_bg + global bar_style_indic + bar_style_bg = lv.style_t() + bar_style_indic = lv.style_t() + + bar_style_bg.init() + bar_style_bg.set_border_color(lv.palette_main(lv.PALETTE.BLUE)) + bar_style_bg.set_border_width(2) + bar_style_bg.set_pad_all(6) # To make the indicator smaller + bar_style_bg.set_radius(6) + bar_style_bg.set_anim_time(1000) + + bar_style_indic.init() + bar_style_indic.set_bg_opa(lv.OPA.COVER) + bar_style_indic.set_bg_color(lv.palette_main(lv.PALETTE.BLUE)) + bar_style_indic.set_radius(3) + + # print('hello pikapython!') + mem = PikaStdLib.MemChecker() + + STATUS_BAR_HEIGHT = 40 + LOGO_WIDTH = 100 + TABVIEW_HEIGHT = 40 + + lv.lock() + status_bar = lv.obj(lv.scr_act()) + status_bar.set_size(lv.pct(100), STATUS_BAR_HEIGHT) + status_bar.clear_flag(lv.obj.FLAG.SCROLLABLE) + lv.scr_act().clear_flag(lv.obj.FLAG.SCROLLABLE) + + # logo label + logo = lv.obj(status_bar) + logo.set_size(LOGO_WIDTH, STATUS_BAR_HEIGHT) + logo_label = lv.label(logo) + logo_label.set_text("logo") + logo_label.align(lv.ALIGN.CENTER, 0, 0) + logo.align(lv.ALIGN.LEFT_MID, -20, 0) + logo.clear_flag(lv.obj.FLAG.SCROLLABLE) + + datetime_label = lv.label(status_bar) + datetime_label.set_text("2023.12.20 16:20:08") + datetime_label.align(lv.ALIGN.LEFT_MID, LOGO_WIDTH, 0) + global_dict["datetime_label"] = datetime_label + + timer = lv.timer_create_basic() + global_list.append(timer) + timer.set_period(1) + timer.set_cb(date_time_update_cb) + + # Keyboard + keyboard = KeyBoard(lv.scr_act(), label_text="", is_number=False) + keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0) + + keyboard_btn = Button(status_bar, label_text="keyboard") + keyboard_btn.align(lv.ALIGN.RIGHT_MID, -20, 0) + keyboard_btn.set_size(60, 30) + global_dict["keyboard_btn"] = keyboard_btn + keyboard_btn.add_event_cb(kb_btn_event_cb, lv.EVENT.CLICKED, None) + + # 创建一个tabview对象 + tabview = lv.tabview(lv.scr_act(), lv.DIR.TOP, TABVIEW_HEIGHT) + tabview.clear_flag(lv.obj.FLAG.SCROLLABLE) + tabview.align(lv.ALIGN.TOP_LEFT, 0, STATUS_BAR_HEIGHT) + tabview.set_size(lv.pct(100), lv.pct(100) - 10) + + # 添加标签到tabview + tab1 = tabview.add_tab("run") + tab2 = tabview.add_tab("debug") + tab3 = tabview.add_tab("log") + tab4 = tabview.add_tab("alert") + tab5 = tabview.add_tab("help") + tab6 = tabview.add_tab("program") + tab7 = tabview.add_tab("edit") + + + # tab1 + meter_temp_box = MyMeter(tab1, label_text="box temp", unit="°C") + meter_temp_box.align(lv.ALIGN.TOP_LEFT, 20, 0) + + meter_humi = MyMeter(tab1, label_text="meter humi", unit="%") + meter_humi.align(lv.ALIGN.TOP_RIGHT, -20, 0) + + meter_temp_tube = MyMeter(tab1, label_text="tube temp", unit="°C") + meter_temp_tube.align(lv.ALIGN.TOP_MID, 0, 0) + + meter_temp_box.set_value(20) + meter_humi.set_value(50) + meter_temp_tube.set_value(30) + + process_count_segment = ProcessCount( + tab1, label_text="tim", value=0, totle=10) + process_count_segment.align(lv.ALIGN.BOTTOM_LEFT, 0, -100) + + process_count_loop = ProcessCount(tab1, label_text="loop", value=0, totle=10) + process_count_loop.align(lv.ALIGN.BOTTOM_LEFT, 160, -100) + + timer_segment = TimerView(tab1, label_text="segment", + seconds_this=5, seconds_totle=10) + timer_totle = TimerView(tab1, label_text="timer totle", + seconds_this=0, seconds_totle=200) + + tab1_process_bar = BtnProcessBar(tab1, label_text="start") + tab1_process_bar.align(lv.ALIGN.BOTTOM_LEFT, 0, 0) + tab1_process_bar.add_event_cb(tab1_btnbar1_event_cb, lv.EVENT.CLICKED) + global_dict["tab1_process_bar"] = tab1_process_bar + + # tab2 + timer_segment.align(lv.ALIGN.BOTTOM_RIGHT, -220, -20) + timer_totle.align(lv.ALIGN.BOTTOM_RIGHT, 0, -20) + + pid_circle = PIDPanel(tab2, label_text="loop PID") + pid_circle.align(lv.ALIGN.TOP_LEFT, 0, 0) + + pid_plate = PIDPanel(tab2, label_text="plate PID") + pid_plate.align(lv.ALIGN.TOP_LEFT, 300, 0) + + pid_hit = PIDPanel(tab2, label_text="hit PID") + pid_hit.align(lv.ALIGN.TOP_LEFT, 600, 0) + pid_hit.set_size(350, 400) + # 低气压PID + label_low_pressure = lv.label(pid_hit.container) + label_low_pressure.set_text("lo pressure PID") + label_low_pressure.align(lv.ALIGN.BOTTOM_MID, 0, -100) + input_box_in = InputBox(pid_hit.container, label_text="in", box_num=2) + input_box_in.align(lv.ALIGN.BOTTOM_LEFT, 0, -50) + input_box_out = InputBox(pid_hit.container, label_text="out", box_num=2) + input_box_out.align(lv.ALIGN.BOTTOM_LEFT, 0, 0) + tab2_btn1 = Button(tab2, label_text="btn1") + tab2_btn1.align(lv.ALIGN.BOTTOM_RIGHT, -150, 0) + tab2_btn2 = Button(tab2, label_text="btn2") + tab2_btn2.align(lv.ALIGN.BOTTOM_RIGHT, -20, 0) + + # tab3 + chart_temp = Chart(tab3, label_text="chart temp") + chart_temp.align(lv.ALIGN.CENTER, 0, 0) + tabview.set_act(0, lv.ANIM.OFF) + + lv.unlock() + + mem.max() + + +main() + +for i in range(10): + time.sleep(0.1) + lv.task_handler() + +lv.deinit() diff --git a/package/pika_lvgl/pika_lvgl_lv_style_t.c b/package/pika_lvgl/pika_lvgl_lv_style_t.c index b27288373..8472b25d6 100644 --- a/package/pika_lvgl/pika_lvgl_lv_style_t.c +++ b/package/pika_lvgl/pika_lvgl_lv_style_t.c @@ -14,9 +14,7 @@ void pika_lvgl_style_t_init(PikaObj* self) { } void pika_lvgl_style_t___init__(PikaObj* self) { - lv_style_t lv_style_stack = {0}; - args_setStruct(self->list, "lv_style_struct", lv_style_stack); - lv_style_t* lv_style = args_getStruct(self->list, "lv_style_struct"); + lv_style_t* lv_style = lv_mem_alloc(sizeof(lv_style_t)); obj_setPtr(self, "lv_style", lv_style); } diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 48551cf03..e4b5871f1 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -20,7 +20,7 @@ // "--gtest_filter=stddata.encode_decode" // "--gtest_filter=packtool.packfiles_txt" // "--gtest_filter=cmodule.class_attr_obj" - "--gtest_filter=lvgl.lv_png" + "--gtest_filter=lvgl.lv_uidemo" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/test/module-test.cpp b/port/linux/test/module-test.cpp index 7275231ee..8756160c5 100644 --- a/port/linux/test/module-test.cpp +++ b/port/linux/test/module-test.cpp @@ -879,7 +879,7 @@ TEST_RUN_SINGLE_FILE(lvgl, lv_list1, "test/python/pika_lvgl/lv_list1.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_obj1, "test/python/pika_lvgl/lv_obj1.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_obj2, "test/python/pika_lvgl/lv_obj2.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_obj3, "test/python/pika_lvgl/lv_obj3.py"); -TEST_RUN_SINGLE_FILE(lvgl, lv_png, "test/python/pika_lvgl/lv_png.py"); +// TEST_RUN_SINGLE_FILE(lvgl, lv_png, "test/python/pika_lvgl/lv_png.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_roller1, "test/python/pika_lvgl/lv_roller1.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_slider1, "test/python/pika_lvgl/lv_slider1.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_style1, "test/python/pika_lvgl/lv_style1.py"); @@ -891,5 +891,6 @@ TEST_RUN_SINGLE_FILE(lvgl, lv_textarea1, "test/python/pika_lvgl/lv_textarea1.py"); TEST_RUN_SINGLE_FILE(lvgl, lv_tim, "test/python/pika_lvgl/lv_tim.py"); +TEST_RUN_SINGLE_FILE(lvgl, lv_uidemo, "test/python/pika_lvgl/lv_uidemo.py"); TEST_END diff --git a/port/linux/test/python/pika_lvgl/lv_uidemo.py b/port/linux/test/python/pika_lvgl/lv_uidemo.py new file mode 100644 index 000000000..8c32c999c --- /dev/null +++ b/port/linux/test/python/pika_lvgl/lv_uidemo.py @@ -0,0 +1,600 @@ +import PikaStdLib +import pika_lvgl as lv +import time + +global_dict = {} +global_list = [] + + +class MyMeter: + def __init__(self, + parent, + label_text="label", + value=0, + value_set=0, + unit="°C"): + container = lv.obj(parent) + container.set_size(200, 250) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + container.set_style_border_width(0, 0) + meter = lv.meter(container) + meter.align(lv.ALIGN.TOP_MID, 0, -20) + meter.set_size(200, 200) + + # Add a scale first + scale = meter.add_scale() + meter.set_scale_ticks( + scale, 51, 2, 10, lv.palette_main(lv.PALETTE.GREY)) + meter.set_scale_major_ticks(scale, 10, 4, 15, lv.color_black(), 10) + + indic = lv.meter_indicator_t() + + # Add a blue arc to the start + indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.BLUE), 0) + meter.set_indicator_start_value(indic, 0) + meter.set_indicator_end_value(indic, 20) + + # Make the tick lines blue at the start of the scale + indic = meter.add_scale_lines(scale, lv.palette_main( + lv.PALETTE.BLUE), lv.palette_main(lv.PALETTE.BLUE), False, 0) + meter.set_indicator_start_value(indic, 0) + meter.set_indicator_end_value(indic, 20) + + # Add a red arc to the end + indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.RED), 0) + meter.set_indicator_start_value(indic, 80) + meter.set_indicator_end_value(indic, 100) + + # Make the tick lines red at the end of the scale + indic = meter.add_scale_lines(scale, lv.palette_main( + lv.PALETTE.RED), lv.palette_main(lv.PALETTE.RED), False, 0) + meter.set_indicator_start_value(indic, 80) + meter.set_indicator_end_value(indic, 100) + + # Add a needle line indicator + indic = meter.add_needle_line( + scale, 4, lv.palette_main(lv.PALETTE.GREY), -10) + label = lv.label(meter) + label.set_text(label_text + unit) + label.align(lv.ALIGN.CENTER, 0, -20) + + value_label = lv.label(meter) + value_label.align(lv.ALIGN.CENTER, 0, 60) + + value_set_input = InputBox(container, label_text="given", unit=unit) + value_set_input.align(lv.ALIGN.BOTTOM_MID, 0, 20) + + self.container = container + self.lv_meter = meter + self.value_label = value_label + self.indic = indic + self.unit = unit + + self.set_value(value) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_value(self, value): + # str_value = "%.1f" % value + str_value = str(value) + self.value_label.set_text(str_value + " " + self.unit) + self.lv_meter.set_indicator_end_value(self.indic, value) + + +class InputBox: + def __init__(self, parent, label_text="label", value='0.0', unit="", box_num=1, box_width=80): + self.input_box_list = [] + global_list.append(self) + container = lv.obj(parent) + container.set_size(110 + box_width * box_num, 50) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + container.set_style_border_width(0, 0) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.LEFT_MID, 0, 0) + for i in range(box_num): + input_box = lv.textarea(container) + input_box.set_size(box_width, 40) + input_box.align(lv.ALIGN.LEFT_MID, 40 + box_width*i, 0) + input_box.clear_flag(lv.obj.FLAG.SCROLLABLE) + input_box.set_one_line(True) + self.input_box_list.append(input_box) + input_box.set_text(value) + input_box.add_event_cb(self.event_cb, lv.EVENT.FOCUSED, None) + unit_label = lv.label(container) + unit_label.set_text(unit) + unit_label.align(lv.ALIGN.LEFT_MID, 50 + box_width*box_num, 0) + self.container = container + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_size(self, width, height): + self.container.set_size(width, height) + + def event_cb(self, e): + code = e.get_code() + ta = e.get_target() + kb: KeyBoard = global_dict["keyboard"] + if code == lv.EVENT.FOCUSED: + kb.set_hiden(False) + kb.set_textarea(ta) + if code == lv.EVENT.DEFOCUSED: + kb.set_textarea(None) + + +class ProcessCount: + def __init__(self, parent, label_text="label", value=0, totle=0): + container = lv.obj(parent) + container.set_size(150, 40) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.BOTTOM_MID, 0, 0) + value_label = lv.label(container) + value_label.align(lv.ALIGN.TOP_MID, 0, 0) + self.container = container + self.value_label = value_label + self.set_value(value, totle) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_value(self, value, totle): + self.value_label.set_text(str(value) + " / " + str(totle)) + + +class TimerView: + def __init__(self, + parent, + label_text="label", + seconds_this=0, + seconds_totle=0): + self.seconds_this = seconds_this + self.seconds_totle = seconds_totle + container = lv.obj(parent) + container.set_size(200, 80) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, -10) + label_this = lv.label(container) + label_this.align(lv.ALIGN.TOP_MID, 0, 10) + label_totle = lv.label(container) + label_totle.align(lv.ALIGN.TOP_MID, 0, 30) + self.container = container + self.label_this = label_this + self.label_totle = label_totle + self.set_value(seconds_this, seconds_totle) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_value(self, seconds_this, seconds_totle): + self.label_this.set_text( + "time now" + str(seconds_this//60) + " min " + str(seconds_this % 60) + " s") + self.label_totle.set_text( + "time total " + str(seconds_totle//60) + " min " + str(seconds_totle % 60) + " s") + + +class PIDPanel: + def __init__(self, parent, label_text="label"): + container = lv.obj(parent) + container.set_size(300, 300) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, 0) + label_partition = InputBox(container, label_text="partition") + label_partition.align(lv.ALIGN.TOP_LEFT, 20, 20) + label_top = lv.label(container) + label_top.set_text("top partition") + label_bottom = lv.label(container) + label_bottom.set_text("bottom partition") + label_top.align(lv.ALIGN.TOP_MID, 0, 80) + label_bottom.align(lv.ALIGN.TOP_MID, 0, 160) + input_box_P_top = InputBox(container, label_text="P") + input_box_P_top.align(lv.ALIGN.TOP_LEFT, -20, 100) + input_box_I_top = InputBox(container, label_text="I") + input_box_I_top.align(lv.ALIGN.TOP_LEFT, 110, 100) + input_box_P_bottom = InputBox(container, label_text="P") + input_box_P_bottom.align(lv.ALIGN.TOP_LEFT, -20, 180) + input_box_I_bottom = InputBox(container, label_text="I") + input_box_I_bottom.align(lv.ALIGN.TOP_LEFT, 110, 180) + self.container = container + + def align(self, align, x, y): + self.container.align(align, x, y) + + def set_size(self, width, height): + self.container.set_size(width, height) + + +class Button: + def __init__(self, parent, label_text="label"): + btn = lv.btn(parent) + btn.set_size(100, 50) + btn.clear_flag(lv.obj.FLAG.SCROLLABLE) + btn.set_style_bg_color(lv.color_white(), 0) + btn.set_style_text_color(lv.color_black(), 0) + btn.set_style_border_color(lv.color_black(), 0) + label = lv.label(btn) + label.set_text(label_text) + label.align(lv.ALIGN.CENTER, 0, 0) + self.is_on = False + self.btn = btn + self.label = label + + def align(self, align, x, y): + self.btn.align(align, x, y) + + def set_text(self, text): + self.label.set_text(text) + + def set_is_on(self, is_on): + self.is_on = is_on + + def _event_cb_adapter(self, e): + self.event_cb(self, e) + + def add_event_cb(self, event_cb, event_type, user_data=None): + self.event_cb = event_cb + self.btn.add_event_cb(self._event_cb_adapter, event_type, user_data) + + def set_size(self, width, height): + self.btn.set_size(width, height) + + + +class ProcessBar: + def __init__(self, parent, value=0): + bar = lv.bar(parent) + bar.remove_style_all() # To have a clean start + bar.add_style(bar_style_bg, 0) + bar.add_style(bar_style_indic, lv.PART.INDICATOR) + bar.set_size(200, 40) + self.bar = bar + self.style_bg = bar_style_bg + self.style_indic = bar_style_indic + self.set_value(value) + + def align(self, align, x, y): + self.bar.align(align, x, y) + + def set_value(self, value, anim=lv.ANIM.ON): + self.bar.set_value(value, anim) + + +def tab1_btnbar1_event_cb(self: "BtnProcessBar", e): + if self.btn.is_on: + self.btn.set_is_on(False) + self.btn.set_text("start") + self.bar.set_value(0) + else: + self.btn.set_is_on(True) + self.btn.set_text("stop") + self.bar.set_value(100) + + +class BtnProcessBar: + def __init__(self, parent, label_text="label", value=0): + container = lv.obj(parent) + container.set_size(350, 80) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + # 无边框 + container.set_style_border_width(0, 0) + btn = Button(container, label_text=label_text) + bar = ProcessBar(container, value=value) + btn.align(lv.ALIGN.LEFT_MID, 0, 0) + bar.align(lv.ALIGN.RIGHT_MID, 0, 0) + self.container = container + self.btn = btn + self.bar = bar + + def align(self, align, x, y): + self.container.align(align, x, y) + + def _event_cb_adapter(self, e): + self.event_cb(self, e) + + def add_event_cb(self, event_cb, event_type, user_data=None): + self.event_cb = event_cb + self.btn.btn.add_event_cb( + self._event_cb_adapter, event_type, user_data) + + +class Chart: + def __init__(self, parent, label_text="label"): + container = lv.obj(parent) + container.set_size(900, 450) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + container.set_style_bg_opa(lv.OPA.TRANSP, 0) + container.set_style_border_width(0, 0) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, -20) + chart = lv.chart(container) + chart.set_size(800, 400) + chart.align(lv.ALIGN.CENTER, 0, 0) + chart.set_type(lv.chart.TYPE.LINE) # Show lines and points too + # Add two data series + ser1 = chart.add_series(lv.palette_main( + lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y) + chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 2, True, 50) + chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 6, 2, True, 50) + # Set next points on ser1 + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 10) + chart.set_next_value(ser1, 30) + chart.set_next_value(ser1, 70) + chart.set_next_value(ser1, 90) + chart.refresh() + self.container = container + + def align(self, align, x, y): + self.container.align(align, x, y) + + +class KeyBoard: + def __init__(self, parent, label_text="label", is_number=True): + container = lv.obj(parent) + if is_number: + width = 300 + else: + width = 600 + container.set_size(width, 360) + container.clear_flag(lv.obj.FLAG.SCROLLABLE) + # container.set_style_bg_opa(lv.OPA.TRANSP, 0) + # container.set_style_border_width(0, 0) + label = lv.label(container) + label.set_text(label_text) + label.align(lv.ALIGN.TOP_MID, 0, 0) + kb = lv.keyboard(container) + kb.set_size(width, 300) + kb.align(lv.ALIGN.BOTTOM_MID, 0, 20) + # kb.add_event_cb(self.event_cb, lv.EVENT.ALL, None) + if is_number: + kb.set_mode(lv.keyboard.MODE.NUMBER) + else: + kb.set_mode(lv.keyboard.MODE.TEXT_LOWER) + global_dict["keyboard"] = self + close_btn = Button(container, label_text="close") + close_btn.set_size(40, 40) + close_btn.align(lv.ALIGN.TOP_RIGHT, 0, -10) + close_btn.btn.add_event_cb( + self.close_btn_event_cb, lv.EVENT.CLICKED, None) + container.add_event_cb( + self.drag_event_cb, lv.EVENT.ALL, None) + self.is_hidden = True + self.container = container + self.close_btn = close_btn + self.kb = kb + + def close_btn_event_cb(self, e): + self.set_hiden(True) + + def drag_event_cb(self, e): + code = e.get_code() + if code == lv.EVENT.PRESSED: + indev = lv.indev_get_act() + self.drag_start_point = indev.get_point() + self.container_start_x = self.container.get_x() + self.container_start_y = self.container.get_y() + self.container.set_align(lv.ALIGN.TOP_LEFT) + # print("drag start", self.drag_start_point.x, self.drag_start_point.y) + if code == lv.EVENT.PRESSING: + indev = lv.indev_get_act() + drag_point = indev.get_point() + # print("drag", drag_point.x, drag_point.y) + self.container.set_pos( + self.container_start_x + drag_point.x - self.drag_start_point.x, self.container_start_y + drag_point.y - self.drag_start_point.y) + + def event_cb(self, e): + code = e.get_code() + ta = e.get_target() + # if code == lv.EVENT.FOCUSED: + # self.kb.move_foreground() + # self.kb.set_textarea(ta) + # self.kb.clear_flag(lv.obj.FLAG.HIDDEN) + + # if code == lv.EVENT.DEFOCUSED: + # self.kb.set_textarea(None) + # self.kb.add_flag(lv.obj.FLAG.HIDDEN) + + def align(self, align, x, y): + self.container.align(align, x, y) + + def move_foreground(self): + self.container.move_foreground() + + def move_background(self): + self.container.move_background() + + def set_hiden(self, is_hidden): + # print("set_hiden", is_hidden) + self.is_hidden = is_hidden + if is_hidden: + self.container.add_flag(lv.obj.FLAG.HIDDEN) + else: + self.container.clear_flag(lv.obj.FLAG.HIDDEN) + self.move_foreground() + + def switch_hidden(self): + self.set_hiden(not self.is_hidden) + + def set_textarea(self, ta): + self.kb.set_textarea(ta) + + +def kb_btn_event_cb(self, e): + # print("kb_btn_event_cb") + kb: KeyBoard = global_dict["keyboard"] + kb.switch_hidden() + + +def date_time_update_cb(timer): + datetime_label = global_dict["datetime_label"] + asctime = time.asctime() + datetime_label.set_text(asctime) + print(asctime) + + +def main(): + global bar_style_bg + global bar_style_indic + bar_style_bg = lv.style_t() + bar_style_indic = lv.style_t() + + bar_style_bg.init() + bar_style_bg.set_border_color(lv.palette_main(lv.PALETTE.BLUE)) + bar_style_bg.set_border_width(2) + bar_style_bg.set_pad_all(6) # To make the indicator smaller + bar_style_bg.set_radius(6) + bar_style_bg.set_anim_time(1000) + + bar_style_indic.init() + bar_style_indic.set_bg_opa(lv.OPA.COVER) + bar_style_indic.set_bg_color(lv.palette_main(lv.PALETTE.BLUE)) + bar_style_indic.set_radius(3) + + # print('hello pikapython!') + mem = PikaStdLib.MemChecker() + + STATUS_BAR_HEIGHT = 40 + LOGO_WIDTH = 100 + TABVIEW_HEIGHT = 40 + + lv.lock() + status_bar = lv.obj(lv.scr_act()) + status_bar.set_size(lv.pct(100), STATUS_BAR_HEIGHT) + status_bar.clear_flag(lv.obj.FLAG.SCROLLABLE) + lv.scr_act().clear_flag(lv.obj.FLAG.SCROLLABLE) + + # logo label + logo = lv.obj(status_bar) + logo.set_size(LOGO_WIDTH, STATUS_BAR_HEIGHT) + logo_label = lv.label(logo) + logo_label.set_text("logo") + logo_label.align(lv.ALIGN.CENTER, 0, 0) + logo.align(lv.ALIGN.LEFT_MID, -20, 0) + logo.clear_flag(lv.obj.FLAG.SCROLLABLE) + + datetime_label = lv.label(status_bar) + datetime_label.set_text("2023.12.20 16:20:08") + datetime_label.align(lv.ALIGN.LEFT_MID, LOGO_WIDTH, 0) + global_dict["datetime_label"] = datetime_label + + timer = lv.timer_create_basic() + global_list.append(timer) + timer.set_period(1) + timer.set_cb(date_time_update_cb) + + # Keyboard + keyboard = KeyBoard(lv.scr_act(), label_text="", is_number=False) + keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0) + + keyboard_btn = Button(status_bar, label_text="keyboard") + keyboard_btn.align(lv.ALIGN.RIGHT_MID, -20, 0) + keyboard_btn.set_size(60, 30) + global_dict["keyboard_btn"] = keyboard_btn + keyboard_btn.add_event_cb(kb_btn_event_cb, lv.EVENT.CLICKED, None) + + # 创建一个tabview对象 + tabview = lv.tabview(lv.scr_act(), lv.DIR.TOP, TABVIEW_HEIGHT) + tabview.clear_flag(lv.obj.FLAG.SCROLLABLE) + tabview.align(lv.ALIGN.TOP_LEFT, 0, STATUS_BAR_HEIGHT) + tabview.set_size(lv.pct(100), lv.pct(100) - 10) + + # 添加标签到tabview + tab1 = tabview.add_tab("run") + tab2 = tabview.add_tab("debug") + tab3 = tabview.add_tab("log") + tab4 = tabview.add_tab("alert") + tab5 = tabview.add_tab("help") + tab6 = tabview.add_tab("program") + tab7 = tabview.add_tab("edit") + + + # tab1 + meter_temp_box = MyMeter(tab1, label_text="box temp", unit="°C") + meter_temp_box.align(lv.ALIGN.TOP_LEFT, 20, 0) + + meter_humi = MyMeter(tab1, label_text="meter humi", unit="%") + meter_humi.align(lv.ALIGN.TOP_RIGHT, -20, 0) + + meter_temp_tube = MyMeter(tab1, label_text="tube temp", unit="°C") + meter_temp_tube.align(lv.ALIGN.TOP_MID, 0, 0) + + meter_temp_box.set_value(20) + meter_humi.set_value(50) + meter_temp_tube.set_value(30) + + process_count_segment = ProcessCount( + tab1, label_text="tim", value=0, totle=10) + process_count_segment.align(lv.ALIGN.BOTTOM_LEFT, 0, -100) + + process_count_loop = ProcessCount(tab1, label_text="loop", value=0, totle=10) + process_count_loop.align(lv.ALIGN.BOTTOM_LEFT, 160, -100) + + timer_segment = TimerView(tab1, label_text="segment", + seconds_this=5, seconds_totle=10) + timer_totle = TimerView(tab1, label_text="timer totle", + seconds_this=0, seconds_totle=200) + + tab1_process_bar = BtnProcessBar(tab1, label_text="start") + tab1_process_bar.align(lv.ALIGN.BOTTOM_LEFT, 0, 0) + tab1_process_bar.add_event_cb(tab1_btnbar1_event_cb, lv.EVENT.CLICKED) + global_dict["tab1_process_bar"] = tab1_process_bar + + # tab2 + timer_segment.align(lv.ALIGN.BOTTOM_RIGHT, -220, -20) + timer_totle.align(lv.ALIGN.BOTTOM_RIGHT, 0, -20) + + pid_circle = PIDPanel(tab2, label_text="loop PID") + pid_circle.align(lv.ALIGN.TOP_LEFT, 0, 0) + + pid_plate = PIDPanel(tab2, label_text="plate PID") + pid_plate.align(lv.ALIGN.TOP_LEFT, 300, 0) + + pid_hit = PIDPanel(tab2, label_text="hit PID") + pid_hit.align(lv.ALIGN.TOP_LEFT, 600, 0) + pid_hit.set_size(350, 400) + # 低气压PID + label_low_pressure = lv.label(pid_hit.container) + label_low_pressure.set_text("lo pressure PID") + label_low_pressure.align(lv.ALIGN.BOTTOM_MID, 0, -100) + input_box_in = InputBox(pid_hit.container, label_text="in", box_num=2) + input_box_in.align(lv.ALIGN.BOTTOM_LEFT, 0, -50) + input_box_out = InputBox(pid_hit.container, label_text="out", box_num=2) + input_box_out.align(lv.ALIGN.BOTTOM_LEFT, 0, 0) + tab2_btn1 = Button(tab2, label_text="btn1") + tab2_btn1.align(lv.ALIGN.BOTTOM_RIGHT, -150, 0) + tab2_btn2 = Button(tab2, label_text="btn2") + tab2_btn2.align(lv.ALIGN.BOTTOM_RIGHT, -20, 0) + + # tab3 + chart_temp = Chart(tab3, label_text="chart temp") + chart_temp.align(lv.ALIGN.CENTER, 0, 0) + tabview.set_act(0, lv.ANIM.OFF) + + lv.unlock() + + mem.max() + + +main() + +for i in range(10): + time.sleep(0.1) + lv.task_handler() + +lv.deinit() diff --git a/src/PikaVersion.h b/src/PikaVersion.h index 8fabe761a..4cdae0978 100644 --- a/src/PikaVersion.h +++ b/src/PikaVersion.h @@ -2,4 +2,4 @@ #define PIKA_VERSION_MINOR 13 #define PIKA_VERSION_MICRO 1 -#define PIKA_EDIT_TIME "2024/01/04 12:49:52" +#define PIKA_EDIT_TIME "2024/01/04 18:47:45" diff --git a/src/dataArg.c b/src/dataArg.c index a4e8b35ad..03d31221a 100644 --- a/src/dataArg.c +++ b/src/dataArg.c @@ -657,39 +657,39 @@ void arg_deinitHeap(Arg* self) { // } } -/* load file as byte array */ Arg* arg_loadFile(Arg* self, char* filename) { size_t file_size = 0; - char* file_buff = pika_platform_malloc(PIKA_READ_FILE_BUFF_SIZE); - Arg* res = New_arg(NULL); - pika_platform_memset(file_buff, 0, PIKA_READ_FILE_BUFF_SIZE); FILE* input_file = pika_platform_fopen(filename, "rb"); if (NULL == input_file) { - if (NULL != res) { - arg_deinit(res); - } - res = NULL; - goto __exit; + return NULL; } - file_size = - pika_platform_fread(file_buff, 1, PIKA_READ_FILE_BUFF_SIZE, input_file); - if (file_size >= PIKA_READ_FILE_BUFF_SIZE) { - pika_platform_printf("Error: Not enough buff for input file.\r\n"); - pika_platform_printf("Info: file size: %d\r\n", file_size); - pika_platform_printf("Info: buff size: %d\r\n", - PIKA_READ_FILE_BUFF_SIZE); - arg_deinit(res); - res = NULL; - goto __exit; - } - /* should not add '\0' to the end of the string */ - res = arg_setBytes(res, "", (uint8_t*)file_buff, file_size); -__exit: - pika_platform_free(file_buff); - if (NULL != input_file) { + // Move the file pointer to the end of the file + pika_platform_fseek(input_file, 0, SEEK_END); + // Get the current file pointer position which is the file size + file_size = pika_platform_ftell(input_file); + // Move the file pointer back to the beginning of the file + pika_platform_fseek(input_file, 0, SEEK_SET); + + // Allocate buffer based on file size + Arg* res = arg_newBytes(NULL, file_size); + char* file_buff = (char*)arg_getBytes(res); + if (file_buff == NULL) { pika_platform_fclose(input_file); + return NULL; } + + pika_platform_memset(file_buff, 0, file_size); + // Read the file into the buffer + if (pika_platform_fread(file_buff, 1, file_size, input_file) != file_size) { + // Handle read error or file size mismatch + arg_deinit(res); + pika_platform_fclose(input_file); + return NULL; + } + + // Clean up + pika_platform_fclose(input_file); return res; }