Просмотр исходного кода

Message builder: Some more UI element.

antirez 3 лет назад
Родитель
Сommit
baecc6c26b
4 измененных файлов с 59 добавлено и 9 удалено
  1. 1 0
      app.h
  2. 17 2
      fields.c
  3. 4 2
      protocols/b4b1.c
  4. 37 5
      view_build.c

+ 1 - 0
app.h

@@ -306,6 +306,7 @@ void fieldset_add_bin(ProtoViewFieldSet *fs, const char *name, uint64_t uval, ui
 void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s);
 void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count);
 void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val, uint32_t digits_after_dot);
+const char *field_get_type_name(ProtoViewField *f);
 
 /* crc.c */
 uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly);

+ 17 - 2
fields.c

@@ -25,6 +25,20 @@ static void field_free(ProtoViewField *f) {
     free(f);
 }
 
+/* Return the type of the field as string. */
+const char *field_get_type_name(ProtoViewField *f) {
+    switch(f->type) {
+    case FieldTypeStr:          return "str";
+    case FieldTypeSignedInt:    return "int";
+    case FieldTypeUnsignedInt:  return "uint";
+    case FieldTypeBinary:       return "bin";
+    case FieldTypeHex:          return "hex";
+    case FieldTypeBytes:        return "bytes";
+    case FieldTypeFloat:        return "float";
+    }
+    return "unknown";
+}
+
 /* Free a field set and its contained fields. */
 void fieldset_free(ProtoViewFieldSet *fs) {
     for (uint32_t j = 0; j < fs->numfields; j++)
@@ -93,9 +107,10 @@ void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s) {
 /* Allocate and append a bytes field. Note that 'count' is specified in
  * nibbles (bytes*2). */
 void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count_nibbles) {
+    uint32_t numbytes = (count_nibbles+count_nibbles%2)/2;
     ProtoViewField *f = field_new(FieldTypeBytes,name);
-    f->bytes = malloc(count_nibbles/2);
-    memcpy(f->bytes,bytes,count_nibbles/2);
+    f->bytes = malloc(numbytes);
+    memcpy(f->bytes,bytes,numbytes);
     f->len = count_nibbles;
     fieldset_add_field(fs,f);
 }

+ 4 - 2
protocols/b4b1.c

@@ -46,8 +46,10 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView
     return true;
 }
 
-static void get_fields(ProtoViewFieldSet *fields) {
-    UNUSED(fields);
+static void get_fields(ProtoViewFieldSet *fieldset) {
+    uint8_t default_id[3]= {0xAB, 0xCD, 0xE0};
+    fieldset_add_bytes(fieldset,"id",default_id,5);
+    fieldset_add_int(fieldset,"button",1,4);
 }
 
 static void build_message(RawSamplesBuffer *samples, ProtoViewFieldSet *fields)

+ 37 - 5
view_build.c

@@ -56,7 +56,7 @@ static void render_view_select_decoder(Canvas *const canvas, ProtoViewApp *app)
     canvas_set_font(canvas, FontPrimary);
     canvas_draw_str(canvas, 0, 9, "Signal builder");
 
-    canvas_draw_str_aligned(canvas,64,40,AlignCenter,AlignCenter,
+    canvas_draw_str_aligned(canvas,64,36,AlignCenter,AlignCenter,
         Decoders[privdata->cur_decoder]->name);
 }
 
@@ -66,13 +66,28 @@ static void render_view_set_fields(Canvas *const canvas, ProtoViewApp *app) {
     BuildViewPrivData *privdata = app->view_privdata;
     char buf[32];
     snprintf(buf,sizeof(buf), "%s field %d/%d",
-        privdata->decoder->name, (int)privdata->cur_field,
+        privdata->decoder->name, (int)privdata->cur_field+1,
         (int)privdata->fieldset->numfields);
     canvas_set_font(canvas, FontPrimary);
     canvas_draw_str(canvas, 0, 9, buf);
     canvas_set_font(canvas, FontSecondary);
     canvas_draw_str(canvas, 0, 19, "up/down: next field, ok: edit");
-    canvas_draw_str(canvas, 0, 62, "Long press ok: create signal");
+    canvas_draw_str(canvas, 0, 62, "Long ok: create, < > incr/decr");
+
+    /* Write the field name, type, current content. For this part we
+     * write white text on black screen, to visually separate the UI
+     * description part from the UI current field editing part. */
+    canvas_set_color(canvas,ColorBlack);
+    canvas_draw_box(canvas,0,21,128,32);
+
+    canvas_set_color(canvas,ColorWhite);
+    ProtoViewField *field = privdata->fieldset->fields[privdata->cur_field];
+    snprintf(buf,sizeof(buf), "%s %s:%d", field->name,
+        field_get_type_name(field), (int)field->len);
+    canvas_set_font(canvas, FontPrimary);
+    canvas_draw_str_aligned(canvas,64,30,AlignCenter,AlignCenter,buf);
+    canvas_set_font(canvas, FontSecondary);
+    canvas_draw_str_aligned(canvas,63,45,AlignCenter,AlignCenter,"\"foobar\"");
 }
 
 /* Render the build message view. */
@@ -93,6 +108,12 @@ static void process_input_select_decoder(ProtoViewApp *app, InputEvent input) {
             privdata->decoder = Decoders[privdata->cur_decoder];
             privdata->fieldset = fieldset_new();
             privdata->decoder->get_fields(privdata->fieldset);
+            // Now we use the subview system in order to protect the
+            // message editing mode from accidental < or > presses.
+            // Since we are technically into a subview now, we'll have
+            // control of < and >.
+            InputEvent ii = {.type = InputTypePress, .key = InputKeyDown};
+            ui_process_subview_updown(app,ii,2);
         } else if (input.key == InputKeyDown) {
             select_next_decoder(app);
         } else if (input.key == InputKeyUp) {
@@ -103,8 +124,19 @@ static void process_input_select_decoder(ProtoViewApp *app, InputEvent input) {
 
 /* Handle input for fields editing mode. */
 static void process_input_set_fields(ProtoViewApp *app, InputEvent input) {
-    UNUSED(app);
-    UNUSED(input);
+    BuildViewPrivData *privdata = app->view_privdata;
+    ProtoViewFieldSet *fs = privdata->fieldset;
+    if (input.type == InputTypeShort) {
+        if (input.key == InputKeyOk) {
+        } else if (input.key == InputKeyDown) {
+            privdata->cur_field = (privdata->cur_field+1) % fs->numfields;
+        } else if (input.key == InputKeyUp) {
+            if (privdata->cur_field == 0)
+                privdata->cur_field = fs->numfields-1;
+            else
+                privdata->cur_field--;
+        }
+    }
 }
 
 /* Handle input for the build message view. */