# author: Ethosa ## It provides primitive display progress. import ../thirdparty/opengl, ../core/vector2, ../core/rect2, ../core/anchor, ../core/input, ../core/color, ../core/enums, ../nodes/node, ../nodes/canvas, ../graphics/drawable, control, math const CIRCLE_STEP: float = TAU * 0.01 type ProgressBarType* {.pure.} = enum PROGRESS_BAR_HORIZONTAL, PROGRESS_BAR_VERTICAL, PROGRESS_BAR_CIRCLE ProgressBarObj* = object of ControlRef max_value*, value*: float progress_color*: ColorRef indeterminate_val*: float indeterminate*: bool progress_type*: ProgressBarType ProgressBarRef* = ref ProgressBarObj proc ProgressBar*(name: string = "ProgressBar"): ProgressBarRef = ## Creates a new ProgressBar. ## ## Arguments: ## - `name` is a node name. runnableExamples: var p = ProgressBar("ProgressBar") nodepattern(ProgressBarRef) controlpattern() result.value = 0 result.max_value = 100 result.progress_color = Color(0.6, 0.6, 0.6) result.rect_size.x = 120 result.rect_size.y = 20 result.indeterminate = false result.indeterminate_val = 0 result.progress_type = PROGRESS_BAR_HORIZONTAL result.kind = PROGRESS_BAR_NODE method draw*(self: ProgressBarRef, w, h: GLfloat) = ## It uses for redraw ProgressBar. let x = -w/2 + self.global_position.x y = h/2 - self.global_position.y # draw progress let progress_percent = self.value / self.max_value case self.progress_type of PROGRESS_BAR_HORIZONTAL: procCall self.ControlRef.draw(w, h) glColor4f(self.progress_color.r, self.progress_color.g, self.progress_color.b, self.progress_color.a) let progress_width = progress_percent * self.rect_size.x if self.indeterminate: if self.indeterminate_val - progress_width < self.rect_size.x: self.indeterminate_val += self.rect_size.x * 0.01 else: self.indeterminate_val = -progress_width glRectf( normalize(x + self.indeterminate_val, x, x + self.rect_size.x), y, normalize(x + self.indeterminate_val + progress_width, x, x + self.rect_size.x), y - self.rect_size.y) else: glRectf(x, y, x + progress_width, y - self.rect_size.y) of PROGRESS_BAR_VERTICAL: procCall self.ControlRef.draw(w, h) glColor4f(self.progress_color.r, self.progress_color.g, self.progress_color.b, self.progress_color.a) let progress_width = progress_percent * self.rect_size.y if self.indeterminate: if self.indeterminate_val - progress_width < self.rect_size.y: self.indeterminate_val += self.rect_size.y * 0.01 else: self.indeterminate_val = -progress_width glRectf( x, normalize(y - self.indeterminate_val, y - self.rect_size.y, y), x + self.rect_size.x, normalize(y - self.indeterminate_val - progress_width, y - self.rect_size.y, y)) else: glRectf(x, y, x + self.rect_size.x, y - progress_width) of PROGRESS_BAR_CIRCLE: self.CanvasRef.calcGlobalPosition() let progress_width = progress_percent * TAU cx = x + (self.rect_size.x / 2) cy = y - (self.rect_size.y / 2) orad = min(self.rect_size.x, self.rect_size.y) / 2 irad = (min(self.rect_size.x, self.rect_size.y) / 2) - 5f # background: glColor4f(self.background.getColor().r, self.background.getColor().g, self.background.getColor().b, self.background.getColor().a) glBegin(GL_TRIANGLE_STRIP) for i in 0..90: let angle = TAU * (i/90) glVertex2f(cx + orad*cos(angle), cy - orad*sin(angle)) glVertex2f(cx + irad*cos(angle), cy - irad*sin(angle)) glEnd() # progress: glColor4f(self.progress_color.r, self.progress_color.g, self.progress_color.b, self.progress_color.a) if self.indeterminate: if self.indeterminate_val - progress_width < TAU: self.indeterminate_val += CIRCLE_STEP else: self.indeterminate_val = -progress_width glBegin(GL_TRIANGLE_STRIP) for i in 0..90: let angle = TAU * (i/90) if angle > self.indeterminate_val and angle < progress_width + self.indeterminate_val: glVertex2f(cx + orad*cos(angle), cy - orad*sin(angle)) glVertex2f(cx + irad*cos(angle), cy - irad*sin(angle)) glEnd() else: glBegin(GL_TRIANGLE_STRIP) for i in 0..90: let angle = TAU * (i/90) if angle < progress_width: glVertex2f(cx + orad*cos(angle), cy - orad*sin(angle)) glVertex2f(cx + irad*cos(angle), cy - irad*sin(angle)) glEnd() method duplicate*(self: ProgressBarRef): ProgressBarRef {.base.} = ## Duplicates ProgressBar object and create a new ProgressBar. self.deepCopy() method setMaxValue*(self: ProgressBarRef, value: float) {.base.} = ## Changes max value. if value > self.value: self.max_value = value else: self.max_value = self.value method setProgress*(self: ProgressBarRef, value: float) {.base.} = ## Changes progress. if value > self.max_value: self.value = self.max_value else: self.value = value method setProgressColor*(self: ProgressBarRef, color: ColorRef) {.base.} = ## Changes progress color. ## For change background color use `setBackgroundColor` method. self.progress_color = color