CSS_DONE += $(ROOTPATH)/livegrid/resources/css/ext-ux-livegrid.css
CSS_DONE += $(EXTJSPATH)/examples/ux/gridfilters/css/GridFilters.css
CSS_DONE += $(EXTJSPATH)/examples/ux/gridfilters/css/RangeMenu.css
+CSS_DONE += $(EXTJSPATH)/examples/ux/css/Spinner.css
CSS_DONE += static/xcheckbox/xcheckbox.css
CSS_DONE += static/app/ext.css
JAVASCRIPT += $(EXTJSPATH)/examples/ux/gridfilters/filter/StringFilter.js
JAVASCRIPT += $(EXTJSPATH)/examples/ux/gridfilters/menu/ListMenu.js
JAVASCRIPT += $(EXTJSPATH)/examples/ux/gridfilters/menu/RangeMenu.js
+JAVASCRIPT += $(EXTJSPATH)/examples/ux/Spinner.js
+JAVASCRIPT += $(EXTJSPATH)/examples/ux/SpinnerField.js
JAVASCRIPT += $(ROOTPATH)/app/i18n-post.js
#
},
{
.type = PT_S64,
- .intsplit = CHANNEL_SPLIT,
+ .intextra = CHANNEL_SPLIT,
.id = "channel_min",
.name = N_("Minimal channel number"),
.desc = N_("Lowest channel number the user can access."),
},
{
.type = PT_S64,
- .intsplit = CHANNEL_SPLIT,
+ .intextra = CHANNEL_SPLIT,
.id = "channel_max",
.name = N_("Maximal channel number"),
.desc = N_("Highest channel number the user can access."),
},
{
.type = PT_S64,
- .intsplit = CHANNEL_SPLIT,
+ .intextra = CHANNEL_SPLIT,
.id = "number",
.name = N_("Number"),
.desc = N_("Number. The position the channel will appear on "
},
{
.type = PT_U32,
+ .intextra = INTEXTRA_RANGE(1, 0x7ff, 1),
.id = "cookie_expires",
.name = N_("Cookie expiration (days)"),
.desc = N_("The number of days cookies set by Tvheadend should "
},
{
.type = PT_S64,
- .intsplit = CHANNEL_SPLIT,
+ .intextra = CHANNEL_SPLIT,
.id = "number",
.name = N_("Number"),
.desc = N_("Channel number as defined in EPG data."),
if (p->type == PT_U32 || p->type == PT_S64 ||
p->type == PT_TIME) {
int64_t v = f->u.n.n;
- if (p->intsplit != f->u.n.intsplit) {
- v = (v / MIN(1, f->u.n.intsplit)) * p->intsplit;
+ if (INTEXTRA_IS_SPLIT(p->intextra) && p->intextra != f->u.n.intsplit) {
+ v = (v / MIN(1, f->u.n.intsplit)) * p->intextra;
f->u.n.n = v;
}
}
},
{
.type = PT_S64,
- .intsplit = CHANNEL_SPLIT,
+ .intextra = CHANNEL_SPLIT,
.id = "channel_number",
.name = N_("Channel numbers from"),
.off = offsetof(iptv_network_t, in_channel_number),
},
{
.type = PT_S64,
- .intsplit = CHANNEL_SPLIT,
+ .intextra = CHANNEL_SPLIT,
.id = "channel_number",
.name = N_("Channel number"),
.off = offsetof(iptv_mux_t, mm_iptv_chnum),
break;
}
case PT_U32: {
- if (p->intsplit) {
+ if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) {
char *s;
if (!(new = htsmsg_field_get_str(f)))
continue;
- u32 = atol(new) * p->intsplit;
+ u32 = atol(new) * p->intextra;
if ((s = strchr(new, '.')) != NULL)
- u32 += (atol(s + 1) % p->intsplit);
+ u32 += (atol(s + 1) % p->intextra);
} else {
if (htsmsg_field_get_u32(f, &u32))
continue;
break;
}
case PT_S64: {
- if (p->intsplit) {
+ if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) {
if (!(new = htsmsg_field_get_str(f)))
continue;
- s64 = prop_intsplit_from_str(new, p->intsplit);
+ s64 = prop_intsplit_from_str(new, p->intextra);
} else {
if (htsmsg_field_get_s64(f, &s64))
continue;
htsmsg_add_u32(m, name, *(uint16_t *)val);
break;
case PT_U32:
- if (p->intsplit) {
- uint32_t maj = *(int64_t *)val / p->intsplit;
- uint32_t min = *(int64_t *)val % p->intsplit;
+ if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) {
+ uint32_t maj = *(int64_t *)val / p->intextra;
+ uint32_t min = *(int64_t *)val % p->intextra;
if (min) {
snprintf(buf, sizeof(buf), "%u.%u", (unsigned int)maj, (unsigned int)min);
htsmsg_add_str(m, name, buf);
htsmsg_add_u32(m, name, *(uint32_t *)val);
break;
case PT_S64:
- if (p->intsplit) {
- int64_t maj = *(int64_t *)val / p->intsplit;
- int64_t min = *(int64_t *)val % p->intsplit;
+ if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) {
+ int64_t maj = *(int64_t *)val / p->intextra;
+ int64_t min = *(int64_t *)val % p->intextra;
if (min) {
snprintf(buf, sizeof(buf), "%lu.%lu", (unsigned long)maj, (unsigned long)min);
htsmsg_add_str(m, name, buf);
htsmsg_add_u32(m, "group", pl->group);
/* Split integer value */
- if (pl->intsplit)
- htsmsg_add_u32(m, "intsplit", pl->intsplit);
+ if (pl->intextra) {
+ if (INTEXTRA_IS_SPLIT(pl->intextra))
+ htsmsg_add_u32(m, "intsplit", pl->intextra);
+ else {
+ htsmsg_add_s32(m, "intmax", INTEXTRA_GET_MAX(pl->intextra));
+ htsmsg_add_s32(m, "intmin", INTEXTRA_GET_MIN(pl->intextra));
+ htsmsg_add_s32(m, "intstep", INTEXTRA_GET_STEP(pl->intextra));
+ }
+ }
/* Data */
if (obj)
#define PO_MULTILINE (1<<16) // Multiline string
#define PO_PERSIST (1<<17) // Persistent value (return back on save)
+/*
+ * min/max/step helpers
+ */
+#define INTEXTRA_RANGE(min, max, step) \
+ ((1<<31)|(((step)&0x7f)<<24)|(((max)&0xfff)<<12)|((min)&0xfff))
+
+#define INTEXTRA_IS_RANGE(e) (((e) & (1<<31)) != 0)
+#define INTEXTRA_IS_SPLIT(e) !INTEXTRA_IS_RANGE(e)
+#define INTEXTRA_GET_STEP(e) (((e)>>24)&0x7f)
+#define INTEXTRA_GET_MAX(e) ((e)&(1<<23)?-(((e)>>12)&0x7ff):(((e)>>12)&0x7ff))
+#define INTEXTRA_GET_MIN(e) ((e)&(1<<11)?-((e)&0x7ff):((e)&0x7ff))
+
/*
* Property definition
*/
uint8_t group; ///< Visual group ID (like ExtJS FieldSet)
size_t off; ///< Offset into object
uint32_t opts; ///< Options
- uint32_t intsplit; ///< integer/remainder boundary
+ uint32_t intextra; ///< intsplit: integer/remainder boundary or range: min/max/step
/* String based processing */
const void *(*get) (void *ptr);
this.duration = conf.duration;
this.date = conf.date;
this.intsplit = conf.intsplit;
+ this.intmin = conf.intmin;
+ this.intmax = conf.intmax;
+ this.intstep = conf.intstep;
this.hexa = conf.hexa;
this.group = conf.group;
this.lorder = conf.lorder;
} else if (this.intsplit) {
c['maskRe'] = /[0-9\.]/;
cons = Ext.form.TextField;
- } else
+ } else if (this.intmin || this.intmax) {
+ cons = Ext.ux.form.SpinnerField;
+ c['minValue'] = this.intmin;
+ c['maxValue'] = this.intmax;
+ c['incrementValue'] = this.intstep || 1;
+ } else {
cons = Ext.form.NumberField;
+ }
break;
/* 'str' and 'perm' */
maskRe: /[0-9\.]/
});
break;
+ } else if (f.intmin || f.intmin) {
+ r = new Ext.ux.form.SpinnerField({
+ fieldLabel: f.caption,
+ name: f.id,
+ disabled: d,
+ width: 300,
+ value: value,
+ minValue: f.intmin,
+ maxValue: f.intmax,
+ incrementalValue: f.intstep || 1
+ });
+ break;
}
r = new Ext.form.NumberField({
fieldLabel: f.caption,
--- /dev/null
+../../../../../../vendor/ext-3.4/examples/ux/Spinner.js
\ No newline at end of file
--- /dev/null
+../../../../../../vendor/ext-3.4/examples/ux/SpinnerField.js
\ No newline at end of file
--- /dev/null
+../../../../../../../vendor/ext-3.4/examples/ux/css/Spinner.css
\ No newline at end of file
--- /dev/null
+../../../../../../../vendor/ext-3.4/examples/ux/images/spinner-split.gif
\ No newline at end of file
--- /dev/null
+../../../../../../../vendor/ext-3.4/examples/ux/images/spinner.gif
\ No newline at end of file