g_rectangle g_component::getBounds() { if (!g_ui_initialized) { return g_rectangle(); } // send initialization request g_message_transaction tx = g_get_message_tx_id(); g_ui_component_get_bounds_request request; request.header.id = G_UI_PROTOCOL_GET_BOUNDS; request.id = this->id; g_send_message_t(g_ui_delegate_tid, &request, sizeof(g_ui_component_get_bounds_request), tx); // read response size_t bufferSize = sizeof(g_message_header) + sizeof(g_ui_component_get_bounds_response); g_local<uint8_t> buffer(new uint8_t[bufferSize]); if (g_receive_message_t(buffer(), bufferSize, tx) == G_MESSAGE_RECEIVE_STATUS_SUCCESSFUL) { g_ui_component_get_bounds_response* response = (g_ui_component_get_bounds_response*) G_MESSAGE_CONTENT(buffer()); if (response->status == G_UI_PROTOCOL_SUCCESS) { return response->bounds; } } return g_rectangle(); }
g_rectangle cursor_t::getArea() { if (currentConfiguration) { return g_rectangle(position.x - currentConfiguration->hitpoint.x, position.y - currentConfiguration->hitpoint.y, currentConfiguration->image.width, currentConfiguration->image.height); } return g_rectangle(); }
void scrollpane_t::layout() { auto bounds = getBounds(); verticalScrollbar.setModelArea(bounds.height, viewPort->getBounds().height); verticalScrollbar.setBounds(g_rectangle(bounds.width - 15, 0, 15, bounds.height - 15)); horizontalScrollbar.setModelArea(bounds.width, viewPort->getBounds().width); horizontalScrollbar.setBounds(g_rectangle(0, bounds.height - 15, bounds.width - 15, 15)); }
g_rectangle cursor_t::getArea() { // get area for current cursor if (currentConfiguration) { return g_rectangle(position.x - currentConfiguration->hitpoint.x, position.y - currentConfiguration->hitpoint.y, currentConfiguration->size.width, currentConfiguration->size.height); } // fallback cursor is just a square return g_rectangle(position.x, position.y, FALLBACK_CURSOR_SIZE, FALLBACK_CURSOR_SIZE); }
void TextField::update() { // Perform layouting g_rectangle bounds = getBounds(); viewModel = g_layouted_text(); g_text_layouter::getInstance()->layout(text, font, fontSize, g_rectangle(0, 0, bounds.width, bounds.height), g_text_alignment::LEFT, viewModel, false); markFor(COMPONENT_REQUIREMENT_PAINT); }
void FlowLayoutManager::layout() { if (component == 0) { return; } std::vector<Component*>& children = component->getChildren(); int x = 0; int y = 0; int lineHeight = 0; g_rectangle parentBounds = component->getBounds(); for (Component* c : children) { g_dimension preferredSize = c->getPreferredSize(); if (x + preferredSize.width > parentBounds.width) { x = 0; y += lineHeight; lineHeight = 0; } c->setBounds(g_rectangle(x, y, preferredSize.width, preferredSize.height)); x += preferredSize.width; if (preferredSize.height > lineHeight) { lineHeight = preferredSize.height; } } }
void scrollpane_t::setPosition(g_point& newPosition) { if (viewPort != nullptr) { scrollPosition = newPosition; g_rectangle viewPortSize = viewPort->getBounds(); g_rectangle bounds = getBounds(); // limit if too small if (scrollPosition.x > 0) { scrollPosition.x = 0; } else if (viewPortSize.width < bounds.width) { scrollPosition.x = 0; } else if (scrollPosition.x + viewPortSize.width < bounds.width) { scrollPosition.x = bounds.width - viewPortSize.width; } if (scrollPosition.y > 0) { scrollPosition.y = 0; } else if (viewPortSize.height < bounds.height) { scrollPosition.y = 0; } else if (scrollPosition.y + viewPortSize.height < bounds.height) { scrollPosition.y = bounds.height - viewPortSize.height; } viewPort->setBounds(g_rectangle(scrollPosition.x, scrollPosition.y, viewPortSize.width, viewPortSize.height)); } }
g_rectangle TextField::glyphToView(g_positioned_glyph g) { int yOffset = getBounds().height / 2 - heightOfCapitalX - 4; int x = scrollX + g.position.x + insets.left; int y = g.position.y + yOffset; g_dimension bitmapDimension = g.glyph->getBitmapSize(); return g_rectangle(x, y, bitmapDimension.width, bitmapDimension.height); }
g_ui_protocol_status RequestHandler::setBounds(uint32_t component_id, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { Component* component = ComponentStore::get(component_id); if (component == 0) { return G_UI_PROTOCOL_FAIL; } component->setBounds(g_rectangle(x, y, width, height)); return G_UI_PROTOCOL_SUCCESS; }
g_ui_protocol_status RequestHandler::createWindow(uint32_t* out_id) { // Create the window Window* win = new Window(); win->setBounds(g_rectangle(10, 10, 100, 60)); uint32_t ident = ComponentStore::add(win); WindowManager::getInstance()->addToScreen(win); *out_id = ident; return G_UI_PROTOCOL_SUCCESS; }
void gui_screen_t::initialize() { window = g_window::create(); window->setTitle("Terminal"); window->setLayout(G_UI_LAYOUT_MANAGER_GRID); canvas = g_canvas::create(); window->addChild(canvas); g_rectangle windowBounds = g_rectangle(200, 200, 400, 250); window->setBounds(windowBounds); window->setVisible(true); canvas->setBounds(g_rectangle(0, 0, windowBounds.width, windowBounds.height)); canvas->setListener(G_UI_COMPONENT_EVENT_TYPE_KEY, new input_key_listener_t()); canvas->setBufferListener(new canvas_buffer_listener_t()); window->setListener(G_UI_COMPONENT_EVENT_TYPE_FOCUS, new terminal_focus_listener_t()); font = g_font_loader::get("consolas"); viewModel = g_text_layouter::getInstance()->initializeBuffer(); g_create_thread((void*) &paint_entry); }
g_ui_protocol_status RequestHandler::createComponent(uint32_t component_type, uint32_t* out_id) { // Create the component Component* comp = 0; if (component_type == G_UI_COMPONENT_BUTTON) { comp = new Button(); comp->setBounds(g_rectangle(0, 0, 100, 50)); } else if (component_type == G_UI_COMPONENT_LABEL) { comp = new Label(); comp->setBounds(g_rectangle(0, 0, 100, 50)); } else if (component_type == G_UI_COMPONENT_TEXTFIELD) { comp = new TextField(); comp->setBounds(g_rectangle(0, 0, 100, 50)); } // Store the component if (comp != 0) { *out_id = ComponentStore::add(comp); return G_UI_PROTOCOL_SUCCESS; } return G_UI_PROTOCOL_FAIL; }
g_rectangle TextField::positionToCursorBounds(int pos) { int cursorX = positionToUnscrolledCursorX(pos); return g_rectangle(scrollX + cursorX, getBounds().height / 2 - lineHeight / 2, 1, lineHeight); }
g_rectangle grabInvalid() { g_rectangle ret = invalid; invalid = g_rectangle(); return ret; }
/**************************************************************************** * * Procedure draw_graph * * Arguments: prim: pointer to primitive_type * obj: pointer to object_type * * Returns: none * * Action: Draws in a graph. * This takes care of the user specified scaling and translating. * ****************************************************************************/ void draw_graph(prim_type *prim,object_type *obj) { static XPoint *points=0; static point_type2D *fpoints=0; static int num_points=0; static char integ_last_time=0; int i,j; graph_type *the_graph; point_type2D origin,dim; char numstring[20]; float xloc,yloc; float inv_xscale,inv_yscale; float scaled_fermi; float xscale,yscale; int lineshown; float xref,yref; float xval,yval; float *max_x,*max_y,*min_x,*min_y; float *old_max_x,*old_max_y,*old_min_x,*old_min_y; /* check to see what type of graph this is */ if(prim->prop_graph){ the_graph = prim->prop_graph->the_data; max_x = &(prim->prop_graph->max_x); max_y = &(prim->prop_graph->max_y); min_x = &(prim->prop_graph->min_x); min_y = &(prim->prop_graph->min_y); old_max_x = &(prim->prop_graph->old_max_x); old_max_y = &(prim->prop_graph->old_max_y); old_min_x = &(prim->prop_graph->old_min_x); old_min_y = &(prim->prop_graph->old_min_y); } else{ if( prim->graph ) the_graph = prim->graph; else if(prim->band_graph) the_graph = prim->band_graph->the_data; else if(prim->walsh_graph) the_graph = prim->walsh_graph->the_data; else FATAL_BUG("Bogus primitive passed to draw_graph."); max_x = &(the_graph->max_x); max_y = &(the_graph->max_y); min_x = &(the_graph->min_x); min_y = &(the_graph->min_y); old_max_x = &(the_graph->old_max_x); old_max_y = &(the_graph->old_max_y); old_min_x = &(the_graph->old_min_x); old_min_y = &(the_graph->old_min_y); } /* check to see if we need to re-determine the location of tic marks */ if( *old_max_x != *max_x || *old_max_y != *max_y || *old_min_x != *min_x || *old_min_y != *min_y || (prim->prop_graph && (prim->prop_graph->integs_for_tics && !integ_last_time))){ /******** if we're using the integration for the X axis, then we need to update the graph max and min values. *******/ if( prim->prop_graph && prim->prop_graph->integs_for_tics ){ /******* check to see if we've already updated them ********/ if(!integ_last_time){ *max_x = prim->prop_graph->the_integration->max_x; *max_y = prim->prop_graph->the_integration->max_y; *min_x = prim->prop_graph->the_integration->min_x; *min_y = prim->prop_graph->the_integration->min_y; /****** make sure that we aren't gonna get horked when we display COOP integrations by displaying COOP's on the same scale as the integration *******/ if( prim->prop_graph->type == COOP_PROP ){ prim->prop_graph->the_data->max_x = *max_x; prim->prop_graph->the_data->min_x = *min_x; } prim->prop_graph->the_data->max_y = *max_y; prim->prop_graph->the_data->min_y = *min_y; integ_last_time = 1; } /* if(!integ_last_time) */ else{ /******* if we got this far, then it means that the user updated the max and/or min values, so we need to change the integration max and min values to reflect the change. ********/ prim->prop_graph->the_integration->max_x = *max_x; prim->prop_graph->the_integration->min_x = *min_x; prim->prop_graph->the_integration->max_y = *max_y; prim->prop_graph->the_integration->min_y = *min_y; if( prim->prop_graph->type == COOP_PROP ){ prim->prop_graph->the_data->max_x = *max_x; prim->prop_graph->the_data->min_x = *min_x; } prim->prop_graph->the_data->max_y = *max_y; prim->prop_graph->the_data->min_y = *min_y; } } /* if( prim->prop_graph && prim->prop_graph->integs_for_tics ) */ else{ /****** reset the max and min values to those of the data... ******/ if( prim->prop_graph ){ if( integ_last_time ){ *max_x = prim->prop_graph->the_data->max_x; *min_x = prim->prop_graph->the_data->min_x; *max_y = prim->prop_graph->the_data->max_y; *min_y = prim->prop_graph->the_data->min_y; } if( prim->prop_graph->the_integration){ if( prim->prop_graph->type == COOP_PROP ){ prim->prop_graph->the_integration->max_x = *max_x; prim->prop_graph->the_integration->min_x = *min_x; } prim->prop_graph->the_integration->max_y = *max_y; prim->prop_graph->the_integration->min_y = *min_y; } } the_graph->max_x = *max_x; the_graph->min_x = *min_x; the_graph->max_y = *max_y; the_graph->min_y = *min_y; integ_last_time = 0; } preprocess_graph_data(the_graph); if( prim->prop_graph && prim->prop_graph->the_integration){ preprocess_graph_data(prim->prop_graph->the_integration); } /* the_graph->old_max_x = the_graph->max_x; the_graph->old_max_y = the_graph->max_y; the_graph->old_min_x = the_graph->min_x; the_graph->old_min_y = the_graph->min_y; */ *old_max_x = *max_x; *old_max_y = *max_y; *old_min_x = *min_x; *old_min_y = *min_y; } /* check to see if we need memory for the Xpoints */ if( !points || num_points < the_graph->num_p ){ if( points ) free(points); num_points = the_graph->num_p; points = (XPoint *)calloc(num_points+2,sizeof(XPoint)); if( !points ) fatal("Can't allocate memory for point storage in draw_graph."); if( fpoints ) free(fpoints); fpoints = (point_type2D *)calloc(num_points+2,sizeof(point_type2D)); if( !fpoints ) fatal("Can't allocate memory for fpoint storage in draw_graph."); } /* determine the location of the origin on screen */ origin.x = obj->cent.x + obj->trans.x + g_xmax / 2; origin.y = obj->cent.y - obj->trans.y + g_ymax / 2; dim.x = DEF_GRAPH_X * obj->scale.x; dim.y = DEF_GRAPH_Y * obj->scale.y; /* scaling terms */ inv_xscale = (the_graph->max_x - the_graph->min_x) / DEF_GRAPH_X; inv_yscale = (the_graph->max_y - the_graph->min_y) / DEF_GRAPH_Y; xscale = 1/inv_xscale; yscale = 1/inv_yscale; /* find the point in data space which will appear at the origin */ xref = the_graph->min_x * xscale; yref = the_graph->min_y * yscale; /* determine the bounding box for this object */ localmin.x = obj->bmin.x = origin.x; localmin.y = obj->bmin.y = origin.y - dim.y; localmax.x = obj->bmax.x = origin.x + dim.x; localmax.y = obj->bmax.y = origin.y; /* put in the tic marks now... */ if( the_graph->do_x_tics && (!prim->prop_graph || !prim->prop_graph->integs_for_tics)){ for(i=0;i<(int)rint(the_graph->num_tics_x);i++){ xloc = origin.x + obj->scale.x * (the_graph->tic_start_x + i * the_graph->tic_sep_x - xref); g_line(xloc,origin.y+obj->scale.y*TIC_DIM,xloc,origin.y); localmin.y += obj->scale.y*TIC_DIM; /***** do the labels *****/ xval = (the_graph->tic_start_x + i*the_graph->tic_sep_x)*inv_xscale; if( fabs(xval) < 1e-12 ) xval = 0.0; sprintf(numstring,"%lg",xval); yloc = origin.y+obj->scale.y*TIC_DIM*(1.1); g_center_text(xloc,yloc,numstring); } } /* Y tics */ if( the_graph->do_y_tics ){ for(i=0;i<(int)rint(the_graph->num_tics_y);i++){ yloc = origin.y + obj->scale.y * (yref - the_graph->tic_start_y - i * the_graph->tic_sep_y); g_line(origin.x-obj->scale.x*TIC_DIM,yloc,origin.x,yloc); yval = (the_graph->tic_start_y + i*the_graph->tic_sep_y)*inv_yscale; if( fabs(yval) < 1e-12 ) yval = 0.0; sprintf(numstring,"%lg",yval); xloc = origin.x-obj->scale.x*TIC_DIM*1.1; g_right_text(xloc,yloc,numstring); } } /* put in legends if they are needed */ if( the_graph->xlegend[0] != 0 && the_graph->do_x_tics ){ xloc = origin.x + dim.x/2; yloc = origin.y+obj->scale.y*TIC_DIM*(1.1); g_xlegend(xloc,yloc,the_graph->xlegend); obj->bmax.y += 2.1*PS_options.fontsize; } if( the_graph->ylegend[0] != 0 && the_graph->do_y_tics ){ yloc = origin.y - dim.y/2; xloc = origin.x-obj->scale.x*TIC_DIM*5.0; g_ylegend(xloc,yloc,the_graph->ylegend); obj->bmin.x -= 3.0*PS_options.fontsize; } /* Now do the title */ if( the_graph->title[0] != 0 && the_graph->do_title){ xloc = origin.x + dim.x/2; yloc = origin.y - dim.y; g_title(xloc,yloc,the_graph->title); } /* now do the plot itself */ lineshown = 0; for(i=0;i<the_graph->num_curves;i++){ if( the_graph->curves_to_display[i] ){ /* adjust the line styles to get distinguishable graphs */ g_change_linestyle(the_graph->styles[i]); for(j=0;j<the_graph->num_p;j++){ points[j].x = fpoints[j].x = origin.x + (the_graph->data[j*the_graph->num_curves + i].x - xref)*obj->scale.x; points[j].y = fpoints[j].y = origin.y + (yref - the_graph->data[j*the_graph->num_curves + i].y)* obj->scale.y; } /********* Deal with the fact that DOS projections may be filled **********/ if( prim->prop_graph && ((prim->prop_graph->type != COOP_PROP && fill_projections && i != 0 ) || prim->prop_graph->the_data->fills[i])){ /********** There are some complications in the filling if the end points of the graph are not at the same x level. deal with these potential problems by inserting 2 extra points into the curve. ************/ if( *min_x == 0.0 || (*max_x >= 0 && *min_x < 0.0) ){ points[the_graph->num_p].x = fpoints[the_graph->num_p].x = origin.x - xref*obj->scale.x; points[the_graph->num_p+1].x = fpoints[the_graph->num_p+1].x = origin.x - xref*obj->scale.x; }else if( *min_x > 0.0 ){ points[the_graph->num_p].x = fpoints[the_graph->num_p].x = origin.x; points[the_graph->num_p+1].x = fpoints[the_graph->num_p+1].x = origin.x; } else{ points[the_graph->num_p].x = fpoints[the_graph->num_p].x = origin.x + (*max_x - xref)*obj->scale.x; points[the_graph->num_p+1].x = fpoints[the_graph->num_p+1].x = origin.x + (*max_x - xref)*obj->scale.x; } points[the_graph->num_p].y = fpoints[the_graph->num_p].y = origin.y + (yref - the_graph->data[(the_graph->num_p-1)*the_graph->num_curves + i].y) * obj->scale.y; points[the_graph->num_p+1].y = fpoints[the_graph->num_p+1].y = origin.y + (yref - the_graph->data[i].y)* obj->scale.y; g_lines(points,fpoints,the_graph->num_p+2,1); } else{ g_lines(points,fpoints,the_graph->num_p,0); } /* set the line style back to the default value */ g_change_linestyle(0); } } /****** put in the fermi level if this is a property graph and the user asked for it ******/ if( prim->prop_graph && prim->prop_graph->show_fermi ){ if( prim->prop_graph->Fermi_E > the_graph->min_y && prim->prop_graph->Fermi_E < the_graph->max_y ){ scaled_fermi = prim->prop_graph->Fermi_E * yscale; yloc = origin.y + (yref - scaled_fermi)*obj->scale.y; xloc = origin.x; /* use a dashed line */ g_change_linestyle(1); /* draw a line */ g_line(xloc,yloc,xloc+dim.x,yloc); /* set the line style back to the default */ g_change_linestyle(0); } } /* check to see if we should draw a line through zero */ if( the_graph->max_x > 0.0 && the_graph->min_x < 0.0 ){ xloc = origin.x - xref * obj->scale.x; yloc = origin.y; g_line(xloc,yloc,xloc,yloc-dim.y); } /* check to see if we need to draw in an integration */ if( prim->prop_graph && prim->prop_graph->the_integration ){ the_graph = prim->prop_graph->the_integration; inv_xscale = (the_graph->max_x - the_graph->min_x) / DEF_GRAPH_X; inv_yscale = (the_graph->max_y - the_graph->min_y) / DEF_GRAPH_Y; xscale = 1/inv_xscale; yscale = 1/inv_yscale; /* find the point in data space which will appear at the origin */ xref = the_graph->min_x * xscale; yref = the_graph->min_y * yscale; /***** if we are using the integration to provide the tic marks then show them now. *****/ if( prim->prop_graph->the_data->do_x_tics && prim->prop_graph->integs_for_tics){ for(i=0;i<(int)rint(the_graph->num_tics_x);i++){ xloc = origin.x + obj->scale.x * (the_graph->tic_start_x + i * the_graph->tic_sep_x - xref); g_line(xloc,origin.y+obj->scale.y*TIC_DIM,xloc,origin.y); localmin.y += obj->scale.y*TIC_DIM; /***** do the labels *****/ xval = (the_graph->tic_start_x + i*the_graph->tic_sep_x)*inv_xscale; if( fabs(xval) < 1e-12 ) xval = 0.0; sprintf(numstring,"%lg",xval); yloc = origin.y+obj->scale.y*TIC_DIM*(1.1); g_center_text(xloc,yloc,numstring); } } lineshown = 0; for(i=0;i<the_graph->num_curves;i++){ if( the_graph->curves_to_display[i] ){ /* adjust the line styles to get distinguishable graphs */ g_change_linestyle(the_graph->styles[i]); for(j=0;j<the_graph->num_p;j++){ points[j].x = fpoints[j].x = origin.x + (the_graph->data[j*the_graph->num_curves + i].x - xref)*obj->scale.x; points[j].y = fpoints[j].y = origin.y + (yref - the_graph->data[j*the_graph->num_curves + i].y)*obj->scale.y; } g_lines(points,fpoints,the_graph->num_p,0); g_change_linestyle(0); } } the_graph = prim->prop_graph->the_data; } /* draw in a box surrounding the plot */ g_rectangle(origin.x,origin.y,dim.x,dim.y); }
int main(int argc, char** argv) { g_ui_open_status open_stat = g_ui::open(); if (open_stat == G_UI_OPEN_STATUS_SUCCESSFUL) { g_window* window = g_window::create(); window->setTitle("Calculator"); window->setResizable(false); display = g_textfield::create(); display->setTitle("0"); display->setBounds(g_rectangle(10, 10, 150, 30)); window->addChild(display); #define PLACE_BUTTON_T(num, text, x, y) \ but##num = g_button::create(); \ but##num->setTitle(text); \ but##num->setBounds(g_rectangle(x, y, 30, 30)); \ window->addChild(but##num); #define PLACE_BUTTON(num, x, y) PLACE_BUTTON_T(num, #num, x, y); int grid1 = 10; int grid2 = 50; int grid3 = 90; int grid4 = 130; int grid5 = 170; int dispOff = 40; PLACE_BUTTON_T(Clear, "C", grid1, grid1 + dispOff); butClear->setActionListener(new command_press_action_listener_t(COM_CLEAR)); PLACE_BUTTON(1, grid1, grid2 + dispOff); but1->setActionListener(new num_press_action_listener_t(1)); PLACE_BUTTON(2, grid2, grid2 + dispOff); but2->setActionListener(new num_press_action_listener_t(2)); PLACE_BUTTON(3, grid3, grid2 + dispOff); but3->setActionListener(new num_press_action_listener_t(3)); PLACE_BUTTON(4, grid1, grid3 + dispOff); but4->setActionListener(new num_press_action_listener_t(4)); PLACE_BUTTON(5, grid2, grid3 + dispOff); but5->setActionListener(new num_press_action_listener_t(5)); PLACE_BUTTON(6, grid3, grid3 + dispOff); but6->setActionListener(new num_press_action_listener_t(6)); PLACE_BUTTON(7, grid1, grid4 + dispOff); but7->setActionListener(new num_press_action_listener_t(7)); PLACE_BUTTON(8, grid2, grid4 + dispOff); but8->setActionListener(new num_press_action_listener_t(8)); PLACE_BUTTON(9, grid3, grid4 + dispOff); but9->setActionListener(new num_press_action_listener_t(9)); PLACE_BUTTON(0, grid1, grid5 + dispOff); but0->setActionListener(new num_press_action_listener_t(0)); PLACE_BUTTON_T(Plus, "+", grid4, grid1 + dispOff); butPlus->setActionListener(new command_press_action_listener_t(COM_PLUS)); PLACE_BUTTON_T(Minus, "-", grid4, grid2 + dispOff); butMinus->setActionListener(new command_press_action_listener_t(COM_MINUS)); PLACE_BUTTON_T(Mult, "*", grid4, grid3 + dispOff); butMult->setActionListener(new command_press_action_listener_t(COM_MULT)); PLACE_BUTTON_T(Div, "/", grid4, grid4 + dispOff); butDiv->setActionListener(new command_press_action_listener_t(COM_DIV)); PLACE_BUTTON_T(Eq, "=", grid4, grid5 + dispOff); butEq->setActionListener(new command_press_action_listener_t(COM_EQ)); window->setBounds(g_rectangle(70, 70, 190, 320)); window->setVisible(true); uint8_t blocker = true; g_atomic_block(&blocker); } }
void TextField::paint() { if (font == 0) { return; } g_rectangle bounds = getBounds(); g_painter p(graphics); // Background p.setColor(RGB(255, 255, 255)); p.fill(g_rectangle(0, 0, bounds.width, bounds.height)); // Border if (focused) { p.setColor(RGB(55, 155, 255)); } else if (visualStatus == TextFieldVisualStatus::HOVERED) { p.setColor(RGB(150, 150, 150)); } else { p.setColor(RGB(180, 180, 180)); } p.draw(g_rectangle(0, 0, bounds.width - 1, bounds.height - 1)); // Scroll applyScroll(); int pos = 0; int first = marker < cursor ? marker : cursor; int second = marker > cursor ? marker : cursor; // Paint marking if (focused) { pos = 0; for (g_positioned_glyph& g : viewModel.positions) { g_color_argb color = textColor; if (first != second && pos >= first && pos < second) { p.setColor(RGB(55, 155, 255)); g_rectangle before = positionToCursorBounds(pos); g_rectangle after = positionToCursorBounds(pos + 1); p.fill(g_rectangle(before.x, before.y, after.x - before.x, before.height)); color = RGB(255, 255, 255); } ++pos; } } // Paint glyphs pos = 0; for (g_positioned_glyph& g : viewModel.positions) { g_rectangle onView = glyphToView(g); g_color_argb color = textColor; if (focused && first != second && pos >= first && pos < second) { color = RGB(255, 255, 255); } p.drawColoredBitmap(onView.x, onView.y, g.glyph->getBitmap(), color, onView.width, onView.height); ++pos; } // Paint cursor if (focused) { p.setColor(RGB(60, 60, 60)); p.fill(positionToCursorBounds(cursor)); } }
/** * Marks the entire component as dirty */ virtual void markDirty() { markDirty(g_rectangle(0, 0, bounds.width, bounds.height)); }
void gui_screen_t::paint() { g_create_thread((void*) blinkCursorThread); int padding = 5; while (true) { auto windowBounds = window->getBounds(); canvas->setBounds(g_rectangle(0, 0, windowBounds.width, windowBounds.height)); auto cr = getGraphics(); if (cr == 0) { g_sleep(100); continue; } // clear cairo_save(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); // relayout text g_text_layouter::getInstance()->layout(cr, output.c_str(), font, 14, g_rectangle(padding, padding, windowBounds.width - 2 * padding - 20, windowBounds.height - 2 * padding), g_text_alignment::LEFT, viewModel, true); // check which is the lowest-down-the-screen character int highesty = 0; for (g_positioned_glyph& g : viewModel->positions) { int ypos = g.position.y - g.glyph->y; if (ypos > highesty) { highesty = ypos; } } // calculate limit int yLimit = windowBounds.height - 60; int yOffset = 0; if (highesty > yLimit) { yOffset = yLimit - highesty; } // paint characters g_point last; cairo_set_source_rgba(cr, 1, 1, 1, 1); for (g_positioned_glyph& g : viewModel->positions) { last = g.position; cairo_save(cr); cairo_translate(cr, g.position.x - g.glyph->x, yOffset + g.position.y - g.glyph->y); cairo_glyph_path(cr, g.glyph, g.glyph_count); cairo_fill(cr); cairo_restore(cr); } // paint cursor if (focused) { if ((g_millis() - lastInput < 300) || cursorBlink) { cairo_save(cr); cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_rectangle(cr, last.x + 10, yOffset + last.y - 12, 8, 14); cairo_fill(cr); cairo_restore(cr); } } canvas->blit(g_rectangle(0, 0, bufferSize.width, bufferSize.height)); paint_uptodate = true; g_atomic_block(&paint_uptodate); } }